1

Git can be cryptic sometimes and the documentation out there even more so. My team and I are faced with a very particular situation. For reference, we have a production ready master branch and a develop branch. Our branching strategy is as follows:

  • branch off master to create feature branch
  • merge feature into develop for integration and functional testing
  • submit merge request to master when feature is done

One of the devs accidentally merged develop into his feature before merging it into master, so there was a bunch of unvetted code that went into feature as well. I reverted that merge to master, then the dev fixed his branch to remove all the unvetted code. However, when trying to merge his branch into master again, it threw an error. It seems to be because master already had the feature branch's history so it wouldn't accept it again.

What is the proper way to handle this situation.

P.S. - Trying to wrap my head around the difference between merging and rebasing. I understand that merge pulls in code changes and leaves everything else in tact, creating a new history for the commit. However, how does rebase work? My understanding is that it sets one branch to exactly the same state as another. Is this correct?

Ryan Cohan
  • 109
  • 1
  • 11
  • Rebase takes two branches, and plucks branch one off of the git tree at the point where it converges with branch two. It then puts the base of branch one at the tip of branch two (it rebases it). – symlink Apr 24 '20 at 17:57
  • 1
    "Proper way" - there isn't. If this was my own private repo, I would not use revert (as it is a _new_ commit). – evolutionxbox Apr 24 '20 at 18:18
  • Rebase writes completely new history. This means if you do `git rebase master` while on the feature branch. It will place your feature branch commits always on top of master. – Utsav Patel Apr 24 '20 at 18:47
  • 1
    There is a trick so that you can merge the history again. It is in [this answer](https://stackoverflow.com/questions/57904970/reverting-a-git-merge-while-allowing-for-the-same-merge-later/57905240#57905240). – j6t Apr 24 '20 at 18:52

1 Answers1

5

This is explained very well in the Git Documentation itself, under revert a faulty merge. Quoting Linus:

Reverting a regular commit just effectively undoes what that commit did, and is fairly straightforward. But reverting a merge commit also undoes the data that the commit changed, but it does absolutely nothing to the effects on history that the merge had.

So the merge will still exist, and it will still be seen as joining the two branches together, and future merges will see that merge as the last shared state - and the revert that reverted the merge brought in will not affect that at all.

So a "revert" undoes the data changes, but it's very much not an "undo" in the sense that it doesn't undo the effects of a commit on the repository history.

So if you think of "revert" as "undo", then you're going to always miss this part of reverts. Yes, it undoes the data, but no, it doesn't undo history.

There are two options to get the changes of the branch "again":

  1. Revert the revert
  2. Rebase the branch without the faulty code, effectively creating new history, i.e. completely new commits and then merge this new branch (it won't share the same history, so it looks "new" when merging)
knittl
  • 246,190
  • 53
  • 318
  • 364