Move commits from one branch to another
Have you ever made a few commits on a branch, only to later realise that you should have been working on a topic branch (i.e. a branch specific to the task you're working on)? So long as you haven't yet shared any of these commits with anybody else, you can easily move them on to a new branch, and then remove them from your current branch.
Making the topic branch
When I decide that I'd be better off working in a topic branch, the first thing I do is commit any outstanding work. It doesn't matter if the tests aren't currently passing; we'll just undo the commit after we've switched branches.
So let's do a "WIP" (Work In Progress) commit and make the branch:
$ git add .
$ git commit -m "WIP"
$ git checkout -b some-feature
You can also make a new branch with the
git branch command, but I prefer
checkout -b as it also switches you to the new branch immediately (whereas
git branch will just make the new branch, leaving you on your current
Your "WIP" commit will now be stored safely at the head of the branch that you
were on and also on the new
Tip: If you're not familiar with branching, you can check that your most recent work is on the new branch before you continue:
$ git log -p some-feature
Removing commits from master
All you need to do now is to switch back to the
master branch and remove any
work that you'd rather develop on the topic branch. If the work to remove is
just your last commit you can use
git reset to roll the branch back:
$ git checkout master
$ git reset --hard HEAD^
--hard option tells git to set the head of the current branch to the
commit that you specify, while modifying the files on disk to match the
contents of the repository.
HEAD^ syntax refers to the previous commit to the head of the current
branch (i.e. the last commit on the branch), so this will roll us back one
commit. You can add extra
^ characters, so
HEAD^^^ will throw away three
If you want to go back more than a couple of commits you can use the tilde syntax to save some typing:
HEAD~1is equivalent to
HEAD~2is equivalent to
HEAD~8is equivalent to
Note: Be careful with the
--hard option to
git reset. It isn't
something to be afraid of, but you do need to make sure that you've committed
all your local changes to another branch before you run it.
Back to work...
Now we can switch back to the topic branch and carry on from where we left off.
$ git checkout some-feature
If you had some work in progress that you saved with a "WIP" commit message you
can back that commit out now, without losing the changes (they'll still be on
your filesystem). We'll use
git reset again, but without the
$ git reset HEAD^
All that'll do is to remove the last commit from your repository, without actually changing your files.
And there you are; all the commits that you deleted from
master are now on your topic branch.
An insurance policy
Should you make a mistake while you're fiddling around with branches and
reset --hard you could find yourself in a position where you've thrown a bunch
of commits away by mistake. It's unlikely but -- let's face it -- could happen.
Don't worry, Git has got your back, and you can recover lost commits
without too much trouble.