Using Git rebase on the command line
Here's a short tutorial on usinggit rebase
on the command line.
Using Git rebase
In this example, we will cover all of thegit rebase
commands available, except forexec
.
We'll start our rebase by enteringgit rebase --interactive HEAD~7
on the terminal. Our favorite text editor will display the following lines:
pick 1fc6c95 Patch Apick 6b2481b Patch Bpick dd1475d something I want to splitpick c619268 A fix for Patch Bpick fa39187 something to add to patch Apick 4ca2acc i cant' typ goodspick 7b36971 something to move before patch B
In this example, we're going to:
- Squash the fifth commit (
fa39187
) into the"Patch A"
commit (1fc6c95
), usingsquash
. - Move the last commit (
7b36971
) up before the"Patch B"
commit (6b2481b
), and keep it aspick
. - Merge the
"A fix for Patch B"
commit (c619268
) into the"Patch B"
commit (6b2481b
), and disregard the commit message usingfixup
. - Split the third commit (
dd1475d
) into two smaller commits, usingedit
. - Fix the commit message of the misspelled commit (
4ca2acc
), usingreword
.
Phew! This sounds like a lot of work, but by taking it one step at a time, we can easily make those changes.
To start, we'll need to modify the commands in the file to look like this:
pick 1fc6c95 Patch Asquash fa39187 something to add to patch Apick 7b36971 something to move before patch Bpick 6b2481b Patch Bfixup c619268 A fix for Patch Bedit dd1475d something I want to splitreword 4ca2acc i cant' typ goods
We've changed each line's command frompick
to the command we're interested in.
Now, save and close the editor; this will start the interactive rebase.
Git skips the first rebase command,pick 1fc6c95
, since it doesn't need to do anything. It goes to the next command,squash fa39187
. Since this operation requires your input, Git opens your text editor once again. The file it opens up looks something like this:
# This is a combination of two commits.# The first commit's message is:Patch A# This is the 2nd commit message:something to add to patch A# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.# Not currently on any branch.# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: a#
This file is Git's way of saying, "Hey, here's what I'm about to do with thissquash
." It lists the first commit's message ("Patch A"
), and the second commit's message ("something to add to patch A"
). If you're happy with these commit messages, you can save the file, and close the editor. Otherwise, you have the option of changing the commit message by simply changing the text.
When the editor is closed, the rebase continues:
pick 1fc6c95 Patch Asquash fa39187 something to add to patch Apick 7b36971 something to move before patch Bpick 6b2481b Patch Bfixup c619268 A fix for Patch Bedit dd1475d something I want to splitreword 4ca2acc i cant' typ goods
Git processes the twopick
commands (forpick 7b36971
andpick 6b2481b
). Italso processes thefixup
command (fixup c619268
), since it doesn't require any interaction.fixup
merges the changes fromc619268
into the commit before it,6b2481b
. Both changes will have the same commit message:"Patch B"
.
Git gets to theedit dd1475d
operation, stops, and prints the following message to the terminal:
You can amend the commit now, with git commit --amendOnce you are satisfied with your changes, run git rebase --continue
At this point, you can edit any of the files in your project to make any additional changes. For each change you make, you'll need to perform a new commit, and you can do that by entering thegit commit --amend
command. When you're finished making all your changes, you can rungit rebase --continue
.
Git then gets to thereword 4ca2acc
command. It opens up your text editor one more time, and presents the following information:
i cant' typ goods# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.# Not currently on any branch.# Changes to be committed:# (use "git reset HEAD^1 <file>..." to unstage)## modified: a#
As before, Git is showing the commit message for you to edit. You can change the text ("i cant' typ goods"
), save the file, and close the editor. Git will finish the rebase and return you to the terminal.
Pushing rebased code to GitHub
Since you've altered Git history, the usualgit push origin
will not work. You'll need to modify the command by "force-pushing" your latest changes:
#Don't override changes$git push origin main --force-with-lease#Override changes$git push origin main --force
Warning
Force pushing has serious implications because it changes the historical sequence of commits for the branch. Use it with caution, especially if your repository is being accessed by multiple people.