问题
My team has been working in a prototype branch off of master. I now want to take that work, slice it up into different "feature branches", and merge them individually into master. I see a couple ways to do this, neither of which I really like:
1 - Create a new branch, Feature_1, off of master. Manually copy the code from the Prototype to Feature_1. This means I have to keep track of what I've copied when I go to make Feature_N and I lose history.
2 - Create a new branch, Feature_1, off of Prototype. Somehow revert the code that is not part of the first feature in Feature_1. This avoids lying to git (and keeps history), but it feels like Feature_N will be a mess to merge because I will have told master that the changes were reverted when I pushed Feature_1.
Am I missing a nicer way to do this?
回答1:
@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 --amend
to create commit C1
in C12
s place, then git add -A; git commit`` 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.
回答2:
Create two branches feature_1
and feature_2
off of master
and cherry pick the commits from prototype
in the regarding feature branch:
git checkout -b feature_1 master
git cherry-pick <commit>
git cherry-pick <commit>
…
git checkout -b feature_2 master
git cherry feature_1 prototype | grep "^+" | cut -c3- | xargs git cherry-pick
The last line cherry picks all commits from prototype
which are not in feature_1
into the current branch, i.e. feature_2
.
When you run into conflicts, use git status
for hints how to continue.
See git-cherry-pick for further documentation.
来源:https://stackoverflow.com/questions/26657309/separate-git-branch-into-multiple-branches-to-merge-to-master