gitでトピックブランチをマージ中にリモートブランチが更新されたときの対応
例えば自分の環境で
$ git merge --no-ff feature/add-c
トピックブランチをmaster
ブランチにマージして
$ git push error: failed to push some refs to '********' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
push
しても、できなかったときの対応。
$ git fetch remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0 Unpacking objects: 100% (3/3), done. From ******** baf2594..2d4f9f4 master -> origin/master
fetch
してリモートブランチと同期をとり
$ git status On branch master Your branch and 'origin/master' have diverged, and have 2 and 2 different commits each, respectively. (use "git pull" to merge the remote branch into yours) nothing to commit, working directory clean
status
を確認すると、master
ブランチとリモートブランチが分岐した状態になっている。
ここでは、自分の環境はトピックブランチ(feature/add-c
)をマージした状態で
$ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative * 5361769 - (HEAD -> master) Merge branch 'feature/add-c' (2 minutes ago) <te2u> |\ | * f3fbe42 - (feature/add-c) add c (3 minutes ago) <te2u> |/ * baf2594 - add a (17 minutes ago) <te2u>
リモートブランチは別のトピックブランチ(feature/add-b
)をマージした状態とする。
$ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative origin/master * 2d4f9f4 - (origin/master) Merge branch 'feature/add-b' (14 minutes ago) <te2u> |\ | * ec63e2a - add b (16 minutes ago) <te2u> |/ * baf2594 - add a (18 minutes ago) <te2u>
メインブランチにトピックブランチ以外のマージを作るのは避けたいのでrebase
したいところだが、ここで
$ git rebase origin/master First, rewinding head to replay your work on top of it... Applying: add c
そのままrebase
すると
$ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative * 0f50808 - (HEAD -> master) add c (23 seconds ago) <te2u> * 2d4f9f4 - (origin/master) Merge branch 'feature/add-b' (16 minutes ago) <te2u> |\ | * ec63e2a - add b (18 minutes ago) <te2u> |/ * baf2594 - add a (20 minutes ago) <te2u>
自分の環境で作成したマージコミットが失われてしまう。
マージコミットが失われないようにするには、rebase
するときに
$ git rebase --preserve-merges origin/master
Successfully rebased and updated refs/heads/master.
preserve-merges
オプションをつけて実行する。こうすると
$ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative * 93ab538 - (HEAD -> master) Merge branch 'feature/add-c' (11 seconds ago) <te2u> |\ | * d3dedd9 - add c (11 seconds ago) <te2u> |/ * 2d4f9f4 - (origin/master) Merge branch 'feature/add-b' (19 minutes ago) <te2u> |\ | * ec63e2a - add b (20 minutes ago) <te2u> |/ * baf2594 - add a (22 minutes ago) <te2u>
リモートブランチのHEAD
に、自分の環境でマージしたときのブランチが残った形で適用される。あとは
$ git push Counting objects: 3, done. Delta compression using up to 8 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 317 bytes | 0 bytes/s, done. Total 3 (delta 1), reused 0 (delta 0) To ******** d8219f9..2bb1372 master -> master
push
して、リモートブランチを更新する。