できない.dev

Git cherry-pick でコンフリクトが解決できない

cherry-pick は対象コミットの差分のみを現在ブランチに当て直す操作なので、merge / rebase と同じくコンフリクトが起こる。
手動で衝突を解消して git add → git cherry-pick --continue、やめるなら --abort で開始前に戻す。

#git#cherry-pick#conflict#abort#range

要約

git cherry-pick のコンフリクトも基本は merge / rebase と同じ流れで解消する。<<<<<<< マーカーを潰し、git addgit cherry-pick --continueやめたいときは git cherry-pick --abort で開始前の HEAD に戻る。
merge コミットを cherry-pick する場合だけ -m で親番号を指定する。

よくある原因

  1. 同じ行を別ブランチで既に変更している: cherry-pick はコミットの差分を再適用するため、当ブランチ側で同じ箇所が変わっていれば必ず衝突する。
  2. continue を忘れて commit: 通常通り git commit してしまい、cherry-pick の進行管理が壊れる。
  3. マーカー残しの add: <<<<<<< HEAD / ======= / >>>>>>> を消し忘れ、壊れた内容を git add してしまう。
  4. merge コミットを直 cherry-pick: 親が複数あるコミットには -m で親番号指定が要る。
    指定なしだと is a merge but no -m option was given で止まる。

解決策

1. 衝突を解消して続行

git cherry-pick <sha>
# CONFLICT が出たら
$EDITOR path/to/file        # マーカーを消し正しい内容にする
git add path/to/file
git cherry-pick --continue

git statuscherry-picking <sha> と衝突ファイルが確認できる。

2. 中止して元に戻す

git cherry-pick --abort

cherry-pick 開始前の HEAD に戻る。--skip は当該コミットを飛ばして次に進む。

3. 範囲指定の cherry-pick

連続コミットをまとめて当てたい場合:

git cherry-pick A^..C

A を含むのが A^..C、含まないのが A..C
途中で衝突したら同じく --continue で進める(公式ドキュメント)。

4. merge コミットを cherry-pick

git cherry-pick -m 1 <merge-sha>

-m 1 で「親 1 番からの差分を当てる」と明示する。
どちらの親が正しいかはマージ元のブランチに合わせる。

この記事は役立ちましたか?