Reputation: 1834
I was wondering if there was a way to do an interactive rebase from one branch onto the current branch but not onto the head. Kind of like combination of git rebase -i otherbranch
and git rebase -i HEAD~2
.
What I want to do is be presented with an interactive rebase file where i can arrange not only the commits from the remote branch but also a range of commits on the current branch beginning from the head.
The scenario I have is:
Now I need to update B2 with the revised commit from B1. I want the revised the commit to replace the original commit.
Simply rebasing B1 into B2 will result in the original and the revised commit appearing in B2's history (and there will probably be some nasty merge conflicts).
If I could get the B1 unique commits and a range of B2's commits in the interactive rebase prompt then i can tell git to discard the old version of the commit and use the new one from B1 in it's place all in one operation.
So it might look something like: git rebase -i B1 HEAD~2
Currently I do this by branching B1 into temp
then cherry-picking the new commit from B2 onto it, erase B2 then move temp to B2. Which is fine I guess... but if i could do it as part of a rebase it would be nicer (i think).
Upvotes: 2
Views: 7095
Reputation: 34076
That's a case for git rebase -i --onto
as @jthill pointed out. To understand what you do fire up gitk - so if you have:
A - B - c - D B2
\
C' B1
(where C' is your amended commit) you just issue git rebase -i --onto C' C B1
where the C, C' are the SHAs of the commits (or temporary branch names you checkout on your commits) and they are excluded from the rebase. Note the -i
is not strictly needed although if you run into conflicts it is much better to be in an interactive rebase while solving them (allows you to edit the commit message, while non interactive will just accept the resolution and march on, although much faster than the interactive one).
Result:
A - B - c - D reflog
\
C' B1
\
D' B2
Same, if you have:
A - B - c - D - E B2
\
C' - D' B1
So you amended commit C and so commit D changed too (although its contents are the same) - issue git rebase -i --onto D' D B1
.
Rebase is the most important git command IMO, gets code writing to the level it should be, you can apply your changes wherever you want in whatever order.
Always post diagrams like the above when asking a question.
Upvotes: 4
Reputation: 5617
Rebasing is indeed cherry-pick
-ing a few commits in turn. The file edited in git rebase -i
specifies what commits to pick, and in which order.
We can even replace one commit with another in B1, without a temp branch, like:
# this is the file get edited in `rebase -i`
# pick commit-in-B2 # the default when rebasing B2, comment out it
pick commit-in-B1 # instead pick the amended commit in B1
pick rest-of-B2
Upvotes: 1