ローカルコミットを行った後、ファイルを再度ステージング解除するにはどうすればよいですか?


268

次のコマンドを実行しました

git add <foo.java>
git commit -m "add the foo.java file"

今すぐローカルコミットを削除してfoo.javaをステージング解除するにはどうすればよいですか?

と入力git reset --hardすると、変更foo.javaしたものが元の状態に戻ることがわかりました。

回答:


452

git reset --soft HEAD~1あなたがしたいことをする必要があります。この後、インデックスが最初に変更され(で表示されgit diff --cachedます)、最新の変更はステージングされません。git statusその後、次のようになります。

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   foo.java
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo.java
#

その後git add foo.java、両方の変更を一度に実行してコミットできます。


私は回答を編集しました。「コミットされる変更」には最初の変更があり、「コミットのためにステージングされていない変更」には2番目の変更があります。
アンティ

4
この回答で説明されているのは、実際には何をするかgit commit --amendです。しかし、はるかに複雑なワークフローです。これは、良い方向性を示しているにもかかわらず、OPが尋ねた質問には答えません(git reset)。
7heo.tk

2
:それはのように見えるので、それを動作させるために「〜」と「^」を交換しなければならなかったgit reset --soft HEAD~
シャハル

3
git reset --soft HEAD〜1を実行し、次にgit reset HEAD
Joko Wandiro

私が欲しいものへの完全な答え!
DeepInJava

78

使用する:

git reset HEAD^

これにより、デフォルトで「混合」リセットが行われ、ユーザーが要求したことを実行します。foo.javaをアンステージングして、最新のコミットを削除します。


2
「混合」リセット、「ソフト」リセット、「ハード」リセットについて教えていただけませんか。
キットホー

1
@Kit Ho-git resetマニュアルには、これらの優れた説明があります。
manojlds

4
@ Kit、@ manojlds:stackoverflow.com/questions/2530060/…(恥知らずなプラグイン)
Cascabel

5
それは実際にあるだけで、正しい答え。他の2つの答えは、コミット後にファイルを再度ステージングします。
7heo.tk

git reset --soft機能しませんでしたが、機能git reset HEAD^しました
言葉によると

43

私には、次の方法がより読みやすい(したがって望ましい)方法です。

git reset HEAD~1

の代わりに1、ステージングを解除するコミットがいくつあってもかまいません。


39

git reset --softそれはそのためだけです:に似git reset --hardていますが、ファイルには触れません。


4
これは、私が聞いた中で最もわかりやすい説明でした(わずか11語)。ありがとう!
phreakhead 2014

3
その答えは間違っています。git reset「のようですgit reset --hardが、ファイルには触れません。」ないgit reset --softgit reset --soft変更をステージングするので、コミットする場合にステージングに追加する必要はありませんが、変更しない場合はgit reset(はい、2回目、なしで--soft)追加する必要があります。その答えは短いですが、正しくありません。
7heo.tk

12

最後のコミットですべてのファイルのステージングを解除するには-

git reset HEAD~


8

「リセット」は、変更をローカルで元に戻す方法です。コミットするときは、最初に「git add」で含める変更を選択します。これは「ステージング」と呼ばれます。そして、変更がステージングされたら、それらを「git commit」します。

ステージングまたはコミットのいずれかからバックアウトするには、HEADを「リセット」します。ブランチでは、HEADは最新のコミットを指すgit変数です。したがって、ステージングしたがコミットしていない場合は、「git reset HEAD」になります。これは、ステージから変更を取り除いて現在のHEADにバックアップします。「git reset --mixed HEAD〜0」の省略形です。

すでにコミットしている場合は、HEADはすでに進んでいるため、以前のコミットにバックアップする必要があります。ここでは、「reset HEAD〜1」または「reset HEAD ^ 1」または「reset HEAD〜」または「reset HEAD ^」-すべての参照HEADから1を引いたものです。

どちらが良い記号ですか、〜または^?〜チルドを単一のストリームと考えてください-各コミットに単一の親があり、それがシーケンスの一連の変更である場合、チルドを使用してストリームをバックアップして参照できます(HEAD〜1、HEAD〜2、HEAD) 〜3、親、祖父母、曾祖父母など(技術的には、初期の世代の最初の親を見つけます)。

マージがある場合、コミットには複数の親があります。そのとき、^キャレットが出てきます。ブランチが一緒に表示されるので、覚えておくことができます。キャレットを使用すると、HEAD ^ 1が1つのコミットの最初の親になり、HEAD ^ 2が2番目の親になります(たとえば、母親と父親)。

したがって、単一の親のコミットで1ホップ戻るだけの場合、HEAD〜とHEAD ^は同等です。どちらでも使用できます。

また、リセットは--soft mixed、または--hardに。ソフトリセットはコミットをバックアウトするだけです-ヘッドをリセットしますが、以前のコミットからのファイルをチェックアウトしないため、作業ディレクトリ内のすべての変更が保持されます。また、-- soft resetはステージ(indexとも呼ばれます)もクリアしないため、ステージングされたすべてのファイルはステージ上に残ります。

--mixedすべての変更が保存されますが、ステージをクリアしているので、リセット(デフォルトでは)また、以前のコミットからファイルをチェックアウトしません。これが、単純な「git reset HEAD」がステージから消える理由です。

--hard先にコミットし、それがすべての変更を上書きするので、すべてのファイルからリセットはHEADをリセットし、そしてそれは、ステージをクリアしますが、それもチェックします。

コミットをリモートリポジトリにプッシュした場合、リセットはうまく機能しません。ローカルでリセットできますが、リモートにプッシュしようとすると、ローカルヘッドがリモートブランチのヘッドの背後にあることがgitに表示され、プッシュが拒否されます。あなたはプッシュを強制することができるかもしれませんが、gitは実際にそれをするのが好きではありません。

または、変更を保持したい場合は、変更を隠しておき、以前のコミットをチェックアウトし、変更を元に戻し、それらをステージングし、新しいコミットを作成してからプッシュします。


動作の詳細な説明については+1。IMOこれは受け入れられる答えになるはずです!
ISAE

2

変更をnコミットまでステージング解除したいとしましょう。

コミットハッシュは次のとおりです。

  • h1
  • h2 ...
  • hn + 1

次に、次のコマンドを実行します。
git reset hn

これで、HEADはhn + 1になります。h1からhnへの変更はステージングされません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.