Merging the Streams
When you have a feature branch dev
ahead of a main branch master
and you only want some of the changes from dev
:
git co dev
git co -b dev-tmp
git rebase -i master
Delete the commits that you want to keep stashed off the master
, don’t worry, deleting them from an interactive merge will, indeed, remove them completely from the source branch, but as the source branch is dev-tmp
, that’s okay; they will still be stashed on dev
Start the Rebase
At this point you may run into a rebase conflict, that’s a lot like a merge conflict; git has found a patch that it doesn’t know how to apply because it can’t find the files/lines it wants to patch against. they have changed on the master.
When you are done resolving your rebase and the rebase is complete:
git co master
git merge dev-tmp
This merges dev-tmp
into master
.
As we just rebased dev-tmp
onto master
, dev-tmp
contains all of master
’s commits and then some, so merging dev-tmp
into master results in a clean, fast-forward merge.
Voila! The changesets that you cherry-picked from dev
are now a part of master
’s commit history.
NOTE: one caution here, while the hand-picked (and possibly reorganized) subset of dev
’s changes have been effectively moved to master
, they are represented in master
’s history as different commits than those in dev
’s history. this will make more sense when you see the next step.
git co dev
git rebase master
this piece of magic will rewind dev
’s changes back to when it diverged from master
’s history, move forward to master
’s HEAD, and then attempt to apply dev
’s patches successively against master
’s history.
As some of those changesets have already been copied over to master
’s history (via the dev-tmp
rebase), those changesets are skipped while the rest are applied on top of master
’s HEAD
.
The result is that dev
now branches from master
’s HEAD
containing only the changes from those commits that were left out of the dev-tmp
rebase list.