Today I came to work and found that I have to move 18 commits from my development git branch to the old release. I’ve worked on one feature for several weeks, and kept my branch up to date with master, so the history looked like this:
Z -- Y -- X -- W -- V -- U -- T -- S feature
/ / /
-- A -- B -- C -- D -- E ----- F ---- G -- H master
\
R -- Q release
So, my goal is to create a feature'
branch on top of the release
and copy the commits Z
, Y
, W
, V
, T
and S
there:
Z -- Y -- X -- W -- V -- U -- T -- S feature
/ / /
-- A -- B -- C -- D -- E ----- F ---- G -- H master
\
R -- Q release
\
Z' -- Y' -- W' -- V' -- T' -- S' feature'
I was not able to rebase my working branch. So I had to cherry-pick
the commits one by one from my working branch to the new branch, based on release version. I’m not very meticulous man. To be honest I’m quite careless, so I really didn’t want to do it by hand one by one. Fortunately, git cherry-pick
allows you to pass several commits, or to pass the range. But the problem is to get only related commits, and skip commits from the master and merges. The cherry-pick
command itself doesn’t have this function, but it can take commits from another command using --stdin
option.
The powerful command to get different commit lists is git rev-list
. You can use --grep
option to filter the commits (I used bug tracker id, but it can be used with any other criteria). Since we need to apply commits in chronological order, --reverse
option shall be specified. And the last, but lot least required option --no-merge
is required to avoid merge-commits in the list. Now the list of commits can be passed to git cherry-pick
command:
git rev-list --reverse C..S --grep='featureX' --no-merge | git cherry-pick --stdin
If any conflict occurs, you have to solve it (using git mergetool
or manually with git add
) and then run git cherry-pick --continue
until all commits are copied.
Finally, if you are going to merge the release
branch into your master, it might be a good idea to merge original feature
branch into master
first. It will simplify the merge with release
since all conflicts between master
and feature
branches will be already resolved.
Z -- Y -- X -- W -- V -- U -- T -- S feature
/ / / \
-- A -- B -- C -- D -- E ----- F ---- G -- H ------ K -- L master
\ /
R -- Q -- Z' -- Y' -- W' -- V' -- T' ------------ S' feature'