Git

merge commitをcherry-pickしようとしたら門前払いされた

tl;dr

conflictがあるとcherry-pickはできない

背景

前年と同様のイベントを開催することになったので、1年前のソースコードを復活させて使いまわしたい。
関連するブランチのマージコミットをごっそり持ってきちゃえないか、という話になったのでトライ。

トライ

cherry-pickを初めて使ったので公式ページ見て把握。
https://git-scm.com/docs/git-cherry-pick

以下、cherry-pickしたいマージコミットのハッシュ値を9ef7ae9とする。

$ git cherry-pick 9ef7ae9
error: commit 9ef7ae91f7c2fabb54633c5b7646c2c027bbb5f4 is a merge but no -m option was given.
fatal: cherry-pick failed
https://git-scm.com/docs/git-cherry-pick#git-cherry-pick--mparent-number

マージコミットは親が2ついるから、どちらの親を辿るのかわからないよーと怒られたので、-mオプションをつけて、追ってほしいブランチの一つ前のコミットのハッシュ値e6ead5fを指定。

$ git cherry-pick -m e6ead5f 9ef7ae9
error: switch 'm' expects a numerical value
usage: git cherry-pick [<options>] <commit-ish>...

-mオプションの後に指定するのはコミットのハッシュ値ではないようだ。
公式ページに戻って-mオプションの説明ページを読む。
いや、parent numberの調べかたこのページに載ってないんかい。

困ったときのstack overflow。ジャストミートなトピックが高確率である。
https://stackoverflow.com/questions/7211092/how-do-i-find-out-the-numbering-of-merge-commit-parents

git rev-parseコマンドで、あるコミットのある親番号のコミットハッシュ値を取得。

$ git rev-parse 9ef7ae9^1 #親番号1
7e7975d876af44cf92c2368b5b45060ac5304046

$ git rev-parse 9ef7ae9^2 #親番号2
e6ead5ffacc3ac96b887a1d6a90a7eb13485e734

今回は親番号2番が追いたいブランチのコミットだったので、-mオプションの後ろには2番を指定。

$ git cherry-pick -m 2 9ef7ae9
On branch feature/hogehoge
You are currently cherry-picking commit 9ef7ae91f7.

nothing to commit, working tree clean
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:

    git commit --allow-empty

Otherwise, please use 'git reset'
$ git st
On branch feature/hogehoge
You are currently cherry-picking commit 9ef7ae91f7.
  (all conflicts fixed: run "git cherry-pick --continue")
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

nothing to commit, working tree clean

conflict直さないとcommitデキナイヨー
conflict全部直した後git cherry-pick --continueシテネー
とのお告げ

・・・merge時のconflict修正っぽくできないの?
conflictしない状態にしてからcherry-pickしろよーって感じ?
おととい来やがれクソヤロー的な?

https://stackoverflow.com/questions/19830464/git-cherry-pick-and-conflicts
どうやらconflictがない状態じゃないとcherry-pickはできないらしい。

そもそもcherry-pickは同時並行で開発が進んでいるブランチ間で、特定のコミットのみ取り出したいという場合に用いるもので、
1年も前で、そこからかなり変更が加えられた大量のファイルを取ってくるのは間違った使い方なのかもしれない。

つらみ。

結論

conflictがあるとcherry-pickはできない。

参考

どうにかconflictしててもcherry-pickできて、あとでconflictをまとめて修正(merge時のconflictのように)できないか、と調べたところ、
https://stackoverflow.com/questions/19830464/git-cherry-pick-and-conflicts
meldというmergeツールをlinuxに導入してgitと連動させると、できるっぽい。
今回はここまでせず、違う方法で昔のソースコードを使いまわすことを考えた。