‹ jan0sch.de

Move git commits between branches... properly!

2020-07-10

Sometime you need or want to move a commit or several of them between different git branches. One possible scenario would involve a created feature branch which runs a bit longer and multiple important fixes have been made on it. Some might argue that this shouldn’t happen but guess what: this happens all the time. ;-)

We assume that we have the following branches in our repository:

  1. main - This is the main development branch, automatically built and deployed.
  2. my-branch - This is your feature branch containing several fixes you want to move.

So what is to be done?

Well, first you should analyse the history (git log) and search for the commits you want. Remember to note their commit hashes!

Now we are ready to cut a fresh branch from main like this:

% git checkout main
% git branch fixes
% git checkout fixes

So basically we moved to the main branch and created a new fresh branch named fixes from it which we checked out afterwards. So let’s get those commits:

% git cherry-pick ID1
% git cherry-pick ID2
% git cherry-pick ID3

We assumed three commit hash ids to be picked in the example above. It is possible that you might have to solve some conflicts if the commits where “somewhat apart” on the branch and had lots of changes in between them. But in many cases things work just fine.

So now you can push your branch fixes and create a pull request with the changes to the main branch.

Read on to avoid tons of trouble!

Please don’t skip the rest and read on: You have to clean up the old branch!

Cherry-picking changes the commit hash so git won’t know that the commits are already on the main branch if you merge my-branch later on. To avoid really nasty stuff you should clean the branch. Of course there are several ways to do it. ;-)

  1. Use interactive rebase (git rebase -i) and get rid of the moved commits by using the drop command.
  2. Create a new branch from main and cherry-pick the wanted commits to that one and drop your outdated my-branch afterwards.

Personally I prefer the first approach but there might be reasons for the second approach. Possibly there are also other options.