44

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

私は持っている :

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

私はそれをつぶしたい

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

Hと同等ですB -- C -- D。そして、のコミットメッセージを指定できるようにしたいHAプッシュされた最後のコミットであるため、その後のすべてのコミットは、サーバーを台無しにすることなく書き換えることができます。アイデアは、早送りする前に履歴をクリーンアップすることですmaster

どうやってやるの ?

PS: 私の場合、実際には途中でスカッシュするコミットが 3 つ以上あることに注意してください。

PPS: また、可能であれば、 と が変更されない (主にコミット日に関して) ソリューションを希望EFますG

4

1 に答える 1

67

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

以下から始めます。

git checkout dev
git rebase -i HEAD~6

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

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 に指示ます。したがって、これは commit を commitにD逆方向に押しつぶし、C次に に押しつぶすことCを示しBています。他のコミットはそのままです。BCD

ファイルを保存して ( : wqWindows の Git Bash に)、リベースが完了します。ご想像のとおり、これからマージの競合が発生する可能性があることに注意してください。ただし、それらを解決することについて特別なことはなく、通常のリベースまたはマージと同じように続行できます。

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

于 2016-08-18T16:47:54.567 に答える