0

git rebase --preserve-merges

The doc says that "Merge conflict resolutions or manual amendments to merge commits are not preserved".

I understand how merge conflicts can be dealt by using rerere, but what exactly are manual amendments to merge commits? Does rerere deal with this as well? If not, is there a workaround?

user1164937
  • 1,979
  • 2
  • 21
  • 29

1 Answers1

1

The doc says that "Merge conflict resolutions or manual amendments to merge commits are not preserved".

What this sentence is saying (not very well) is that with --preserve-merges, git rebase actually re-does the merge.

It's not possible in general to preserve the original merge, and Git simply does not try. Instead, it notes that original commit M was a merge with extra parent(s) p2, p3, ..., pN over and above the parent in the chain you're rebasing. So, when copying M, instead of doing git cherry-pick <ID>, it does git merge p2 .... This, of course, makes an all-new merge.

The rebase code does not adjust your rerere settings at all, so you get whatever you have set.

... what exactly are manual amendments to merge commits?

This is probably best demonstrated by example:

$ git checkout br1
$ git merge --no-commit br2
Automatic merge went well; stopped before committing as requested
$ git status --short
A  file2
$ echo 'sneaky sneaky' >> file2
$ git add file2
$ git commit --no-edit
[br1 86ea409] Merge commit 'br2' into br1

The line I added to file2 appears nowhere in either branch: I amended it manually.

(Equivalently, I could let the merge do an auto-commit, and use git commit --amend afterward, which shoves the original merge aside and puts a new merge in place using whatever I have git added into the index since then.)

torek
  • 448,244
  • 59
  • 642
  • 775
  • How common is that example, or any manual amendments? My intention was to start rebasing my work after reviews, but I've experienced some branches that shared others' commits as well. – user1164937 Oct 20 '16 at 16:58
  • With any luck, *that* particular case is extremely rare: that's what I (and others) call an "evil merge", as it slips stuff in that was not in either branch originally, but clearly *should have been*. Other, saner, cases, such as manually resolved conflicts where some slight tweak is required (above and beyond just picking one version), are pretty common. – torek Oct 20 '16 at 17:54
  • Bummer. I guess I'm gonna mainly stick to local rebases, and only rebase further commits and force push if I'm the sole author to the end of the review. And use merge commits when other people are involved. I think rebasing shared branches is best left for organizations with strict guidelines. – user1164937 Oct 20 '16 at 18:18
  • Well, if you're rebasing a private branch where you did your own merge, and you remember that you did your merge sensibly, it would be safe enough to rebase with `--preserve`. But in general, I find that rebasing after merging is a bad plan—it's mainly useful for some special cases (like discovering a glitch in an earlier commit just before pushing). – torek Oct 20 '16 at 19:47
  • Actually, I've been thinking: Is there a reason why I should even use `-p` for my own private branch? If both preserving and not preserving the merges output the same code 100% of the time, I'm totally fine not using `-p`. They do in fact output the same code all the time, right? – user1164937 Oct 21 '16 at 05:36
  • Without `-p`, your `git rebase` will simply *omit* merge commits. If you aren't doing merges into your private branch, then (and *only* then): yes, you get the same result. (In the past, I've argued that this means that rebase should default to merge-preserving, but also merge-refusing, as it were: you probably don't *want* to copy some chain of commits if there's a merge in the chain. Once you really understand this part, you might sometimes want to copy-and-re-merge and you'd do that with an `--allow-merges` flag or some such.) – torek Oct 21 '16 at 13:54