Git でコミットを取り消そうとしました。使用するのは危険ですかgit reset --hard HEAD~1
?
のさまざまなオプションの違いは何ですかgit reset
?
注: HEADは現在/最新のコミットですが、HEAD~1はHEADの直前のコミットです。
ベストアンサー1
git reset
には、ソフト、ミックス、ハード、マージ、キープの 5 つの「モード」があります。通常、これらのモードが使用されるため、最初の 3 つから説明します。その後に、ちょっとしたおまけがありますので、お楽しみに。
次のような履歴を持つリポジトリがあると仮定します。
7e05a95 (HEAD -> main) Update a
e62add5 Update b
ca9ae0a Update a
9b6060d Add c
eebe372 Add b
947586a Add a
最新のコミット ( 7e05a95
) には次の変更が含まれています:
diff --git a/a b/a
index b66ba06..28b68e2 100644
--- a/a
+++ b/a
@@ -1 +1 @@
-new content
+new new content
git reset
では、さまざまなモードで実行すると何が起こるでしょうか? 調べてみましょう!
柔らかい
を使用すると、git reset --soft HEAD~1
現在のブランチから最後のコミットが削除されますが、ファイルの変更はそのまま残ります。作業ツリーまた、変更はインデックスに残るため、 を続けて実行すると、git commit
前に「削除」したコミットとまったく同じ変更を含むコミットが作成されます。
これは実際にはどのように見えるでしょうか? 次のようになります:
> git reset --soft HEAD^ # Assuming HEAD points at 7e05a95
> git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: a
ご覧のとおり、ファイルの変更はa
インデックス上にあり、再度コミットする準備ができています。
混合
これはデフォルトのモードで、soft と非常によく似ています。 でコミットを「削除」すると、git reset HEAD~1
作業ツリー内の変更は保持されますが、インデックスには保持されません。そのため、コミットを「やり直す」場合は、コミットする前に変更を追加する必要があります ( git add
)。
実際には、結果は次のようになります。
> git reset --mixed HEAD^ # Assuming HEAD points at 7e05a95
> git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: a
no changes added to commit (use "git add" and/or "git commit -a")
ファイルの変更はa
まだ残っていますが、インデックスには表示されません。
難しい
git reset --hard HEAD~1
使用するとコミットされていない変更と追跡されていないファイルをすべて失う最後のコミットで導入された変更に加えて、変更は作業ツリーに残らないため、コマンドを実行するとgit status
リポジトリに変更がないことがわかります。
これについては慎重に扱ってください。 によって追跡されていないgit
(コミットされていない、または少なくともインデックスに追加されていない) 未コミットの変更を誤って削除した場合、 を使用してそれらを元に戻す方法はありませんgit
。
実際の例は次のようになります。
> git reset --hard HEAD^ # Assuming HEAD points at 7e05a95
> git status
On branch main
nothing to commit, working tree clean
ご覧のとおり、変更は残っていません。ファイルにコミットされていない変更もあったとすると、b
それらも失われます。
> echo 'some uncommitted changes' > b
> git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: b
no changes added to commit (use "git add" and/or "git commit -a")
> git reset --hard HEAD^ # Assuming HEAD points at 7e05a95
> git status
On branch main
nothing to commit, working tree clean
ボーナス
保つ
git reset --keep HEAD~1
興味深い便利な機能です。現在 HEAD
および指定されたコミット。これらのファイルの 1 つ以上にコミットされていない変更がある場合は、リセットを中止します。基本的には、 のより安全なバージョンとして機能しますhard
。
コミットされていない変更がいくつかある、以前の例をもう一度見てみましょうb
。
> echo 'some uncommitted changes' > b
> git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: b
no changes added to commit (use "git add" and/or "git commit -a")
> git reset --keep HEAD^ # Assuming HEAD points at 7e05a95
> git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: b
no changes added to commit (use "git add" and/or "git commit -a")
ファイルの変更は削除されましたa
が、ファイル内のコミットされていない変更は保持されていますb
。
繰り返しになりますが、「ハード」は削除します全て「keep」はリセットコミットからの変更のみを削除します。
これらのモードのそれぞれについては、git リセットのドキュメント。
注記
コミットを削除すると、git reset
コミットは実際には失われません。コミットまたはその子を指す参照がなくなるだけです。git reset
たとえば、 などのコマンドを使用して、 で「削除」されたコミットの SHA-1 キーを見つけることで、コミットを復元できますgit reflog
。