0

Consider the following situation:

git configuration has rerere.enabled 1, enabling resolution recording and replay. The following commit history exists:

  B
 / \
A---C---E master 
 \   \ / 
  D   D'
  1. Commit B was merged in master with --no-ff to create commit C.

  2. Commit B and D contain conflicting modifications to a file Foo.

  3. Commit D was rebased to C creating commit D' - the conflict in Foo was erroneously resolved by taking the changes in D only. The correct resolution would have included changes from both B and D.

  4. Commit D' was merged into master to create commit E, and changes to Foo due to commit B were lost without conflict.

  5. A later inspection revealed the mistake. A attempt to recover was performed by executing git cherry-pick B on master with the intention of being able to manually resolve the conflict correctly using a mergetool. However, rerere kicks in and replays the bad resolution. No git rerere invocations seem to be able to show or clear the bad resolution.

What's the best way to deal with this situation? Is it a bug in git that cherry-pick has no rerere override (I am on version 2.9.2)? It feels like something that would crop up often, yet I can't find examples of it being addressed in the documentation (which may be poor searching on my part).

Bear in mind this is a vastly simplified commit tree. In reality there were dozens more commits along the way between those shown, over the period of several days - but the essence of what happened is as captured above.

James World
  • 29,019
  • 9
  • 86
  • 120

1 Answers1

0

Here's what I did, but is there a better way?

It seems that there is no equivalent to the git merge --no-rerere-autoupdate for git cherry-pick. The best way I could think of to get around this was to temporarily apply git config --local --add rerere.enabled 0, which worked - that is I could then git cherry-pick B without the automatic resolution and then use git mergetool to resolve the conflict. This is a bit of a pain - especially as you have to remember to undo the config setting afterwards, but it does have the advantage of presenting the correct merge base in the diff tool.

Another approach I tried was to use git checkout B . (note the dot) to grab the changes into the index, and use git difftool --cached to edit Foo in my diff tool. Whilst this works and is less steps, it doesn't give you the merge base to work from in the diff.

James World
  • 29,019
  • 9
  • 86
  • 120