確認 - git 変更 取り消し




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

私は誤ってコマンドを使ってgitにファイルを追加しました:

git add myfile.txt

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

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


Gitは想像を絶するあらゆる行動のコマンドを持っていますが、物事を正しくするためには豊富な知識が必要です。そのため、それは逆に直感的です。

あなたが前にしたこと:

  • ファイルを変更し、 git add .を使用しました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>を削除し<file>バージョン管理されていないファイルは作業コピーに変更が加えられています。

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

    git rm <file>
    

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

私は新しいファイルを作成し、gitに追加しました。 その後、SourceTree GUIを使用してそれをアンステージしました。 これが結果です。

ファイルをアンステージする[08/12/15 10:43]
git -c diff.mnemonicprefix = false -c core.quotepath = false -c credential.helper = sourcetreeのリセット-q - パス/ to / file / filename.java

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


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"(リスト復帰の最初のエントリ)、 "復帰"で復帰モードを解除し、 "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)
$

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

このコマンドの正反対は、

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

あなたは以前の状態になります。 指定されていないリスト(以前の状態)になります。

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


git resetとタイプするだけで元に戻すことができ、 git add .入力したことのないようですgit add . あなたの最後のコミット以来。 以前にコミットしたことを確認してください。


特定のファイルの場合:

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

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

  • git reset。
  • git checkout。

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


あなたが欲しい:

git rm --cached <added_file_to_undo>

推論:

私はこれを初めて知りましたが、最初に試しました

git reset .

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

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

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

  1. 私のすばらしい新しいプロジェクトディレクトリにcdして、Gitを試してみましょう。
  2. git init
  3. git add .
  4. git status

    ...によって多くのくそスクロール...

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

  5. google "git addを元に戻す"

    =>スタックオーバーフローを見つける - よろしく

  6. git reset .

    =>致命的: 'HEAD'を有効なrefとして解決できませんでした。

さらに、メーリングリストにはこれが役に立たないというバグが記録されています

Gitのステータス出力(Git status output)に正しい解決策があったことは間違いありません。

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

そして実際にはgit rm --cached FILEを使用することです。

git rmはファイルのローカル作業コピーを削除しますが、-- git rmを使用している場合は削除しませんgit help rm結果は次のとおりです。

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

私は使用を進める

git rm --cached .

すべてを取り除き、再び始める。 add .ので、しかし、動作しませんでしたadd . 再帰的であり、 rmは再帰するために-rを必要とする。 一口。

git rm -r --cached .

さて、私はどこから始めたのですか。 次回は、 -nを使って-nを実行し、何が追加されるのかを見ていきます:

git add -n .

私は安全な場所にすべてを圧縮し、 git help rm信頼して、何も破壊しないようにしました(そして間違っていたらどうしたらいいでしょうか?)。


このコマンドはあなたの変更を取り消します:

git reset HEAD filename.txt

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

git add -p 

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


たぶんGitはあなたの質問を投稿して以来進化しました。

$> git --version
git version 1.6.2.1

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

git reset HEAD .

これはあなたが探しているものでなければなりません。


コミットgit add前に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"(オプションやパラメータなし)が、空のインデックスを返します(存在しないコミットと一致するようになりました)。


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

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


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

git rm --cached FILE

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


受け入れられた答えに加えて、間違って追加されたファイルが巨大だった場合、 ' 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 その内容をキャッシュに git add ます

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

これを踏まえて、質問はやや曖昧です。

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

OPのシナリオが最初のもの(未追跡のファイル)であるように見えるので、追跡されたアイテムからファイル(現在のコンテンツだけでなく)を削除することを「元に戻す」ことが望まれます。 この場合、 git rm --cached <file>

また、 git reset HEAD <file>実行することもできgit reset HEAD <file> 。 どちらのシナリオでも機能するため、これは一般的には好ましい方法です。既に追跡されたアイテムのバージョンを間違って追加したときに取り消しも行います。

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

最初は: git reset HEADが動作しないが、 git rm --cachedは:新しいリポジトリ( git rm --cachedしていない)という1つのシナリオだけが(回答で指摘されているように)存在します。 しかし、実際には、これは事実上無関係なケースです。

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

もちろん、新しいファイル(ケース1)を追加するためだけに 'git add'を実行する通常の怠惰なワークフローに従うと、これはあまり重要ではありません。コミット、 git commit -aコマンドで新しいコンテンツを更新します。

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


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

  1. ステージング領域に新しいファイルを追加し、 git rm --cached file元に戻しgit rm --cached file
  2. ステージング領域に変更されたファイルを追加し、次にgit reset HEAD file元に戻しgit reset HEAD file

不確かな場合は、

git reset HEAD file

それは両方の場合に期待されることを行うからです。

警告: 変更されたファイル(以前リポジトリに存在していたファイル)でgit rm --cached filegit 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

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

  • 新しいプロジェクトのメインディレクトリを作成します。
  • git init実行しgit init
  • .gitignoreファイルを作成します(空であっても)。
  • .gitignoreファイルをコミットします。

Gitはコミットがなければgit resetを実行するのが本当に難しいです。 最初の小さなコミットを作成する場合は、その後git add -Agit reset何度でもgit resetして、すべてを正しく取得することができます。

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

  • 最初のコミットを確認してください。 これにより、すべてのファイルが削除されます。
  • その後、直近のコミットをもう一度チェックアウトします。 現在の行末設定を使用して、ファイルの新しいコピーを取得します。

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

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

git stage

git addは、 git stageエイリアスを入力する方が簡単です

残念なことにgit unaddコマンドや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

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

git reset *

誰もインタラクティブモードについて言及していないことに私は驚いている。

git add -i

オプション3を選択してファイルを追加解除します。 私の場合は、複数のファイルを追加したい場合があります。対話モードでは、このような番号を使用してファイルを追加できます。 これは、4:1,2,3,5

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

ステージングファイル


git reset filename.txt

現在のインデックスである "about to be committed"領域からfilename.txtという名前のファイルを削除します。


git reset filename.txt  

現在のインデックスである "about to be committed"領域からfilename.txtという名前のファイルを削除します。





git-stage