Sleavely
Sleavely

Reputation: 1693

How do I extract and remove a merged branch in Git?

I have a 7 branches that affect the same files, all have been merged into the master branch through a secondary branch. One of the branches was not meant to be merged because it was not stable - can I undo the changes made by that single branch?

Assuming my repository looks like the following:

master  A - B - - - - E - - G - - - J - K
b1          |          `- F - - - I´  
b2          |                    / 
b3          |` - C - - - - - H -´
b4           ` - - D - - - -´

Now D is in the master. I want to remove it (but keep it in the b4 branch).

Upvotes: 4

Views: 1924

Answers (4)

Sebastien
Sebastien

Reputation: 1476

Assuming no push were made:

        git checkout master -b old-ref

Just in case we need it... Then:

    git checkout <old correct sha1> -b TEMP
    git branch -D master
    git checkout master

Should get origin/master

    git rebase -i TEMP

now you can do the un done merge properly (or not). If push were made, and you have no control over it (meaning rebuilding it "from scratch") you will have to revert the bad commit.

Upvotes: 0

Isantipov
Isantipov

Reputation: 20969

In the case that everything is just in your local repo (not being pushed anywhere), I'd just reset branches to the state before merges and do the merges again.

If it's pushed (i.e. you don't want to reset): revert your merge commit (H) on b3 (this will create a new commit - say, Q) and merge b3 into master again (so you merge this commit which revert changes, brought by b4). In case you want to merge b4 into master later, you need to: merge b3 into b4 (this will bring in Q into b4), revert Q on b4 (so you revert reverting) - now b4 can be worked on again and merged into master at some point later

If it's just a single D commit, that you don't want to have in master, you can do the following:

  • checkout b4
  • revert D (this will create a new commit - say, U)
  • merge b4 into master (or cherry-pick just U commit which removes unwanted changes).

Later on, you can revert U commit on b4 (i.e. bring back changes, made in D) and merge b4 into master again .

Upvotes: 0

MattJenko
MattJenko

Reputation: 1218

Read this.

Essentially, you want to undo the merge with something like

git revert -m 1 H

to create commit L, then at a later date when that commit becomes valid again

git checkout master &&
    git revert L &&
    git checkout b3 &&
    git merge b4

and merge it on up again.

In my example I have done the revert on master, but I would suggest doing the initial git revert H at the lowest level branch that the change doesn't make sense - if it's simply to avoid it becoming part of master then do it at that level, but if you don't want it affecting b3 (or any of the other branches) either then do this revert - and subsequent revert-revert - on b3.

Upvotes: 1

Adam Dymitruk
Adam Dymitruk

Reputation: 129762

you should be able to just revert H.

git revert H

However, you won't be able to fix it and remerge it later when fixed. D will only be redone by doing a revert of that first revert.

Depending on your workflow, it may be easier to do the merges again without including b4.

I address this sort of stuff in my post here (or google "branch per feature"): http://dymitruk.com/blog/2012/02/05/branch-per-feature/

Getting rid of bad branches is at the heart of this workflow. I hope it helps you out.

Upvotes: 3

Related Questions