問題となった状態
初期状態
-
developブランチには以下のコミットがあります:* commit3 - Develop Feature C * commit2 - Develop Feature B * commit1 - Initial commit -
feature-aブランチには以下のコミットがあります:* commit5 - Feature A2 * commit4 - Feature A1 -
feature-bブランチには以下のコミットがあります:* commit7 - Feature B2 * commit6 - Feature B1
誤ったマージ
feature-a ブランチに feature-b ブランチを誤ってマージしました:
git checkout feature-a
git merge feature-b
これにより、feature-a ブランチの履歴は以下のようになります:
* merge-commit-feature-b - Merge branch 'feature-b'
* commit7 - Feature B2
* commit6 - Feature B1
* commit5 - Feature A2
* commit4 - Feature A1
マージの取り消し
この誤ったマージを git revert で取り消します:
git revert -m 1 <merge-commit-feature-b-hash>
これにより、feature-a ブランチの履歴は以下のようになります:
* revert-merge-commit-feature-b - Revert "Merge branch 'feature-b'"
* merge-commit-feature-b - Merge branch 'feature-b'
* commit7 - Feature B2
* commit6 - Feature B1
* commit5 - Feature A2
* commit4 - Feature A1
feature-a ブランチの develop へのマージ
feature-a ブランチを develop にマージします:
git checkout develop
git merge feature-a
これにより、develop ブランチの履歴は以下のようになります:
* merge-commit-feature-a - Merge branch 'feature-a'
* revert-merge-commit-feature-b - Revert "Merge branch 'feature-b'"
* merge-commit-feature-b - Merge branch 'feature-b'
* commit7 - Feature B2
* commit6 - Feature B1
* commit5 - Feature A2
* commit4 - Feature A1
* commit3 - Develop Feature C
* commit2 - Develop Feature B
* commit1 - Initial commit
feature-b ブランチの develop への再マージ
feature-b ブランチを develop にマージしようとします:
git checkout develop
git merge feature-b
コンフリクトの発生
この再マージの際に、Gitは以下のようにコンフリクトを検出します:
-
developブランチには既にfeature-bの変更(commit6とcommit7)が含まれており、それがrevert-merge-commit-feature-bによって取り消されています。 - そのため、
feature-bの同じ変更を再適用しようとすると、既に存在するrevert-merge-commit-feature-bと衝突します。
対策
reset を使いましょう。この方法では、feature-a ブランチの状態を誤って feature-b をマージする前の状態に戻し、その状態を develop にマージします。
reset を使った解決法
feature-a ブランチのリセット
feature-a ブランチを誤って feature-b をマージする前の状態にリセットします。
-
feature-aブランチにチェックアウト:git checkout feature-a -
リセットポイントのコミットハッシュを確認:
feature-aブランチを誤ってfeature-bをマージする前のコミット(commit5)のハッシュを確認します。git log --oneline例えば、リセットしたいコミットハッシュが
commit5の場合: -
feature-aブランチをリセット:git reset --hard <commit5のハッシュ>これにより、
feature-aブランチの履歴は以下のようになります:* commit5 - Feature A2 * commit4 - Feature A1 -
リモートリポジトリに強制プッシュ:
リセット後の状態をリモートリポジトリに反映させます。git push --force
develop ブランチへのマージ
-
developブランチにチェックアウト:git checkout develop -
feature-aブランチをマージ:git merge feature-a git pushこれにより、
developブランチの履歴は以下のようになります:* merge-commit-feature-a - Merge branch 'feature-a' * commit5 - Feature A2 * commit4 - Feature A1 * commit3 - Develop Feature C * commit2 - Develop Feature B * commit1 - Initial commit
feature-b ブランチの develop へのマージ
-
feature-bブランチをdevelopにマージ:git checkout develop git merge feature-b git pushこれにより、
developブランチの履歴は以下のようになります:* merge-commit-feature-b - Merge branch 'feature-b' * commit7 - Feature B2 * commit6 - Feature B1 * merge-commit-feature-a - Merge branch 'feature-a' * commit5 - Feature A2 * commit4 - Feature A1 * commit3 - Develop Feature C * commit2 - Develop Feature B * commit1 - Initial commit
まとめ
この方法では、feature-a ブランチを誤って feature-b をマージする前の状態に戻し、その状態を develop にマージします。これにより、feature-a の変更が正しく develop に統合され、その後 feature-b の変更を再度 develop にマージしてもコンフリクトが発生しません。