gen_Eric
gen_Eric

Reputation: 227190

Move past commits to their own branch

I have a git repo that looks kinda like this:

   A - B - C - D - E - F
   ^                   ^
   |                   |
Staging              master

I want to move the Staging branch pointer to E, but I don't want commits B and D to be in the branch. I want to put B and D into their own branch.

            Staging
               |
               V
A ---- C ----- E - F <- master
  \               /
   B ----- D -----
           ^
           |
         new branch

I have no idea how to move the commits out of the master branch chain and move them to their own branch, and then re-merge them into master again.

Is this even possible?

Upvotes: 2

Views: 103

Answers (3)

Micha Wiedenmann
Micha Wiedenmann

Reputation: 20823

I would use interactive rebasing (git rebase -i) for these kind of transformations.

  1. Create new-branch

    git checkout -b new-branch D
    git rebase -i A^
    
  2. Move staging:

    git checkout staging
    git reset --hard E
    git rebase -i A^
    
  3. Update master:

    git checkout master
    git reset --hard staging
    git merge new-branch
    

Interactive rebasing

You start the interactive rebasing with git rebase -i A^ (which takes everything from HEAD to A). Your editor will open and present the commit ordered from oldest to newest (beware, this is dhe opposite order of git log and confusing sometimes). You can rearrange commits by rearranging the corresponding lines. You can also delete lines, which deletes the associated commits. (In your case deleting should be sufficient.)

Note: Rebasing changes the history which you should not do, if you have already published your history to your colleagues.

Upvotes: 4

sleske
sleske

Reputation: 83577

Create two new branches based on A:

git branch staging-new A
git branch new-branch A

Then use cherry-picking to pick the commits you want for each branch:

git checkout staging-new
git cherry-pick C E

and similar for new-branch.

Then you can delete the old branch Staging. master remains untouched.

Notes:

  • This will be more complicated if any of the intermediate commits are merge commits (because cherry-picking a merge commmit is more complex).
  • Since you are recreating branch Staging, any branches based on it (by you or others) will have to be changed (typically rebased).
  • You will not get exactly what you describe, because cherry-picking creates new commits. So staging-new and new-branch will not be ancestors of master (as in your picture). To obtain that, you will have to modify master's history using rebase. Of course this is usually only advisable if you have not yet shared master.

Upvotes: 1

kunalbhat
kunalbhat

Reputation: 1719

You want to use git cherry-pick to selectively move commits from one branch to another.

This article may help you: http://technosophos.com/content/git-cherry-picking-move-small-code-patches-across-branches

And from the git manual: http://git-scm.com/docs/git-cherry-pick

Upvotes: 0

Related Questions