Git - Revert changes made by merge without destroying recent additions to the same files

Viewed 36

Introduction

I work on a dev team where everyone works on different branches adding different features.

Today it was discovered that a feature from a branch merged into our develop branch a week ago is no longer in develop.

I would like to find the best way of reintroducing this lost feature into develop.

Structure

There are two branches: featureA and featureB. Both of these are branches off of develop.

Structure of branches:
 - Master
   - Develop
     - featureA
     - featureB
     - ...

featureA - adds <small>Creator ... </small> to a bunch of files

featureB - does something completely unrelated

What Happened

featureA is completed before featureB and is merged into develop

featureB is now complete and merges its changes into develop

A week goes by and during that time, new changes are made to the files that featureA modified.

Finally, I notice that the changes made by featureA are no longer in develop.

I search through the commit history and find that the merging of featureB into develop removed the changes to the project made by featureA.

The Goal

I want the changes made by featureA to be included in the most recent version of develop again. However, I don't want to restore the file to the state it was in previously as changes to some of the same files have been made since featureA was merged into develop.

What I've tried

  • Merging featureA into develop: $ git checkout develop && git merge featureA

But git just tells me it's "up to date" since featureA hasn't diverged from develop since it was originally merged into develop.

My Solution

  1. checkout develop right after having featureA merged into it
  2. get a copy of the files modified by that merge
  3. checkout the latest develop
  4. manually go through and readd the changes that were removed

The Question

I imagine that there is a much better way to do this that doesn't involve me manually readding the changes.

Is there a better way I could have merged the changes made in the featureA branch with the current version of those files in develop?

Things I've Found Along the Way

Instead of searching through bitbucket's interface to track down the last commit that included the changes made by featureA, you can run $ git log -p -S '<small>Creator'.

Other info

The people that merge features into develop are different than the people that make the changes. As such the developer is expected to merge develop into the feature branch before marking the branch as ready to be merged/tested in our task tracking software.

This means that, most likely, featureB destroyed featureA's changes when doing something like: $ git fetch && git checkout featureB && git merge develop.

This could have happened by poor manual handling of merge conflicts or beacuase they forgot to fetch the lastest version of develop before merging develop into featureB.

Potential Better Solution

$ git fetch && git checkout -b featureA-readd-changes <featureA>
$ git merge develop ...
$ git push -u origin featureA-readd-changes

And then submit a request for merging into develop via our Task software.

Lastly

I would like the answer to not only give the solution, but to explain the rational behind the solution. My goal is to learn how git works a bit better so I can more easily handle a situation like this in the future.

Feel free to suggest changes to our current process if you think they could help to prevent stuff like this from happening in the future.

Thank you for your time.

1 Answers

Well.... I stopped reading when you explained what removed the changes introduced by branchA: merging of branchB. Easy way around it: cherry-pick all revisions that make up branchA so that to git they are brand new revisions that are not merged into develop and then git won't complain to merge when you try again. Find out the revision that branchA was started from (say, the revision in develop that is parent to the first "branchA-proper" revision).

git checkout that-revision
git cherry-pick HEAD..branchA # reapply all changes introduced by branch A.. assuming it's a straight line
git branch -f branchA # set branchA over here
git checkout develop # or the remote one, whatever suits
git merge branchA # this should work this time

Now, you should find whoever merged branchB and ask them why they removed the changes from branchA. Conflicts? They were not solved properly if that was the case. Ask them to read this excellent guide (that I wrote, of course ;-)) on how to deal with conflicts: www.ezconflict.com (no monetizing, no tracking, no cookies, etc etc).

Related