@Michael's answer is the good stuff if your commits are single-feature commits that don't share dependencies with commits for any other feature. If you've mixed work on the two features in any commit, though, you'll want interactive rebase. It allows you to arbitrarily redistribute change hunks and commit boundaries, and it does keep track of which hunks haven't yet been committed to the current branch.
If the feature changes are just sometimes combined into commits and there are no cross-feature dependencies, to make life easy my first try would be to git rebase -i master prototype
, split the commits with mixed hunks into two commits, one for each, and then finish off with the cherry-picks as in Michael's answer. Given
A1-B2-C12-D2-E1-F12 prototype
where the digits signify which feature(s) the commit contains code for, for `git rebase -i master prototype you'd edit commits C12 and F12,
pick A1
pick B2
edit C12
pick D2
pick E1
edit F12
(using each commit's hash instead of its illustrative tag here).
Rebase will stop after committing C12
, and you can git reset HEAD~
then git add --patch
to apply all the feature-1 hunks, git commit
to create commit C1
where C12
was, then git commit -a
to apply all the remaining hunks and create commit C2
following it. You'll end up with
A1-B1-C1-C2-D2-E1-F1-F2
and you can then git checkout -b feature1 master; git cherry-pick A1 B1 C1 E1 F1
and similarly for feature2.
In more complicated situations this method still works with only very minor changes. Interactive rebase is much better than the above might lead you to believe, but by far the best way to find out about that is to sit down with the manpage while you get in there and scramble some hunks for fun. Do that, and it may soon get to the point where doing this as a prepublication ritual is often enough more convenient than trying to keep your actual workflow publishable at every little step.