コミットの順序変更 質問する

コミットの順序変更 質問する

現在、ブランチで作業しており、いくつかのコミットを他のブランチにマージしたいと考えています。

    a-b-c-d-e-f-g (branchA)
   /
--o-x-x-x-x-x-x-x-x-x-x (master)
   \
    x-x-x-x-x (branchB)

(文字はコミットを示し、 はx無関係なコミットです。)

しかし、いくつかのコミットをプールするのが良いアイデアであることに気付きました。コミットadeg1 つのパッチに「連結」して にコミットしたいと考えていますmaster。コミットbと はf1 つのコミットとして にコミットする必要がありますbranchB。これを実現するための「git」風の良い方法はあるでしょうか?

ベストアンサー1

探しているコマンドはgit rebase、具体的には-i/--interactiveオプションです。

コミット c をブランチ A に残し、マージではなく他のコミットを他のブランチに移動したいと考えていると仮定します。マージは簡単なので、まずはブランチ A を操作するところから始めましょう。

git rebase -i <SHA1 of commit a>^ branchA

^前のコミットを意味するので、このコマンドは「a」の前のコミットをベースとしてブランチ A をリベースするように指示します。Git はこの範囲内のコミットのリストを表示します。それらを並べ替えて、適切なコミットを圧縮するように git に指示します。

pick c ...
pick a ...
squash d ...
squash e ...
squash g ...
pick b
squash f

履歴は次のようになります。

    c - [a+d+e+g] - [b+f] (branchA)
   /
--o-x-x-x-x-x-x-x-x-x-x (master)

ここで、ブランチ B の新しく圧縮されたコミット b+f を取得しましょう。

git checkout branchB
git cherry-pick branchA  # cherry-pick one commit, the tip of branchA

マスターの場合は、a+d+e+g も同様です。

git checkout master
git cherry-pick branchA^

最後に、branchA を更新して c を指すようにします。

git branch -f branchA branchA^^

これで次のようになります:

    c (branch A) - [a+d+e+g] - [b+f] (dangling commits)
   /
--o-x-x-x-x-x-x-x-x-x-x-[a+d+e+g] (master)
   \
    x-x-x-x-x-[b+f] (branchB)

ブランチ間で移動したいコミットが複数ある場合は、再度 rebase を使用できることに注意してください (非対話型):

# create a temporary branch
git branch fromAtoB branchA
# move branchA back two commits
git branch -f branchA branchA~2
# rebase those two commits onto branchB
git rebase --onto branchB branchA fromAtoB
# merge (fast-forward) these into branchB
git checkout branchB
git merge fromAtoB
# clean up
git branch -d fromAtoB

最後に、免責事項: コミットの順序を変更した結果、一部のコミットがきれいに適用されなくなる可能性は十分にあります。これは、間違った順序 (パッチを適用した機能を導入するコミットの前にパッチを配置する) を選択したために発生する可能性があります。その場合は、リベースを中止する必要があります ( git rebase --abort)。それ以外の場合は、競合を賢く修正し (マージ競合の場合と同様に)、修正を追加してから、実行しgit rebase --continueて先に進む必要があります。これらの手順は、競合が発生したときに表示されるエラー メッセージにも表示されます。

おすすめ記事