Hi, I used to find it hard to resolve conflicts during complex interactive rebases, and I asked Jonathan for help off-list. I found the response very useful. I thought I should reproduce the original email here so that everyone on the list can benefit from it. Please feel free to add to it. Also, we should document this somewhere. -- 8< -- Ramkumar Ramachandra wrote: > How did you manage to make the rebase look so effortless? I tried it > too, but I always end up messing up the conflict resolution, and > aborting many times before I get it right. Even after that, I run > tests on all the patches and correct the pending mistakes by hand. True, this workflow is underdocumented. The most important details are [merge] conflictstyle = diff3 [rerere] enabled in ~/.gitconfig. I used to use "git checkout --conflict=diff3" explicitly instead, which also works. If you are lucky, a conflict hunk will look something like this: <<<<<<< ours A B C ||||||| parent of theirs B ======= B C D >>>>>>> theirs It can be merged blindly by following the rule "whenever a feature is the same between the ancestor and one of the competing versions, delete it from them". For example, both the ancestor and "theirs" have 'B', so: <<<<<<< ours A B C ||||||| parent of theirs ======= C D >>>>>>> theirs Our side and their side both added C independently and from the context we know that a second 'C' would be redundant. So we are ready to resolve the conflict after thinking a little. A B C D Unfortunately sometimes the diff3 conflict style makes conflicts huge and unmanageable. That's no good. I dream of a conflict style that would show "our" version and the patch hunk to apply. Since that doesn't exist yet, often a good strategy is to fake it by looking at the patch directly. For example, patches to ChangeLog files rarely merge cleanly and the conflicts don't tend to be very useful. git checkout HEAD ChangeLog vim ChangeLog :split .git/rebase-merge/patch "git add" is used to mark good changes and "git diff" to see what's left to do. When ready, I build, run some simple tests, "git diff --cached", "git rebase -i --continue", flinch at how git 1.7.6 broke my muscle memory, and "git rebase --continue". Usually I try to only make a single change in an interactive rebase and let it ripple through, then rinse and repeat. If something goes wrong, I can "git rebase --abort" and previous unrelated changes are not lost. After a rebase, I use "git diff" to compare to the previous version, to make sure the changes accumulated are good and nothing was lost. Summary: - conflictstyle=diff3 makes 3-way merging require way less thought and history mining. I don't know how I coped with conflictstyle=merge. - For thorny cases, "git checkout --ours file" unapplies the patch. Then one can (a) apply the patch by hand, if it is short. (b) fix up the patch by hand and apply it with "git apply", if it is long. The patch is in .git/rebase-merge/patch. - "git rerere forget" is a lifesaver. - Check for sanity at each step (by running manual or automatic tests) before continuing. - Inspect with "git log -p" and by diffing against a merge of the pre-rebase state with the new upstream when done. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html