tags:

views:

203

answers:

2

I have a series of commits (20+) that pertain to a particular feature that I am trying to remove from our master branch and into a separate branch.

I have a tag (rel_2009_07_18) on the commit that represents our latest stable release, so when on master, git log rel_2009_07_18..HEAD gets me the set of commits that I want to move to a separate branch. There are also some commits in this set that should remain, but I could just cherry-pick those as they are few.

I've looked at git filter-branch, but the commit option mentions leaving the changes in but removing the commit -- definitely don't want that. I also looked at git rebase, but that also mentions reapplying the commits to the upstream branch.

Is there a good option for moving these commits to a separate branch?

I'm not sure if this is a viable option and the repercussions in a distributed, albeit small (3 developers), environment. But could I perform the following little shift...

  1. Locally rename the master branch to master_plus_feature (or similar...)
  2. Checkout from the `rel_2009_07_18` tag
  3. Create a new branch master from this point
  4. Delete remote branches and re-push from local

Thoughts and suggestions? Thanks!

+1  A: 

For me the easiest option is to use git-cherry-pick.

Basically you need to switch to the branch you want the commits on, then using the log of the original branch (git log master) you find the SHA-1 of each commit you want and cherry-pick it onto the current branch.

Once this is done, you can then move back to master and reverse all those unwanted commits by using git-reset and hey presto, you now have a branch with your new commits, and a clean master branch.

jkp
+6  A: 

You write that you want to remove commits from 'master' branch. This might cause problems if 'master' branch was published (well, commits after rel_2009_07_18 are published), and somebody based their work on your 'master'. But perhaps it is not a problem in your case.

Both solutions below assume that you don't have uncomitted changes

If you can rewind 'master' branch:

$ git checkout master
$ git branch separate_branch
$ git reset --hard rel_2009_07_18

Now 'master' is at rel_2009_07_18 tag, and 'separate_branch" is at where 'master' was. The final result is exactly the same as in set of steps you proposed (rename 'master' to 'separate_branch', recreate 'master' at rel_2009_07_18), the only difference is in reflogs.

If you can't rewind 'master' branch

$ git checkout master
$ git branch separate_branch
$ git checkout rel_2009_07_18 -- .
$ git clean -df
$ git commit -m 'Reverted to state at rel_2009_07_18'

Note that this solution is not tested! YMMV.

Jakub Narębski
I can rewind master, so I'll opt for that solution. I can notify others of the change. From there, I can cherry-pick the good commits back into master, right? That shouldn't cause any real issues down the road with merging separate_branch back into master, right?
Eric M.
@Eric M. yes, you would be able to cherry-pick into master, and there shouldn't be any issues with merging 'separate\_branch' into 'master' later.
Jakub Narębski