Gitリポジトリの最初の2つのコミットを結合しますか?
-
22-07-2019 - |
質問
3つのコミット A、B および C を含む履歴があるとします:
A-B-C
2つのコミット A および B を1つのコミット AB に結合したい:
AB-C
試しました
git rebase -i A
次の内容でエディターが開きます:
pick e97a17b B
pick asd314f C
これを
に変更しますsquash e97a17b B
pick asd314f C
Git 1.6.0.4の場合:
Cannot 'squash' without a previous commit
方法はありますか、それとも不可能ですか?
解決
git rebase -i --root
を使用します
Git バージョン1.7.12 。
インタラクティブリベースファイルで、コミットの2行目を B から squash に変更し、他の行は pick のままにします:
pick f4202da A
squash bea708e B
pick a8c6abc C
これにより、2つのコミット A および B が1つのコミット AB に結合されます。
この回答で見つかりました。
他のヒント
試しました:
git rebase -i A
squash
ではなく edit
を続行すると、そのように開始できます:
edit e97a17b B
pick asd314f C
次に実行
git reset --soft HEAD^
git commit --amend
git rebase --continue
完了
A
は最初のコミットでしたが、今では B
を最初のコミットにしたいです。 gitコミットはツリー全体であり、通常は導入されたdiffの観点から説明および表示されていても、diffではありません。
このレシピは、AとB、およびBとCの間に複数のコミットがある場合でも機能します。
# Go back to the last commit that we want
# to form the initial commit (detach HEAD)
git checkout <sha1_for_B>
# reset the branch pointer to the initial commit,
# but leaving the index and working tree intact.
git reset --soft <sha1_for_A>
# amend the initial tree using the tree from 'B'
git commit --amend
# temporarily tag this new initial commit
# (or you could remember the new commit sha1 manually)
git tag tmp
# go back to the original branch (assume master for this example)
git checkout master
# Replay all the commits after B onto the new initial commit
git rebase --onto tmp <sha1_for_B>
# remove the temporary tag
git tag -d tmp
インタラクティブなリベースの場合、リストが次のようになるように、Aの前に実行する必要があります。
pick A
pick B
pick C
なる:
pick A
squash B
pick C
Aが初期コミットである場合、Aの前に別の初期コミットを行う必要があります。Gitは違いを考え、(AとB)と(BとC)の違いを処理します。したがって、この例ではスカッシュは機能しません。
数百または数千のコミットがある場合、 kostmoの回答を使用して
git rebase -i --root
インタラクティブなリベースエディターリストを生成するために一度リベーススクリプトが 2回処理しなければならないコミットが多数あるため、非実用的で遅い可能性があります各コミット)、およびコミットの再適用を実際に1回実行します。
代替ソリューションは、最初にインタラクティブなリベースを使用しないことにより、インタラクティブなリベースエディタリストを生成する時間コストを回避します。この方法では、 Charles Baileyのソリューションに似ています。 2番目のコミットから孤立ブランチを作成し、その上にすべての子孫コミットをリベースします。
git checkout --orphan orphan <second-commit-sha>
git commit -m "Enter a commit message for the new root commit"
git rebase --onto orphan <second-commit-sha> master
ドキュメント
関連する質問で、私は最初のコミットに対して潰す必要性に対する別のアプローチを思いつくことができました。
興味がある場合: git:最初にコミットを挿入し、他のすべてをシフトする方法
チームのGitコマンド: git rebase -i HEAD〜[コミット数]
gitのコミット履歴が下にあるとしましょう:
ピック5152061 feat:画像の保存のサポートが追加されました。 (A)
pick 39c5a04修正:バグ修正。 (B)
ピック839c6b3修正:競合が解決しました。 (C)
AとBをABに押しつぶしたい場合は、以下の手順を実行します。
ピック5152061 feat:画像の保存のサポートが追加されました。 (A)
s 39c5a04修正:バグ修正。 (B)
ピック839c6b3修正:競合が解決しました。 (C)
注:スカッシュコミットには、squashまたはsを使用できます。
最終結果は次のようになります。
ピック5152061 feat:画像の保存のサポートを追加しました。 (AB)
ピック839c6b3修正:競合が解決しました。 (C)
コマンドラインの魔法を少し実行する必要があります。
git checkout -b a A
git checkout B <files>
git commit --amend
git checkout master
git rebase a
これにより、コミットとしてABとCを持つブランチが残ります。