How can I merge many commits, but leave one out?
Asked Answered
A

5

75

Suppose I have this feature branch "foo". Now I want to merge it back into master, but I've added some debugging code that I don't want in master.

The debug code is in it's own commit, so I could use git cherry-pick on each commit and leave out this commit. But that's gonna be quite tiresome.

Is there some "inverse cherry-pick" that does this, or an interactive merge?

Alfred answered 26/10, 2009 at 13:13 Comment(0)
E
54

Use interactive rebase:

git rebase -i SHA-OF-FIRST-COMMIT-IN-BRANCH

That will open something like this in your $EDITOR:

    pick 8ac4783 folders and folders
    pick cf8b1f5 minor refactor
    pick 762b37a Lots of improvement. Folders adn shit.
    pick 3fae6e1 Be ready to tableview
    pick b174dc0 replace folder collection view w/ table view
    pick ef1b65b more finish
    pick ecc407f responder chain and whatnot
    pick 080a847 play/pause video
    pick 6719000 wip: movie fader
    pick c5f2933 presentation window fade transition

    # Rebase e6f77c8..c5f2933 onto e6f77c8
    #
    # Commands:
    #  p, pick = use commit
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #

So what you do is simply to remove the line containing the debug commit, write the file and close your editor, and git will tell you something along the lines of:

Successfully rebased and updated refs/heads/master.

Now you can just merge in that branch to master.

UPDATE: It should be noted that altering history with rebase should only happen on private branches. If this branch has been exposed to the public, use git revert as proposed by other answerer.

Elysia answered 26/10, 2009 at 13:16 Comment(2)
Nice.. and is there a nice way to get the SHA-OF-FIRST-COMMIT-IN-BRANCH?Alfred
@DaveVogt yes! See stackoverflow.com/questions/1527234/…Allophone
A
69

Despite what other SCMs use it to mean, in git, git revert is an inverse cherry-pick.

Austinaustina answered 26/10, 2009 at 13:16 Comment(3)
git revert does record a new commit with the appropriate changes removed.String
@mikem: which is, I think, what an inverse cherry-pick intuitively means. Both revert and cherry-pick also have a -n option which doesn't perform a commit but leaves the changes in the cache/index/staging area so the commands are very similar.Austinaustina
short and sweet - encourages you to try it, thinking 'there's no way it can be this simple! i'll show him!'... and then it is that simple. it seems to work even for code that i started cherry-picking but then just committed normally (oops?), which i guess makes sense, since ultimately git is all about diffs between snapshots, not dependent events. i dunno. i keep learning about features like this and expecting there to be a catch, but they just seem to work, every time!Ligan
E
54

Use interactive rebase:

git rebase -i SHA-OF-FIRST-COMMIT-IN-BRANCH

That will open something like this in your $EDITOR:

    pick 8ac4783 folders and folders
    pick cf8b1f5 minor refactor
    pick 762b37a Lots of improvement. Folders adn shit.
    pick 3fae6e1 Be ready to tableview
    pick b174dc0 replace folder collection view w/ table view
    pick ef1b65b more finish
    pick ecc407f responder chain and whatnot
    pick 080a847 play/pause video
    pick 6719000 wip: movie fader
    pick c5f2933 presentation window fade transition

    # Rebase e6f77c8..c5f2933 onto e6f77c8
    #
    # Commands:
    #  p, pick = use commit
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #

So what you do is simply to remove the line containing the debug commit, write the file and close your editor, and git will tell you something along the lines of:

Successfully rebased and updated refs/heads/master.

Now you can just merge in that branch to master.

UPDATE: It should be noted that altering history with rebase should only happen on private branches. If this branch has been exposed to the public, use git revert as proposed by other answerer.

Elysia answered 26/10, 2009 at 13:16 Comment(2)
Nice.. and is there a nice way to get the SHA-OF-FIRST-COMMIT-IN-BRANCH?Alfred
@DaveVogt yes! See stackoverflow.com/questions/1527234/…Allophone
M
7

Another idea is to add the reverted commit of the one with debug code and to merge it into your master branch. Afterwards we remove that extra commit in the foo branch.

git checkout foo
git revert COMMIT_REF_WITH_DEBUG_CODE

git checkout master
git merge foo

git checkout foo
git reset --hard HEAD~1

Make sure your working tree is clean. First create the reverted commit. Then merge it into master. Afterwards reset the branch pointer of the foo branch to the parent of the reverted commit, so it's back in its original state.

If you dislike using git reset then you could create a temporary branch where you create the reverted commit. At the end you delete the temporary branch.

Moe answered 26/7, 2011 at 18:30 Comment(0)
M
2

Use interactive rebase to remove the commits which you do not want.

On a new branch "foo-merge" created from "foo":

git rebase -i master

Once you are in commit edit mode, remove the lines containing the debug commits, save, and quit from the editor.

After rebasing, simply pull foo-merge into master:

git checkout master
git pull . foo-merge
Moniliform answered 27/10, 2009 at 7:6 Comment(1)
A little difficult to contribute via comments when you're not allowed to. FWIW, I did vote up your answer before deciding that mine would be different enough to be a separate entry, then filing it.Moniliform
I
0

I've had success with:

git rebase -p --onto SHA^ SHA

Where SHA is the commit you want to remove.

via http://sethrobertson.github.io/GitFixUm/fixup.html#remove_deep

Illustrational answered 8/4, 2016 at 9:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.