web-dev-qa-db-ja.com

Gitでファイルをステージング解除する方法が2つあるのはなぜですか?

Gitはファイルをアンステージングすることをgit rm --cachedに提案することがあります。時にはgit reset HEAD fileを提案することがあります。いつ使うべきですか?

編集:

D:\code\gt2>git init
Initialized empty Git repository in D:/code/gt2/.git/
D:\code\gt2>touch a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       a
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a
#
D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a

D:\code\gt2>touch b

D:\code\gt2>git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       b
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add b

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#
1015
Senthess

git rm --cached <filePath> ステージングを解除しない ファイル、実際には ファイルの削除を段階的に実行する (以前に既にコミットされていると仮定して)ファイルを作業ツリーに残したままにします。未追跡ファイル)。

git reset -- <filePath> アンステージ 与えられたファイルのための段階的な変更を行います。

そうは言っても、ステージングされている新しいファイルでgit rm --cachedを使用した場合、それは以前にコミットされたことがないので、基本的にはステージング解除したばかりのように見えます。

1665
Ryan Stewart

git rm --cachedはインデックスからファイルを削除するために使用されます。ファイルがすでにリポジトリにある場合、git rm --cachedはインデックスからファイルを削除して作業ディレクトリに残し、コミットするとリポジトリからも削除されます。基本的に、コミット後は、ファイルのバージョンを解除してローカルコピーを保持しているはずです。

git reset HEAD file(デフォルトでは--mixedフラグを使用しています)が異なるのは、ファイルがすでにリポジトリにある場合は、インデックスバージョンのファイルをリポジトリからのものに置き換え(HEAD)、事実上 変更をステージング解除する それに。

バージョン管理外のファイルの場合は、ファイルがHEADにないため、ファイル全体をステージング解除します。この側面ではgit reset HEAD filegit rm --cachedは同じですが、同じではありません(既にリポジトリにあるファイルの場合で説明したように)

Why are there 2 ways to unstage a file in git?の質問に - gitで何かをするための唯一の方法は本当にありません。それはそれの美しさです:)

319
manojlds

非常に単純に:

  • git rm --cached <file> gitがファイルの追跡を完全に停止するようにします (普通のgit rm *とは異なり、ファイルシステムに残します)
  • git reset HEAD <file> 最後のコミット以降に行われたファイルへの変更をステージング解除します (ただし、コマンド名が示すものとは反対に、ファイルシステムでは変更を元に戻しません**)。ファイルはリビジョン管理下に置かれたままです。

ファイルが以前にリビジョン管理されていなかった場合(つまり、初めてgit addedされたファイルをステージング解除している場合)、2つのコマンドは同じ効果を持ちます。 ".

*リポジトリに対して以前にコミットされたであったファイルのgit rm --cachedに関して、@DrewTが彼の答えで述べている警告に留意してください。この質問の文脈では、追加されたばかりでまだコミットされていないファイルについては、何も心配する必要はありません。

**その名前のせいでgit resetコマンドを使うのは恥ずかしく長い間怖がっていました - それでも今日でも私は失敗しないように構文を調べます。 ( update :ようやく時間がかかった git resetの使い方をtldrのページにまとめる )だから今、私はそれがどのように機能するかについてのより良いメンタルモデル、そして忘れたときのクイックリファレンスを持っているいくつかの詳細。)

112
waldyrious

このスレッドは少し古くなっていますが、それでも直感的な問題ではないので、少しデモを追加したいと思います。

me$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   to-be-added
#   modified:   to-be-modified
#   deleted:    to-be-removed
#

me$ git reset -q HEAD to-be-added

    # ok

me$ git reset -q HEAD to-be-modified

    # ok

me$ git reset -q HEAD to-be-removed

    # ok

# or alternatively:

me$ git reset -q HEAD to-be-added to-be-removed to-be-modified

    # ok

me$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   to-be-modified
#   deleted:    to-be-removed
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   to-be-added
no changes added to commit (use "git add" and/or "git commit -a")

git reset HEAD-qなし)は変更されたファイルについての警告を与え、その終了コードは1です。これはスクリプトのエラーと見なされます。

編集:git checkout HEAD to-be-modified to-be-removedはステージング解除にも機能しますが、変更をワークスペースから完全に削除します。

43
Daniel Alder

誤ってコミットしたくないファイルをステージングした場合で、その変更を確実に保持したい場合は、次のようにすることもできます。

git stash
git stash pop

これによりHEADへのリセットが実行され、変更内容が再適用され、個々のファイルをコミット用に再ステージングできるようになります。プルリクエスト用の機能ブランチ(git stash ; git checkout -b <feature> ; git stash pop)を作成するのを忘れた場合にも便利です。

31
ives

問題のファイルがすでにリポジトリにあり、バージョン管理下にある場合(以前にコミットされたものなど)、これら2つのコマンドにはいくつかの微妙な違いがあります。

  • git reset HEAD <file>は、現在のコミットでファイルをステージング解除します。
  • git rm --cached <file>は将来のコミットのためにファイルのステージングを解除します。 git add <file>で再度追加されるまでは、ステージングされていません。

そしてもう一つ重要な違いがあります。

  • git rm --cached <file>を実行してブランチをリモートにプッシュすると、リモートからブランチを引っ張っている人はだれでも自分のフォルダからファイル _実際に_ を削除したことになります。フォルダから削除されます。

この最後の違いは、チームの各開発者が異なる設定(つまり、異なるベースURL、IP、またはポート設定)を持つ設定ファイルを含むプロジェクトにとって重要です。したがってgit rm --cached <file>を使用している場合、ブランチを引っ張る人は手動で再設定する必要があります。削除はリモートからあなたのブランチを引っ張って人々に影響を与えるので、設定を作成するか、あなたは彼らにあなたのものを送って彼らのip設定(など)に戻すことができます。

15
DrewT

git add <folder>を介してディレクトリ全体をstagename__としますが、ステージングリスト(つまり、git statusの実行時に生成されるリスト)からファイルを除外したい、および keep 除外ファイル内の変更(作業中)コミットする準備ができていませんが、作業を失いたくはありません...)。あなたは単に使用することができます:

git reset <file>

git statusを実行すると、resetname__であるファイルがunstagedname__であり、残りのファイルであるaddedname__がまだstagedname__リストにあることがわかります。

8
jiminikiz

1。

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a

( "git rm --cached ..."を使ってステージングを解除します)

  • gitはポインタのシステムです

  • ポインタをに変更するコミットがまだありません。

  • 「指されているバケツからファイルを取り出す」唯一の方法は、 gitに変更を監視するように指示したファイルを削除することです

2。

D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a

git commit -m a

  • コミットしました、 ' saved '

3。

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

( "git reset HEAD ..."を使用してステージングを解除します)

  • あなたはこの時点であなたのコードをコミットしました
  • 今、あなたはあなたのコミットにあなたのポインタをリセットすることができます ' 最後の保存に戻ります '

私は誰もgit reflog( http://git-scm.com/docs/git-reflog )に言及していないのは驚きです。

# git reflog
<find the place before your staged anything>
# git reset HEAD@{1}

Reflogはリポジトリへの変更を追跡するだけでなく、ユーザの行動(例えばpull、別のブランチへのチェックアウトなど)も追跡し、それらの行動を元に戻すことを可能にするgit履歴です。そのため、誤ってステージングされたファイルをステージング解除する代わりに、ファイルをステージングしなかった時点に戻すことができます。

これはgit reset HEAD <file>に似ていますが、場合によってはより細かい場合があります。

すみません - 本当にあなたの質問に答えるのではなく、私がかなり頻繁に使用するファイルをアンステージングするためのさらに別の方法を指摘するだけです(私はRyan Stewartによる答えのようで、とてもお世話になりました).

5
Alex

OS git rm --cached <file>がファイルを削除するのと同様に、git rm <file>はインデックスからファイルを削除し、プレーンrm <file>が両方を実行するディレクトリからは削除しないように思えますバージョン管理を削除せずにディレクトリ。

3
ernie.cordell