{"thread":{"id":"28063","subject":"Documenting the 'rebase -i' workflow","startedAt":"2011-08-11T07:00:07Z","lastAt":"2011-08-11T07:00:07Z","messageCount":1,"participants":["Ramkumar Ramachandra"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"173259","messageId":"CALkWK0kAX3U9AJvD4Gw9Cwndk9412jB4O_P+OGZKFk4kMhpnsg@mail.gmail.com","threadId":"28063","inReplyTo":null,"subject":"Documenting the 'rebase -i' workflow","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2011-08-11T07:00:07Z","receivedAt":"2011-08-11T07:00:07Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Hi,\n\nI used to find it hard to resolve conflicts during complex interactive\nrebases, and I asked Jonathan for help off-list.  I found the response\nvery useful.  I thought I should reproduce the original email here so\nthat everyone on the list can benefit from it.  Please feel free to\nadd to it.\n\nAlso, we should document this somewhere.\n\n-- 8< --\nRamkumar Ramachandra wrote:\n> How did you manage to make the rebase look so effortless?  I tried it\n> too, but I always end up messing up the conflict resolution, and\n> aborting many times before I get it right.  Even after that, I run\n> tests on all the patches and correct the pending mistakes by hand.\n\nTrue, this workflow is underdocumented.  The most important details\nare\n\n       [merge] conflictstyle = diff3\n       [rerere] enabled\n\nin ~/.gitconfig.  I used to use \"git checkout --conflict=diff3\"\nexplicitly instead, which also works.\n\nIf you are lucky, a conflict hunk will look something like this:\n\n       <<<<<<< ours\n       A\n       B\n       C\n       ||||||| parent of theirs\n       B\n       =======\n       B\n       C\n       D\n       >>>>>>> theirs\n\nIt can be merged blindly by following the rule \"whenever a feature\nis the same between the ancestor and one of the competing versions,\ndelete it from them\".  For example, both the ancestor and \"theirs\"\nhave 'B', so:\n\n       <<<<<<< ours\n       A\n       B\n       C\n       ||||||| parent of theirs\n       =======\n       C\n       D\n       >>>>>>> theirs\n\nOur side and their side both added C independently and from the\ncontext we know that a second 'C' would be redundant.  So we are ready\nto resolve the conflict after thinking a little.\n\n       A\n       B\n       C\n       D\n\nUnfortunately sometimes the diff3 conflict style makes conflicts huge\nand unmanageable.  That's no good.  I dream of a conflict style that\nwould show \"our\" version and the patch hunk to apply.  Since that\ndoesn't exist yet, often a good strategy is to fake it by looking at\nthe patch directly.  For example, patches to ChangeLog files rarely\nmerge cleanly and the conflicts don't tend to be very useful.\n\n       git checkout HEAD ChangeLog\n       vim ChangeLog\n       :split .git/rebase-merge/patch\n\n\"git add\" is used to mark good changes and \"git diff\" to see what's\nleft to do.  When ready, I build, run some simple tests, \"git diff\n--cached\", \"git rebase -i --continue\", flinch at how git 1.7.6 broke\nmy muscle memory, and \"git rebase --continue\".\n\nUsually I try to only make a single change in an interactive rebase\nand let it ripple through, then rinse and repeat.  If something goes\nwrong, I can \"git rebase --abort\" and previous unrelated changes are\nnot lost.\n\nAfter a rebase, I use \"git diff\" to compare to the previous version,\nto make sure the changes accumulated are good and nothing was lost.\n\nSummary:\n\n - conflictstyle=diff3 makes 3-way merging require way less thought\n  and history mining.  I don't know how I coped with\n  conflictstyle=merge.\n\n - For thorny cases, \"git checkout --ours file\" unapplies the patch.\n  Then one can\n\n   (a) apply the patch by hand, if it is short.\n   (b) fix up the patch by hand and apply it with \"git apply\", if\n       it is long.\n\n  The patch is in .git/rebase-merge/patch.\n\n - \"git rerere forget\" is a lifesaver.\n\n - Check for sanity at each step (by running manual or automatic\n  tests) before continuing.\n\n - Inspect with \"git log -p\" and by diffing against a merge of the\n  pre-rebase state with the new upstream when done.\n"}]}