複数の Git コミットを元に戻すにはどうすればいいですか? 質問する

複数の Git コミットを元に戻すにはどうすればいいですか? 質問する

次のような Git リポジトリがあります。

A <- B <- C <- D <- HEAD

ブランチのヘッドが A を指すようにしたい、つまり、B、C、D、HEAD が消えて、ヘッドが A と同義になるようにしたいのです。

リベースを試すか (その間に変更をプッシュしているので適用されません)、元に戻すかのどちらかができるようです。しかし、複数のコミットを元に戻すにはどうすればよいですか? 一度に 1 つずつ元に戻すのですか? 順序は重要ですか?

ベストアンサー1

コメントに書いた内容を拡張する

一般的なルールとして、公開した履歴を書き換え (変更) してはいけません。誰かがその履歴に基づいて作業を行っている可能性があるためです。履歴を書き換え (変更) すると、その人の変更をマージしたり更新したりする際に問題が生じます。

解決策としては、削除したい変更を元に戻す新しいコミットを作成することです。これを行うには、git を元に戻す指示。

次のような状況があります。

A <-- B <-- C <-- D <-- マスター <-- ヘッド

(ここでの矢印はポインターの方向を示します。コミットの場合は「親」参照、ブランチ ヘッド (ブランチ参照) の場合は最上位コミット、HEAD 参照の場合はブランチの名前です)。

作成する必要があるものは次のとおりです。

A <-- B <-- C <-- D <-- [(BCD) -1 ] <-- マスター <-- HEAD

ここで、[(BCD)^-1]はコミット B、C、D の変更を元に戻すコミットを意味します。数学的には (BCD) -1 = D -1 C -1 B -1となるため、次のコマンドを使用して必要な状況を得ることができます。

$ git revert --no-commit D
$ git revert --no-commit C
$ git revert --no-commit B
$ git commit -m "the commit message for all of them"

マージコミット以外のすべてに機能します。


別の解決策としてはチェックアウト コミット A の内容と、この状態をコミットします。マージ コミットでも機能します。ただし、追加されたファイルは削除されません。ローカルの変更がある場合は、git stashまずそれを実行してください。

$ git checkout -f A -- . # checkout that revision over the top of local files
$ git commit -a

すると、次のような状況になります。

A <-- B <-- C <-- D <-- A' <-- マスター <-- HEAD

コミット A' はコミット A と同じ内容ですが、コミットが異なります (コミット メッセージ、親、コミット日付)。


代わりのジェフ・ファーランドによる解答、チャールズ・ベイリーによる修正同じアイデアに基づいていますが、git リセットここでは少し変更されていますが、この方法はすべてに有効です。

$ git reset --hard A
$ git reset --soft D # (or ORIG_HEAD or @{1} [previous location of HEAD]), all of which are D
$ git commit

おすすめ記事