Eugen Konkov Eugen Konkov - 10 months ago 71
Git Question

How to recreate the conflicted file state with the checkout command?

I have long life branch and some time ago I have resolved big merge conflict. Now I want again merge

into my branch but got conflict. I have google a bit and found

But when I do:

git checkout --conflict=merge FileTheMergeConflictWas.ext

I get nothing.

What should I do to create merge conflict resolution file and complete my current merge with automatic resolution?

Answer Source

If your merge is already committed, it is in one sense too late. The rerere code works by recording the conflict at the time the conflict occurs, and then recording (separately) the conflict resolution once you have resolved the conflict.

Both the conflict itself, and your previous resolution, happened in the past, when git rerere was not enabled. Hence, to get git rerere to record them now, you must go back in time, enable git rerere, start the merge, get the conflict, resolve the conflict, and then return to the present.

If you have a time machine handy, you can use that. :-) Most of us don't, but fortunately, Git is a time machine! Well, sort of.

Simply turn on git rerere, then check out the correct commit using the history. This will give you a "detached HEAD" with HEAD pointing to the commit that you just checked out. Which commit is the correct one? Well, the one right before you did the merge last time, of course. That's the first parent of the existing merge commit.

Then, now that you have a detached HEAD and are on the correct commit, do the merge, which will have conflicts:

git merge <hash-id>

What's the correct hash ID for the commit to merge? Why, the one you used when you did the merge last time, of course. That's the second parent of the existing merge commit.

This merge will, of course, fail due to the conflict. But now the conflict is recorded, because you, back in the past with your detached HEAD, are recording this time. Now resolve the conflict the same way you did before. To save time, you can simply copy the correct resolution from the past. That correct resolution is in the merge you committed. So:

git show <merge-id>:path/to/conflict.ext > path/to/conflict.ext

Now git add the resolved file (repeat for all files as needed) and run git commit to record the final resolution.

Now, time-travel back to the present, abandoning the merge you just made. It has served its purpose, which was to record the conflict and the resolution:

git checkout thebranch

and you are now ready to go.

Minor annoyances

If you are currently in the middle of a conflicted merge or rebase, you will have to abort it now, then use the Git time machine to go back and re-merge, then restart your conflicted merge or rebase. (If you have a lot of useful work done, you might want to save it first—just commit it somewhere and/or create a branch or tag name pointing to the current commit, as needed and appropriate—and only then abort.)