More Rebase Use Cases + More Practice
More Rebase Use Cases + More Practice κ΄λ ¨
By now I hope you feel comfortable with the syntax of rebase. The best way to actually understand it is to consider various cases and figure out how to solve them yourself.
With the upcoming use cases, I strongly suggest you stop reading after I've introduced each use case, and then try to solve it on your own.
How to Exclude Commits
Say you have this history on another repo:
Before playing around with it, store a tag to "Commit F" so you can get back to it later:
git tag original_commit_f
Now, you actually don't want the changes in "Commit C" and "Commit D" to be included. You could use an interactive rebase like before and remove their changes. Or, could can use again git rebase -βonto
. How would you use --onto
in order to "remove" these two commits?
You can rebase HEAD
on top of "Commit B", where the old parent was actually "Commit D", and now it should be "Commit B". Consider the history again:
Rebasing so that "Commit B" is the base of "Commit E", means "moving" both "Commit E" and "Commit F", and giving them another base β "Commit B". Can you come up with the command yourself?
git rebase --onto <SHA_OF_COMMIT_B> <SHA_OF_COMMIT_D> HEAD
Notice that using the syntax above would not move main
to point to the new commit, so the result is a "detached" HEAD
. If you use gg
or another tool that displays the history reachable from branches it might confuse you:
But if you simply use git log
(or my alias git lol
), you will see the desired history:
I don't know about you, but these kinds of things make me really happy. ππ
By the way, you could omit HEAD
from the previous command as this is the default value for the third parameter. So just using:
git rebase --onto <SHA_OF_COMMIT_B> <SHA_OF_COMMIT_D>
Would have the same effect. The last parameter actually tells Git where the end of the current sequence of commits to rebase is. So the syntax of git rebase --onto
with three arguments is:
git rebase --onto <new_parent> <old_parent> <until>
How to move commits across branches
So let's say we get to the same history as before:
git checkout original_commit_f
And now I want only "Commit E", to be on a branch based on "Commit B". That is, I want to have a new branch, branching from "Commit B", with only "Commit E".
So, what does this mean in terms of rebase? Consider the image above. What commit (or commits) should I rebase, and which commit would be the new base?
I know I can count on you here π
What I want is to take "Commit E", and this commit only, and change its base to be "Commit B". In other words, to replay the changes introduced in "Commit E" onto "Commit B".
Can you apply that logic to the syntax of git rebase
?
Here it is (this time I'm writing <COMMIT_B>
instead of <SHA_OF_COMMIT_B>
, for brevity):
git rebase β-onto <COMMIT_B> <COMMIT_D> <COMMIT_E>
Now the history looks like so:
Awesome!