gitであるブランチの途中までの変更を、別のブランチに適用させたい

A(リビジョンan), B(リビジョンa0) があったとして
変更a1,a2,...an を適用させたい。

最新の状態を適用させるだけでいい場合はブランチBでgit pull -b A を指定するだけでいい。
ただし今回はブランチAの途中の変更までをBへ適用したい。







cherry-pick を使用して特定のリビジョンを取得する。



git checkout で取り込み元へ移動
git log などで取得したいリビジョンのリビジョン番号を取得する。

変更を適用したいリポジトリ(B)で git cherry-pick を実行すると指定したリビジョンの差分が適用される。

error: could not apply 9ddf2d9... update:
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add ' or 'git rm '
hint: and commit the result with 'git commit'
could not apply

が表示される場合

上記はコンフリクトが発生していて
cherry-pickは指定したリビジョンの差分しか持ってこないらしい。

指定した範囲の差分を適用させる。
git cherry-pick e3eb7cxxxx..9ddf2dxxxx

マージコミットを含む場合オプション指定がいるらしい。
git cherry-pick -m 1 e3eb7cxxxx..9ddf2dxxxx

オプション1を指定すると マージ先を基準にする。

error: a cherry-pick or revert is already in progress
hint: try "git cherry-pick (--continue | --quit | --abort)"
fatal: cherry-pick failed

mainline was specified but commit 9ddf2d96c9f9fa01ab100da7468c4axxxxxxxx is not a merge.

mergeコミットは -m 1をつけて通常コミットはリビジョン番号を指定する。
マージコミットと普通のコミットが混在している場合一気に持ってくる手段はなさそう。
古い順に1個ずつ適用していけばいける?ただしめんどくさい。



特定のバージョンを指定して取得する(checkout, pull)



pullコマンドは最新の状態しか取得できないが特定のリビジョンをチェックアウトすることはできる。
これを利用する。
例えばAブランチの9ddf2dxxxx をBに適用させたい場合

> git checkout 9ddf2dxxxx

Note: checking out '9ddf2dxxxx'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

ローカルからローカルへは持ってこれないようなので一旦リモートへ9ddf2dxxxxをプッシュする。
git push -u origin 9ddf2d96c9

Bブランチへ移動
git checkout B

git pull origin 9ddf2dxxxx

こっちの方が早くて楽




参考


https://git-scm.com/docs/git-cherry-pick
http://dackdive.hateblo.jp/entry/2016/06/06/203542
https://qiita.com/daikiichikawa/items/7d8c6471e8827f756f22
http://nkawamura.hatenablog.com/entry/2015/12/12/234716




2018年5月27日日曜日