web-dev-qa-db-ja.com

コミットする前に 'git add'を元に戻す方法は?

誤ってgitにファイルを追加してしまいました。

git add myfile.txt

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


これまでに48個の回答があります(一部削除)。新しい情報がない限り、新しい情報を追加しないでください。

8101
paxos1977

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

git reset <file>

他のものを変更することなく現在のインデックス( "約コミットされる"リスト)からそれを削除します。

あなたが使用することができます

git reset

すべての適切な変更をステージング解除するためのファイル名なし。合理的な時間内に1つずつ一覧表示するにはファイルが多すぎる場合に便利です。

Gitの古いバージョンでは、上記のコマンドはそれぞれgit reset HEAD <file>git reset HEADと同等で、HEADが未定義(まだリポジトリにコミットしていないため)またはあいまいな(HEADという名前のブランチを作成したため)あなたがすべきではないことはバカなことです)。この はGit 1.8.2で変更されました 、それで、現代のバージョンのGitではあなたの最初のコミットをする前にさえあなたは上のコマンドを使うことができます:

"git reset"(オプションやパラメータなし)は、履歴にコミットがないときにエラーになっていましたが、現在は空のインデックスになっています(存在しないコミットに一致させるためにも存在しません)。

9181
genehack

あなたが欲しい:

git rm --cached <added_file_to_undo>

推論:

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

git reset .

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

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

これはHEAD ref(branch?)が最初のコミットの後まで存在しないためです。つまり、私のようなワークフローが次のようなものだった場合、私と同じ初心者の問題に遭遇するでしょう。

  1. 新しいプロジェクトディレクトリにcdしてG​​itを試してみてください。
  2. git init
  3. git add .
  4. git status

    ...たくさんのがらくたスクロール.

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

  5. google "undo git add"

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

  6. git reset .

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

さらに、 バグがログに記録されている メーリングリストでこれが役に立たないことに反対していることがわかります。

そして、正しい解決策がGitのステータス出力に表示されていました(そう、私は「がらくた」と言いました)。

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

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

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

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

使い続けます

git rm --cached .

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

git rm -r --cached .

さて、今私は始めたところに戻ります。次回は-nを使用して予行演習を行い、追加される内容を確認します。

git add -n .

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

2047
Rhubarb

あなたが入力した場合:

git status

gitはどのようにステージングされているかなどを教えてくれます。

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

私は、gitがこのような状況で正しいことをするように私を忠告するのに非常に良い仕事をしているのを見つけます。

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

(use "git rm --cached <file>..." to unstage)
507
Paul Beckingham

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

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

git stage

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

残念ながらgit unstageコマンドもgit 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
238
takeshin

誤って追加されたファイルが巨大だった場合、受け入れられた回答に加えて、 'git reset'を使用してインデックスから削除した後でも、.gitディレクトリ内のスペースを占有しているように思われます。これは気にする必要はありません。ファイルは実際にはまだリポジトリ内にありますが、「緩いオブジェクト」としてのみ存在し、他のリポジトリに(クローン、プッシュによって)コピーされることはなく、スペースは最終的に再利用されます。おそらくそれほど早くはないでしょう。あなたが心配なら、あなたは走ることができます:

git gc --Prune=now

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

git addの本当のundoはどれでしょうか。

git reset HEAD <file>

または

git rm --cached <file>

厳密に言えば、私が間違っていなければ、noneです。

git add元に戻すことはできません - 安全に、一般に。

最初にgit add <file>が実際に何をするのか思い出しましょう。

  1. <file>以前は追跡されていないの場合、git addキャッシュに追加します、およびその現在の内容。

  2. <file>すでに追跡済みの場合、git add現在のコンテンツを保存(スナップショット、バージョン)がキャッシュに保存されます。 GITでは、このアクションは依然としてadd、(単なる update itではなく)と呼ばれます。これは、ファイルの2つの異なるバージョン(スナップショット)が2つの異なる項目として見なされるためです。実際にキャッシュに新しいアイテムを追加することで、後でコミットすることができます。

この点を考慮すると、問題は少しあいまいです。

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

OPのシナリオは最初のシナリオ(追跡されていないファイル)のようです。追跡されている項目からファイル(現在のコンテンツだけではなく)を削除するには、[元に戻す]を実行します。 Ifこれが事実です、それで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 lost irrevocably "version 2"
-version 1
+version 3

もちろん、これは新しいファイルを追加するためだけに 'git add'を実行するという通常の遅延ワークフローに従って(ケース1)、commit、git commit -aコマンドで新しい内容を更新するだけであれば、それほど重要ではありません。


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

161
leonbloy
git rm --cached . -r

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

91
braitsch

実行する

git gui

手動で、またはそれらをすべて選択して unstage from commit ボタンをクリックして、すべてのファイルを削除します。

85

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

git reset HEAD myfile.txt

説明しなさい:

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

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

git reset HEAD file

82
Alireza

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>
    
80
sjas

問題は明確には言えません。その理由はgit addには2つの意味があるからです。

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

疑問がある場合は使用

git reset HEAD file

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

変更された(リポジトリに以前存在していたファイル)であったファイルに対してgit rm --cached fileを実行すると、Warning: _そのファイルは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
71
Michael_Scharf

あなたが最初のコミットをしていて、git resetを使うことができない場合は、単に "Git bankruptcy"を宣言し、.gitフォルダを削除して最初からやり直してください。

61
Paul Betts

他の答えの多くと同様に、あなたはgit resetを使うことができます

BUT:

私はgit unaddのためにGitコマンド(まさにエイリアス)を実際に追加するこの小さな小さな記事を見つけました。詳細は_ git unaddを参照してください。

単に、

git config --global alias.unadd "reset HEAD"

今すぐすることができます

git unadd foo.txt bar.txt
55
electblake

git removeまたはgit rm--cachedフラグと共に使用することができます。試してください:

git help rm
46
gnud

git add -iを使用して、これから追加するファイルを次回のコミットから削除します。例:

不要なファイルを追加します。

$ git add foo
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   foo
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]#

対話的な追加を行って追加を元に戻す(ここでgitで入力したコマンドは "r"(元に戻す)、 "1"(リストの最初のエントリには元に戻す)、元に戻すモードからの脱退は "return"、そして "q" (終了する):

$ git add -i
           staged     unstaged path
  1:        +1/-0      nothing foo

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> r
           staged     unstaged path
  1:        +1/-0      nothing [f]oo
Revert>> 1
           staged     unstaged path
* 1:        +1/-0      nothing [f]oo
Revert>> 
note: foo is untracked now.
reverted one path

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> q
Bye.
$

それでおしまい!これがあなたの証明で、 "foo"が追跡されていないリストに戻ってきたことを示しています。

$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]
#       foo
nothing added to commit but untracked files present (use "git add" to track)
$
42
Alex North-Keys

新しいプロジェクトを始めるときにこの厄介な問題を回避する方法は次のとおりです。

  • 新しいプロジェクトのメインディレクトリを作成します。
  • git initを実行してください。
  • 今度は.gitignoreファイルを作成します(たとえそれが空であっても)。
  • あなたの.gitignoreファイルをコミットしてください。

コミットがない場合、Gitはgit resetを実行するのを非常に困難にします。念のために小さな初期コミットを作成した場合は、その後、すべてを正しく実行するために必要なだけgit add -Aおよびgit resetを実行できます。

この方法のもう1つの利点は、後で行末でトラブルが発生し、すべてのファイルを更新する必要がある場合、簡単に実行できることです。

  • その初期コミットをチェックしてください。これですべてのファイルが削除されます。
  • それからあなたの最新のコミットをもう一度チェックしてください。現在の行末設定を使用して、ファイルの新しいコピーを取得します。
37
Ryan Lundy

質問を投稿してからGitが進化したのかもしれません。

$> git --version
git version 1.6.2.1

今、あなたは試すことができます:

git reset HEAD .

これはあなたが探しているものです。

33
Kokotte23

リビジョンの指定に失敗した場合は、セパレータを含める必要があります。私のコンソールからの例:

git reset <path_to_file>
fatal: ambiguous argument '<path_to_file>': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

git reset -- <path_to_file>
Unstaged changes after reset:
M   <path_to_file>

(git version 1.7.5.4)

33
powlo

上で提案したように、ステージング領域から新しいファイルを削除するには(そして新しいファイルの場合にのみ):

git rm --cached FILE

誤って追加された新しいファイルに対してのみrm --cachedを使用してください。

30
Ran

特定のフォルダ(およびそのサブフォルダ)内のすべてのファイルをリセットするには、次のコマンドを使用できます。

git reset *
24
Zorayr

一度に複数のファイルを処理するには、*コマンドを使用します。

git reset HEAD *.prj
git reset HEAD *.bmp
git reset HEAD *gdb*

24
boulder_ruby

git resetと入力するだけで元に戻ります。前回のコミット以降、git add .を入力したことがないようなものです。あなたが以前にコミットしたことを確認してください。

22
Donovan

新しいファイルnewFile.txtを作成したとします。

enter image description here

誤ってファイルを追加したとします。git add newFile.txt

enter image description here

さて、コミットする前に、この追加を元に戻したいと思いますgit reset newFile.txt

enter image description here

18
Vidura Mudalige

特定のファイルの場合:

  • git reset my_file.txt
  • git checkout my_file.txt

追加されたすべてのファイルの場合:

  • git reset.
  • git checkout.

注: checkout はファイル内のコードを変更し、最後に更新(コミット)された状態に移動します。 reset コードを変更しません。ヘッダーをリセットするだけです。

17
Hasib Kamal

Git add useを元に戻すには

git reset filename

13
Anirudh Sood

このコマンドはあなたの変更を隠します。

git reset HEAD filename.txt

また使用することができます

git add -p 

ファイルの一部を追加します。

13
wallerjake

私は誰もインタラクティブモードに言及していないことに驚きました:

git add -i

オプション3を選択してファイルを追加解除します。私の場合私はしばしば対話型モードであなたがファイルを追加するためにこのような番号を使うことができる、一つ以上のファイルを追加したいです。これは4:1,2,3,5以外のすべてを取るでしょう

シーケンスを選択するには、1-5を入力して1から5までをすべて実行します。

Gitステージングファイル

13
Jonathan

git add myfile.txt#これはあなたのファイルをコミットリストに追加します

このコマンドとは正反対です。

git reset HEAD myfile.txt  # this will undo it. 

そう、あなたは前の状態になります。指定されたものは再び追跡されていないリスト(前の状態)になります。

指定したファイルで頭をリセットします。だから、あなたの頭がそれを意味しないならば、それは単にそれをリセットするでしょう

9
git reset filename.txt

他のものを変更せずに、filename.txtという名前のファイルを現在のインデックス、「コミットしようとしている」領域から削除します。

9
Rahul Sinha

SourceTreeでは、guiを使ってこれを簡単に行うことができます。ファイルのステージング解除にsourcetreeが使用するコマンドを確認できます。

新しいファイルを作成し、それをgitに追加しました。それから私はSourceTree guiを使ってそれをステージング解除しました。これが結果です。

ファイルのアンステージング[08/12/15 10:43]
git -c diff.mnemonicprefix = false -c core.quotepath = false -c credential.helper = sourcetree reset -q - パス/ /ファイル/ファイル名.Java

SourceTreeはresetを使用して新しいファイルをステージング解除します。

8
miva2
git reset filename.txt  

他のものを変更せずに、filename.txtという名前のファイルを現在のインデックス、「コミットしようとしている」領域から削除します。

7
Joseph Mathew

最も直感的な解決策の1つは SourceTree を使うことです。

あなたはステージングされたステージングされていない/からファイルをドラッグアンドドロップすることができます enter image description here

7
Marcin Szymczak

git resetコマンドを使用すると、ステージング領域またはステージング領域と作業ツリーを変更できます。 Gitが望む通りにコミットを作成できるということは、git addで行った変更に対する変更を元に戻す必要があることを意味しています。

git reset HEAD <file to change>を呼び出すことによってそれを行うことができます。変更を完全に取り除くには2つの方法があります。 git checkout HEAD <file(s) or path(s)>はステージングエリアと作業ツリーへの変更を元に戻す簡単な方法です。ただし、このコマンドは作業ツリーに対するすべての変更を削除するため、このコマンドには注意してください。 Gitはこれらの変更をコミットしたことがないので知らない。このコマンドを実行した後でこれらの変更を元に戻す方法はありません。

あなたが自由に使えるもう一つのコマンドはgit reset --hardです。それはあなたの作業ツリーにとっても同様に有害です - コミットされていない変更や段階的な変更はそれを実行した後に失われます。 git reset -hard HEADを実行することは、git checkout HEADと同じことをします。ファイルやパスを必要としません。

--softgit resetと一緒に使用できます。指定したコミットにリポジトリをリセットし、それらすべての変更をステージングします。すでにステージングした変更は影響を受けず、また作業ツリーの変更も影響を受けません。

最後に、--mixedを使用して、何も変更を加えることなく作業ツリーをリセットできます。これにより、段階的に行われた変更もすべて解除されます。

1
SAIguru011