That seems a job for git rebase --onto
:
git rebase --onto master new_feature specific_feature
That will take only the commits after new_feature
up to specific_feature
HEAD, and replay them onto master
.
Note that you will then have to force push specific_feature to upstream (if you already pushed it before): git push --force specific_feature
.
That can be an issue if others have already pulled that branch and are working on it.
davidriod correctly points out that:
I don't think this will work as the OP as merged several times the upstream/new_feature
branch in the specific_feature branch
If new_feature
was never updated (fetch only, never pull), then it might still work.
If new_feature
was updated (pull) and merged into specific_feature
, then the rebase --onto
would only play the last few commits since the last merge: here, only z'
commits would be replayed, not the first z
.
x--x--x
\
y--y--Y--y--y (new_feature)
\ \
z--M--z'--z' (specific_feature)
Instead of cherry-picking, I would:
- make
specific_feature
out of master
(and mark the specific_feature
branch as tmp
)
- merge
Y
(the last new_feature
commit which was merged in specifc_feature
) into the new specific_feature
branch
That is:
git checkout -b tmp specific_feature
git checkout -B specific_feature master
git merge $(git merge-base tmp new_feature) # that merges Y
----------M (specific_feature)
/ /
x--x--x /
\ /
y--y--Y--y--y (new_feature)
\ \
z--M--z'--z' (tmp)
Then the rebase --onto
can use that same common ancestor Y
as the correct base:
git rebase --onto specific_feature $(git merge-base tmp new_feature) tmp
git branch -D tmp
----------M--z''--z'' (specific_feature)
/ /
x--x--x /
\ /
y--y--Y--y--y (new_feature)