23

I'd like to move my last few commits from master into a branch of their own.

The tree on my PC looks like that:

   W (some branch)
  /       
X1--X2--X3--X4--Y--Z1--Z2 (master)

I'd like it to look like:

   W (some branch)
  /       
X1--X2--X3--X4 (master)
             \
              Y--Z1--Z2 (my new branch)

However, the tree at GitHub looks like:

   W (some branch)
  /       
X1--X2--X3--X4--Y (master)

That's what I saw as a solution for moving the last commits to another branch:

git checkout master
git branch my_new_branch
git reset <commit_id>

My question is: would I be able to successfully push to GitHub after moving the commits into a new branch and if so would it require to do something else than these three commands?

nulltoken
  • 64,429
  • 20
  • 138
  • 130
Albus Dumbledore
  • 12,368
  • 23
  • 64
  • 105
  • 2
    You don't want Y in master or you just want your branch to start from X4? I mean, is Y being in master a mistake? – CharlesB May 17 '11 at 19:14

3 Answers3

20

(I assume <commit_id> is the object name of X4...)

Those commands will indeed end you up with what you want locally. (You might want to use git reset --hard to keep the working tree and index the same as the commit you're resetting to, but as usual, be very careful that git status is clean before you use that command.)

If you afterwards try to push master to GitHub, it will tell you that everything's already up to date, because the master on GitHub is one commit ahead. You can force the push, so that master is reset on GitHub, but that's rewriting public history, so you should only do that if (a) you're the only who'll have fetched master from GitHub or (b) you can let your collaborators know what do so that they don't accidentally merge Y back in. If that's OK, you can do:

 git push --force origin master

... and then master on GitHub will be the same as your local version.

Mark Longair
  • 446,582
  • 72
  • 411
  • 327
  • Likewise +1 for your more succinct answer - 7 seconds is harsh for a 16 minute old question! – Mark Longair May 17 '11 at 19:17
  • Thanks Mark. I'm the only one committing to the project for now. One guy has actually forked the project but he is working on his own. So, in that case, there is no theoretical danger for me, ruining my project history, and for him, having problems with his fork? Sorry for my rather *not-very-bright* questions. :-) – Albus Dumbledore May 17 '11 at 19:34
  • 2
    It's not *ruining* it, just rewriting it :) That should be OK, but if you ever want to merge his work back into yours, you'll want to be careful - probably using interactive rebase to rewrite the other person's branch so that it skips your `Y`. Or if he hasn't done anything yet, it might be easiest to say "you might want to delete your fork and re-fork my repository"... – Mark Longair May 17 '11 at 19:42
  • Great. Thank you very much. Mark, You've been most helpful! – Albus Dumbledore May 17 '11 at 19:44
  • 2
    @Albus Dumbledore: no problem - it's quite an honour to be able to help the Order of the Phoenix with their version control strategy ;) – Mark Longair May 17 '11 at 19:50
  • That made me laugh my head off. :-D – Albus Dumbledore May 17 '11 at 19:55
  • I swear I come back to this damn question once every two weeks. – merwok Oct 09 '15 at 17:08
3

It should work but you will need:

  • to push -f origin master (force the push, which will spell trouble if anyone else has already clone your repo)
  • to push then your new branch (which will then find the X4 sha1 on top of which said new branch will be set).
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
0

Nobody has mentioned that you can simply cherry pick the commit into another branch. This way your commit message will still be there for you.

Just copy the revision id of your commit you want to move. git log --oneline

Than create a new branch on top of the former commit and change to it: git checkout -b "$newBranchName" HEAD~$n (HEAD~$n stands for the n-th commit) or git checkout -b "$newBranchName" $formerRevsion

Now you just have to cherry pick the wanted commit: git cherry-pick $revision

The old commit will be still in the other branch but you can fix that with rebase. Move back to your old branch and use rebase: git rebase -i HEAD~$n

Just delete the commit line of the cherry picked commit and your branch will be rebased with out it. You have to use git push -f because the revisions of all rebased commits have changed.

Devpool
  • 701
  • 7
  • 6