Reputation: 737
I am working on two features simultaneously, "feature1" being the basis for "feature2". I create two branches for them; when I work on feature1, I commit into "feature1" branch; when I work on feature2, I commit into "feature2" branch, and regularly rebase "feature2" on top of "feature1":
git checkout feature2
git rebase feature1
... work ...
git commit ...
So, at some moment, I have this structure:
feature1: A -> B -> C
feature2: A -> B -> C -> P -> Q -> R
At this point, I am done with feature1; I want to squash A, B and C into a single commit D , and rebase feature2 upon this new state of feature1:
feature1: D
feature2: D -> P' -> Q' -> R'
Simple-mindedy, I run interactive rebase on feature1, successfully squash A, B and C into D, and try to rebase feature2
git checkout feature2
git rebase feature1
Now, git pulls D into the feature2 branch and tries to reapply A, B, C, P, Q and R on top of it. Of course, the updates in A, B and C are already applied by D, so they result in merge conflicts.
I figured by trial and error that when a merge conflict is reported while A, B and C are being re-applied, I just need to run
git rebase --skip
and I end up with exactly the result I need. But, first, this is not obvious if you didn't already know, and second, makes it easy to overlook and skip a potential genuine merge conflict. The latter should be unlikely, but if it happens, it's rather bad because you lose the corresponding update for good.
So, my question is: is there a better way to rebase your branch upon a branch in which some commits where recently squashed into one?
Upvotes: 3
Views: 134
Reputation: 3202
I like using the --onto option to rebase and the @n reflog commit naming to solve my problem here, which often arises when interacting with non-git VCSes, or pretty much any time you are several local branches that are interdependent but not published.
After your first rebase: (you are squashing commits, but it can be pretty much any rebase)
git rebase -i master feature1
Follow it up with a second rebase:
git rebase --onto feature1 feature1@1 feature2
OR ("long hand")
git checkout feature2
git rebase --onto feature1 feature1@1
Which says, take the commits in feature2 that aren't in the previous version of feature1 and replay them on top of the current version of feature1.
Upvotes: 2
Reputation: 155670
Since rebasing messes with git's idea of merge history, git cannot tell automatically what you're trying to do. Instead of dealing with the conflicts and issuing a rebase --skip
for each unwanted commit, use git rebase -i feature1
as your final rebase command, and simply remove the unsquashed commits from the list.
Upvotes: 2