brool

brool \brool\ (n.) : a low roar; a deep murmur or humming

Poison Reverts in Git

Alice owns the main branch that a bunch of people are using: A -- B -- C -- D

Bob checks it out, makes changes 0..2, and does regular pulls: A -- B -- 0 -- 1 -- C -- 2 -- D

Now, Alice pulls Bob’s stuff: she has A -- B -- C -- D -- (0 + 1 + 2)

Alice pulls from another developer: A -- B -- C -- D -- (0 + 1 + 2) -- E

Bob’s patch is bad! How did it get through the audits and QA and unit tests? No matter, revert it. Alice now has:

A -- B -- C -- D -- (0+1+2) -- E -- (-0 -1 -2)

(Note that Alice can’t rebase Bob’s changes out of the history because other developers are pulling from her).

Bob sees that his commits didn’t work, is properly chastened, and makes a fix titled “3″.

Now, see the problem:

  • If Bob pulls from Alice, he’ll either get a merge conflict if he’s made changes, or his stuff will get deleted out of his repo (!)
  • If Alice pulls from Bob, then she’ll have problems — her mainline thinks that it’s already taken Bob’s changes, but now he’s trying to change a deleted file.

So it looks like Git is in a situation where someone or the other (or both) are going to have to do a painful merge conflict resolution. There must be a better way of reverting a patch?

Update 3/20/2009: The word from Linus on this. He says that when you unrevert the merge that you always need to revert the revert, rather than trying to apply it again.

Leave a Reply