1

Consider a scenario where while merging a branch lets say feature into master (git megre origin/feature) and after resolving conflicts, if someone pushes into the master branch again during this process. Now, we cannot push the merge into master as they have diverted again. I see these options in these scenarios.

  • git rebase origin/master - This will screw up the whole merge history.
  • git merge origin/master - But now we have two merge commits in the history and the second one is in most cases unnecessary.
  • Discard all your work, fast forward you local branch to latest master and merge again with feature branch.

Is there anything obvious I am missing which is cleaner and does not requires to redo the merge conflict work we just did?

FUD
  • 5,114
  • 7
  • 39
  • 61
  • I'm not sure there is a nice way out from this. In my experience, this scenario is something which happens very rarely. In many cases, the reviewer (usually one person) is the one who would be merging feature branched back to master, and so this could never happen. – Tim Biegeleisen Apr 14 '18 at 09:45
  • Yes but master is a branch which is open to all, I am usually doing the merge work in our team and I have faced this twice now. For us the test build success windows is also 30 minutes which makes it even more probable that someone will push to master in between the merge process. – FUD Apr 14 '18 at 09:48
  • 1
    Then I would say you need to fix your workflow problem. In most organizations, master is closed to everyone. – Tim Biegeleisen Apr 14 '18 at 09:49
  • Thanks for the confirmation! Only if the pointy head bosses would ever listen! – FUD Apr 14 '18 at 10:01

1 Answers1

2

I think that you may want to try the following command:

git pull --rebase=preserve

or following if the upstream is already fetched

git rebase -p origin/master

where the semantics of option --rebase (according to the doc) is as follows:

When set to preserve, rebase with the --preserve-merges option passed to git rebase so that locally created merge commits will not be flattened.

However note that according to the doc of git rebase,

Merge conflict resolutions or manual amendments to merge commits are not preserved.

In order to avoid resolving conflicts again you can look into the usage of git rerere.

FUD
  • 5,114
  • 7
  • 39
  • 61
ErikMD
  • 13,377
  • 3
  • 35
  • 71
  • Interesting! So you are saying I need to do `git rebase origin/master --preserve-merges` and this will not change SHA's for the merge commit and the commits being merged from `origin/features` ? – FUD Apr 14 '18 at 09:57
  • 1
    Basically `git rebase --preserve-merges origin/master` should keep the upstream commits from `origin/master` as is, and replay your local history on top of that, including the merge commits you had performed just beforehand in `master` (while `git rebase origin/master` would flatten the history, and `git merge origin/master` would yield an extra, unwanted merge...) – ErikMD Apr 14 '18 at 10:01
  • However note that according to the [doc of git rebase](https://git-scm.com/docs/git-rebase#git-rebase---preserve-merges), "Merge conflict resolutions or manual amendments to merge commits are not preserved." unfortunately... – ErikMD Apr 14 '18 at 10:03
  • This may not work as you suggest. Git will try to recreate the merge commit, but I'm not sure it guarantees this. – Tim Biegeleisen Apr 14 '18 at 10:04
  • @TimBiegeleisen what do you mean by "I'm not sure it guarantees this"? – ErikMD Apr 14 '18 at 10:06
  • 1
    Regarding the issue I had mentioned with the possible merge conflicts, this has already been discussed on SO in this thread [Git rebase --preserve-merges fails](https://stackoverflow.com/questions/25670519/git-rebase-preserve-merges-fails/25671230#25671230) where the tool [git rerere](https://git-scm.com/docs/git-rerere) can be used for this use case. – ErikMD Apr 14 '18 at 10:10
  • @FUD you ask whether "it's as as good as option 3" and indeed, `git rebase --preserve-merges` can just be viewed as an automated way to perform your "option 3" in one go. Even if it just amounts to the same "algorithm", I still recommend using it in this case because it's more convenient to use it, and it can be combined with `git rerere` if need be. – ErikMD Apr 14 '18 at 10:16
  • @FUD Also note that regarding the SHA1 of the involved commits, it's fairly normal that the SHA1 of your previous local merge will change, because it is replayed on top of a different base, and this SHA1 change is not a problem because in practice this "local merge" you had performed before doing `git fetch origin && git rebase --preserve-merges origin/master` (or equivalently, `git pull --rebase=preserve origin master`) has not been pushed yet, so this SHA1 change shouldn't cause any issue with your collaborators which won't notice it anyway... – ErikMD Apr 14 '18 at 10:19
  • @ErikMD I am ok with sha of local merge commit changing as long as the sha of commits from feature branch does not change. However losing all your work is kind of a bummer. I'd rather have one more merge commit than redoing all the merge conflict resolutions again! – FUD Apr 14 '18 at 10:59