web-dev-qa-db-ja.com

Gitスカッシュがブランチの途中でコミットする

ブランチの途中で、前後のコミットを変更せずに、いくつかのコミットをまとめてスカッシュしたい。

私が持っています :

A -- B -- C -- D -- E -- F -- G
|                             |
master                        dev
Origin/master

押しつぶしたい

A -- H -- E -- F -- G
|                   |
master              dev
Origin/master

ここで、HB -- C -- Dと同等です。そして、Hのコミットメッセージを指定できるようにしたいと思います。 Aはプッシュされた最後のコミットなので、サーバーを混乱させることなく、その後のすべてのコミットを書き換えることができます。 masterを早送りする前に、履歴を整理するのが目的です。

どうやってやるの ?

PS:私の場合、実際には、スカッシュへのコミットが3つ以上ありますが、3つで実行できれば、もっと多く実行できるはずです。

PPS:また、可能であれば、EF、およびGをそのままにしておくソリューションをお勧めします(主にコミット日に関して)。

29
deadbeef

インタラクティブなリベースを行って、スカッシュしたいコミットを手動で選択できます。これはdevブランチの履歴を書き換えますが、これらのコミットをプッシュしていないので、自分のコンピューターで発生する可能性があること以外に、これによる悪影響はありません。

以下から始めます。

git checkout dev
git rebase -i HEAD~6

これにより、次の7つのコミットのリストを示すウィンドウが表示され、devブランチのHEADから6ステップ戻ります:

pick 07c5abd message for commit A
pick dl398cn message for commit B
pick 93nmcdu message for commit C
pick lst28e4 message for commit D
pick 398nmol message for commit E
pick 9kml38d message for commit F
pick 02jmdmp message for commit G

表示される最初のコミット(上記のA)は最も古いで、最後のコミットが最新です。デフォルトでは、各コミットのオプションはpickです。ここでリベースを完了した場合、各コミットをそのまま保持することになりますが、これは事実上何もしません。しかし、特定の中間コミットを押しつぶしたいので、リストを編集して次のように変更します。

pick 07c5abd message for commit A
pick dl398cn new commit message for "H" goes here
squash 93nmcdu message for commit C
squash lst28e4 message for commit D
pick 398nmol message for commit E
pick 9kml38d message for commit F
pick 02jmdmp message for commit G

上で何が起こっているのか注意してください。 squashと入力すると、そのコミットをマージするようにGitに指示します上記 it、これはすぐに来たコミットですbefore it。つまり、これはコミットDを逆方向にコミットCにスカッシュし、次にCBにスカッシュして、コミットBを1つだけコミットすることを示しています。 $ var] _、C、およびD。他のコミットはそのままです。

ファイルを保存します(: wq WindowsのGit Bashの場合)、リベースは完了です。予想されるように、これからマージの競合が発生する可能性がありますが、それらを解決することは特別なことはなく、通常のリベースまたはマージの場合と同様に続行できます。

リベース後にブランチを調べると、EF、およびGコミットに新しいハッシュ、日付などが含まれていることに気づくでしょう。これは、これらのコミットが原因です。実際には新しいコミットに置き換えられました。これは、履歴を書き直したため、一般的にコミットが以前と同じにならないためです。

38
Tim Biegeleisen