コミットする前に「gitadd」を元に戻すにはどうすればよいですか?

2008年12月08日に質問されました。  ·  閲覧回数 3.4M回  ·  ソース

paxos1977 picture
2008年12月08日

次のコマンドを使用して、誤ってファイルをGitに追加しました。

git add myfile.txt

git commitまだ実行していません。 これを元に戻す方法はありますか?そうすれば、これらのファイルはコミットに含まれませんか?

回答

genehack picture
2008年12月08日
10970

コミットする前にgit addを元に戻すことができます

git reset <file>

これにより、他に何も変更せずに、現在のインデックス(「コミットしようとしている」リスト)から削除されます。

使用できます

git reset

予定されているすべての変更をアンステージするファイル名なし。 これは、ファイルが多すぎて妥当な時間内に1つずつリストできない場合に便利です。

古いバージョンのGitでは、上記のコマンドはそれぞれgit reset HEAD <file>git reset HEADと同等であり、 HEADが定義されていない場合は失敗します(まだコミットを行っていないため)リポジトリ)またはあいまいです( HEADという名前のブランチを作成したため、これは愚かなことです)。 ただし、これはGit 1.8.2

「gitreset」(オプションまたはパラメーターなし)は、履歴にコミットがない場合にエラーアウトするために使用されていましたが、現在は空のインデックスを提供します(存在しないコミットと一致させるため)。

ドキュメント: git reset

Rhubarb picture
2009年03月26日
2204

あなたが欲しい:

git rm --cached <added_file_to_undo>

理由:

私がこれに不慣れだったとき、私は最初に試しました

git reset .

(最初の追加全体を元に戻すため)、これ(そうではない)の役立つメッセージを取得するためだけに:

fatal: Failed to resolve 'HEAD' as a valid ref.

これは、最初のコミットが完了するまでHEAD ref(ブランチ?)が存在しないためであることが判明しました。 つまり、私のようなワークフローが次のようなものである場合、私と同じ初心者の問題に遭遇します。

  1. 新しいホットさであるGitを試すために、私のすばらしい新しいプロジェクトディレクトリにCDを挿入してください
  2. git init
  3. git add .
  4. git status

    ...たくさんのがらくた巻物...

    =>くそー、私はそのすべてを追加したくありませんでした。

  5. google "undo git add"

    =>スタックオーバーフローを見つける-イェーイ

  6. git reset .

    =>致命的:「HEAD」を有効な参照として解決できませんでした。

さらに、メーリングリストにこれが役に立たないことに対してログに記録されたバグがあることが判明しました。

そして、正しい解決策がGitステータス出力にありました(はい、私は 'がらくたとしてグロスオーバーしました)

...
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
...

そして、解決策は確かにgit rm --cached FILEを使用することです。

ここの他の場所での警告に注意してください- git rmはファイルのローカル作業コピーを削除しますが、 -cachedを使用する場合は削除しませんgit help rmの結果は次のとおりです。

--cachedこのオプションを使用して、インデックスからパスのみをステージング解除および削除します。 変更されているかどうかに関係なく、作業ツリーファイルは残されます。

使用を続行します

git rm --cached .

すべてを削除してやり直します。 add .は再帰的ですが、 rmは再帰的に-rが必要であることが判明したため、機能しませんでした。 はぁ。

git rm -r --cached .

さて、今、私は始めたところに戻っています。 次回は-nを使用してドライランを実行し、何が追加されるかを確認します。

git add -n .

--cachedが何も破壊しないことについて、 git help rm信頼する前に、すべてを安全な場所に圧縮しました(スペルを間違えた場合はどうなりますか)。

Paul Beckingham picture
2008年12月08日
548

入力した場合:

git status

Gitは、ステージングを解除する方法の説明を含め、ステージングされているものなどを教えてくれます。

use "git reset HEAD <file>..." to unstage

Gitは、このような状況で正しいことをするように私を促すのにかなり良い仕事をしていると思います。

注:最近のGitバージョン(1.8.4.x)では、次のメッセージが変更されています。

(use "git rm --cached <file>..." to unstage)
takeshin picture
2010年09月11日
257

明確にするために: git addは、変更を現在の作業ディレクトリからステージング領域(インデックス)に移動します。

このプロセスはステージングと呼ばれます。 したがって、変更(変更されたファイル)をステージングする最も自然なコマンドは明らかなものです。

git stage

git addは、 git stage入力が簡単なエイリアスです。

残念ながら、 git unstagegit unaddコマンドもありません。 関連するものを推測したり覚えたりするのは難しいですが、それはかなり明白です:

git reset HEAD --

このためのエイリアスを簡単に作成できます。

git config --global alias.unadd 'reset HEAD --'
git config --global alias.unstage 'reset HEAD --'

そして最後に、新しいコマンドがあります。

git add file1
git stage file2
git unadd file2
git unstage file1

個人的には、さらに短いエイリアスを使用しています。

git a # For staging
git u # For unstaging
leonbloy picture
2011年05月19日
175

受け入れられた回答に加えて、誤って追加されたファイルが巨大な場合、「 git reset 」でインデックスから削除した後でも、 .gitスペースを占有しているように見えることに気付くでしょう。

これは心配する必要はありません。 ファイルは確かにまだリポジトリにありますが、「ルーズオブジェクト」としてのみです。 (クローン、プッシュを介して)他のリポジトリにコピーされることはなく、スペースは最終的に再利用されます-おそらくすぐにはありませんが。 心配な場合は、次のコマンドを実行できます。

git gc --prune=now

更新(以下は、最も賛成の回答から生じる可能性のあるいくつかの混乱を解消するための私の試みです):

それで、 git addの本当の取り消しはどれですか?

git reset HEAD <file>

または

git rm --cached <file>

厳密に言えば、私が間違っていなければ:なし

git addは元に戻せません-一般的に安全です。

まず、 git add <file>実際に何をするかを思い出してみましょう。

  1. <file>以前に追跡されてgit addはそれを現在のコンテンツとともに

  2. <file>すでに追跡されている場合、 git addは現在のコンテンツ(スナップショット、バージョン)をキャッシュにaddと呼ばれます(単に更新するだけではありません)。したがって、実際に新しいアイテムをキャッシュに追加し、最終的には後でコミットします。

これに照らして、質問は少し曖昧です:

コマンドを使用して誤ってファイルを追加しました...

OPのシナリオは最初のシナリオ(追跡されていないファイル)のようです。「元に戻す」で、追跡されたアイテムからファイル(現在のコンテンツだけでなく)を削除する必要があります。 このような場合は、それが実行しても大丈夫だgit rm --cached <file>

また、 git reset HEAD <file>実行することもできます。 これは両方のシナリオで機能するため、一般的には望ましい方法です。すでに追跡されているアイテムのバージョンを誤って追加した場合にも元に戻します。

ただし、2つの注意点があります。

最初:(回答で指摘されているように) git reset HEADが機能しないシナリオは1つだけですが、 git rm --cachedは機能します:新しいリポジトリ(コミットなし)。 しかし、実際には、これは実質的に無関係なケースです。

2番目: git reset HEADは、以前にキャッシュされたファイルの内容を魔法のように復元することはできず、HEADから再同期するだけであることに注意してください。 誤った方向に進んだgit addが、以前にステージングされたコミットされていないバージョンを上書きした場合、それを回復することはできません。 そのため、厳密に言えば、元に戻すことはできません[*]。

例:

$ git init
$ echo "version 1" > file.txt
$ git add file.txt   # First add of file.txt
$ git commit -m 'first commit'
$ echo "version 2" > file.txt
$ git add  file.txt   # Stage (don't commit) "version 2" of file.txt
$ git diff --cached file.txt
-version 1
+version 2
$ echo "version 3" > file.txt
$ git diff  file.txt
-version 2
+version 3
$ git add  file.txt    # Oops we didn't mean this
$ git reset HEAD file.txt  # Undo?
$ git diff --cached file.txt  # No dif, of course. stage == HEAD
$ git diff file.txt   # We have irrevocably lost "version 2"
-version 1
+version 3

もちろん、新しいファイルを追加するためだけに「git add」を実行する通常の怠惰なワークフロー(ケース1)に従い、commit、 git commit -aコマンドを使用して新しいコンテンツを更新する場合、これはそれほど重要ではありません。


*(編集:上記は実質的に正しいですが、ステージングされたがコミットされてから上書きされた変更を回復するための少しハック/複雑な方法がある可能性があります-Johannes Matokicとiolsmitによるコメントを参照してください)

Alireza picture
2017年06月28日
129

すでに追加されているファイルを元に戻すのは、Gitを使用すると非常に簡単です。 すでに追加されているmyfile.txtリセットするに

git reset HEAD myfile.txt

説明:

不要なファイルをステージングした後、元に戻すには、 git reset実行できます。 Headはローカル内のファイルの先頭であり、最後のパラメーターはファイルの名前です。

これらの場合に発生する可能性のあるすべての手順を含め、以下の画像の手順を詳細に作成しました。

git reset HEAD file

braitsch picture
2009年12月10日
99
git rm --cached . -r

現在のディレクトリから追加したものすべてを再帰的に「追加解除」します

Khaja Minhajuddin picture
2011年10月12日
94

実行

git gui

すべてのファイルを手動で削除するか、すべてを選択して[コミットからアンステージ]ボタンをクリックして

Michael_Scharf picture
2014年01月17日
89

問題は明確に提起されていません。 その理由は、 git addは2つの意味があるためです。

  1. ステージング領域に新しいファイルを追加してから、 git rm --cached file元に戻します。
  2. 変更したファイルをステージング領域に追加してから、 git reset HEAD file元に戻します。

疑わしい場合は、

git reset HEAD file

どちらの場合も期待通りのことをするからです。

警告:変更されたファイル(以前にリポジトリに存在していたファイル)に対してgit rm --cached fileを実行すると、ファイルはgit commitで削除されます! ファイルシステムには引き続き存在しますが、他の誰かがコミットをプルすると、ファイルはその作業ツリーから削除されます。

git statusは、ファイルが新しいファイルである変更されているかを示します。

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   my_new_file.txt
    modified:   my_modified_file.txt
sjas picture
2013年03月29日
88

Gitには、考えられるすべてのアクションに対するコマンドがありますが、物事を正しく行うには広範な知識が必要であり、そのため、せいぜい直感に反します...

以前にしたこと:

  • ファイルを変更し、 git add .またはgit add <file>

あなたが欲しいもの:

  • インデックスからファイルを削除しますが、バージョン管理を維持し、作業コピーにコミットされていない変更を残します。

     git reset HEAD <file>
    
  • ファイルをHEADから最後の状態にリセットし、変更を元に戻し、インデックスから削除します。

     # Think `svn revert <file>` IIRC.
     git reset HEAD <file>
     git checkout <file>
    
     # If you have a `<branch>` named like `<file>`, use:
     git checkout -- <file>
    

    git reset --hard HEADは単一のファイルでは機能しないため、これが必要です。

  • インデックスとバージョン管理から<file>を削除し、バージョン管理されていないファイルを作業コピーの変更とともに保持します。

     git rm --cached <file>
    
  • 作業コピーとバージョン管理から<file>を完全に削除します。

     git rm <file>