1

Despite best efforts we have gotten ourselves into quite the pickle with a feature branch in our Git repository. The end result is that a git diff develop..feature-branch shows a completely unexpected diff.

For instance, one file that was added in develop appears as a delete in the diff. Many other files show similar issues, some missing, some added, many many unexpected changes. Some files that should have been in develop do not even appear in the diff. We first noticed the issue in Atlassian Stash when we went to review the code via a Pull Request. The pending merge is completely and utterly incorrect and cannot be resolved through standard conflict resolution during the merge.

We attempted to decipher what caused this and we believe the problem stems from a developer performing several resets on commits in the feature branch that were already pushed to origin. This was to "revert" some changes suggested during a pull request code review. Specifically, we believe this to be the timeline of events.

  1. Feature branch created from develop
  2. Work performed on feature branch
  3. Pull request generated in Atlassian Stash (PR looks ok, but some minor edits suggested)
  4. Developer uses a reset to revert some changes and pushes those to origin
  5. Meanwhile minor conflicts noticed between develop and feature branch
  6. Developer updates feature branch from develop to reconcile conflicts and pushes to origin
  7. Pull request (diff) shows unexpected diff, drastically different from the one before. Files that are expected to be committed are missing and vice versa
  8. I attempt to undo (revert not reset) the "bad" merge and try it again. However the PR/diff shows the same incorrect changes for the pending merge
  9. I then learn that the developer used reset somewhere prior to the first merge from develop.

So, I have three questions.

  1. How we need to "recover" a corrected feature branch so we can merge our changes into develop correctly? My thought is to create a new "good" feature branch from a commit in our feature branch that is a known to occur before the resets. I can then cherry pick the commits we want from the "bad" feature branch into the "good" one to recreate it. Finally, I can merge the "good" feature branch into develop and delete the "bad" one.

  2. If I were to merge the "bad" feature branch into develop, aside from the incorrect state of the files, would there be any other "corruption" leaked into the develop branch. That is, would the polluted "bad" feature branch further pollute the develop branch and anything downstream from it? I do not plan to do this of course, but I do want to understand the ramifications.

  3. Would resets as I have described them cause the issues that I am seeing or is this possibly related to something else?

Ryan Taylor
  • 8,740
  • 15
  • 65
  • 98
  • The only way this scenario could have happened would be if the other developer did a "force push" to origin in step #4 (as the push would have been rejected from origin if it were not a fast-forward merge). Do you know if that is the case? – Patrick Jul 21 '14 at 13:06
  • Patrick, no. The developer did not do a "force push" to origin, though, the changes were pushed. – Ryan Taylor Jul 21 '14 at 14:02

1 Answers1

1

The developer's "reset" probably did not affect origin unless he/she did a "force push" to origin. In my experience when stuff like this happens it is due to a bad merge or conflict resolution process (i.e. I suspect something in step #6 above is the culprit). Instincts are correct; your best bet is to create a new branch before the bad merge (e.g. "feature-branch2") and discard the original branch (since it is difficult to undo merges or any other changes that have been pushed to origin already) and retry the merge that went bad.

I'm not sure a "revert" is really what you want to do to undo the bad merge. My understanding is that "revert" reverse-applies a patch from a single commit, and attempting to reverse-apply a merge sounds sticky as merges are 2 diffs in 1 commit (I don't have a ton of experience with "revert" so maybe it can be done, I'm not sure). The safest, most reliable way to resolve this issue would be to create a new branch and stop using the one that has the bad merge.

Patrick
  • 5,970
  • 4
  • 24
  • 21
  • Creating a new branch from the last known good commit was the answer. We determined that we didn't need to cherry pick any commits from the last known good commit either and just merged in the new branch without issue. – Ryan Taylor Jul 21 '14 at 16:48