7 ms·
Oh, reverting merges! I've been there, and it is completely possible, out of the box, with git. But! It requires a relatively thorough understanding of how it w
by rallison 13y ago
Oh, reverting merges! I've been there, and it is completely possible, out of the box, with git. But! It requires a relatively thorough understanding of how it works, or you will definitely mess it up. I wrote up this summary a while back for our company wiki:
Imagine this scenario:
- Team Sandy does a ton of work on branch foo.
- Team Sandy ensures the release manager that branch foo is perfect and bug free.
- Team Sandy merges branch foo into branch develop and pushes.
- Other developers continue committing to develop.
- Massive devastation and destruction start occurring due to massive bugs scattered throughout Sandy's code.
At this point, we want to get all of Sandy's code out of develop, as we can't post to production until develop is Sandy-free. What do we do?
- Revert the merge commit
The important thing to note here is that this basically undoes the effect of the merge, but NOT the history. If you were to try to merge branch foo back in at a later date, git would do nothing and tell you that everything is already merged in. This is technically correct, but confusing.
Let's imagine that Sandy goes back to branch foo and commits bug fixes to fix the devastation. Now, branch foo is ready to be merged back in. What do we do?
- Revert the revert commit (yes, really). This basically undoes the effect of our original undo. At this moment, develop has all of branch foo's code pre-bug fixes.
- Merge foo into develop. This merges the subsequent bug fix commits into develop.
A much more thorough discussion can be enjoyed here (I highly recommend the read): https://www.kernel.org/pub/software/scm/git/docs/howto/revert-a-faulty-merge.txt https://www.kernel.org/pub/software/scm/git/docs/howto/rever...
--
Basically, it can be done with one line on the commandline, but I wouldn't recommend anyone do it unless they've read the above (specifically, the discussion I've linked to).
- jheriko 13y ago'- Revert the merge commit' this is what i had problems with. i got an error message back from git that you can't revert a branch commit and when i googled it the conclusion i came to was i needed to go back in time and change our configuration to make this possible. its entirely possible that i ended up down the wrong path from google searching. now, googling around i find some stack overflow answers and such i'm pretty sure i found at the time i had the issue. when i am next there (at work) i'll see if i can find a copy of that repo or recreate the same problem so that i can show what happened and why it is difficult to solve and dangerous in a production environment. actually... i might just try and repro it now, but my connection is so poor here (at home) that even installing git is likely to be painful. however, ignoring that, the process you describe is horribly counter intuitive. well done for working it out in the first place, although i do see this suggested in a few of the stack overflow answers... :)
- stormbrew 13y agoIt's possible that when you were doing this things were different, because even in the last year or so it seems like git has become a lot less esoteric in its interface, but the man page for git revert currently explains a fair bit about how to use it to revert a merge commit. Basically you just need to specify which parent (of the merge commit's 2 parents) is the one that should survive the reversion with '--mainline'. This seems intuitive to me, with a maybe deeper than average understanding of git, though the rather more involved process of undoing the reversion is less so.
- jheriko 13y agoyeah, i feel like this is almost certainly the case. that man page was absolutely my first stop when i got the error message and looking at it now i can't imagine how distracted and stupid i must have been to have missed all of that information. its a weak argument, but i have never struggled to learn anything when provided sufficient information. usually much less than that is enough...
- rallison 13y agoI completely agree that reverting a merge in git is painful (painful, that is, in figuring out the parameters to pass to git revert). Let's say this is your scenario: d Merge branch 'test' |\ | c-test Test Branch Commit 1 b | Master Commit 2 \| a Master Commit 1 And let's say you want to revert d, the merge commit. You would do this: git revert -m 1 HEAD Now your history looks like this: e-master Revert "Merge branch 'test'" | d Merge branch 'test' |\ | c-test Test Branch Commit 1 b | Master Commit 2 \| a Master Commit 1 -m, or --mainline is the key here. Git needs to know which parent is the appropriate one to revert to. As the d-b-a line is the leftmost one, its parent number is 1. Let's say that, instead, for some reason you actually wanted to rely on the d-c-a line as the basis for the commit, effectively throwing away the changes presented in commit b. You would do: git revert -m 2 HEAD That said, you almost always want -m 1. And that said, this is how I understand merge reverts to work, but I've only had to do this a few times, so take that with a grain of salt. -- With all that said, I completely agree with you about the frustration in trying to figure it out, even with SO. This is exactly where some nice porcelain sitting on top of git could make things much simpler.