What is git rebase -i HEAD~n ?

1 of 3

Rebasing is useful for making sure that the branch you are working on diverges from the latest version of the parent branch.

Let’s say you are working on a branch and continue working on it, adding new commits. During this time, the branch ends up with new commits and updates from other contributors who merged their code with it.

Now, you want the branch you have been working on to link to the last few commits by your collaborators in your current branch. git rebase -i HEAD~n allows you to manage this concern.

For instance, if you want to rebase the last two commits in your current branch, enter the following command in the terminal if you’re a Linux or MAC user:

git rebase -i HEAD~2

The above scenario is illustrated in the slides above.

Example

Let’s see git rebase -i HEAD~n in action:

mkdir example
cd example
git init
echo "Hello1" > example.txt
git commit -am "first hello"
echo "Hello2" > example.txt
git commit -am "second hello"
echo "Hello3" > example.txt
git commit -am "third hello"
git rebase -i HEAD~2

The above code creates a folder example and initializes git inside the folder. Then, we do a series of commits, where we edit the file example.txt. Now, you want your branch to reflect the second last commit that has the commit message, “second hello”. Enter the following command:

git rebase -i HEAD~2

The -i flag stands for interactive; the rebase opens an interactive vim editor where you can not only rebase to the second last commit but alter the commit history up to that point in the process as well. Your shell would look something like this:

pick 64794ce second hello
pick e772fe9 third hello

# Rebase 4bdbfef..e772fe9 onto 4bdbfef (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified); use -c <commit> to reword the commit message
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.

Remove the second pick command line and save before closing the interactive shell. You’ll have the following result on the screen:

Successfully rebased and updated refs/heads/main.

Now, you can use the below cat command to verify the changes:

cat example.txt
Hello2
Copyright ©2024 Educative, Inc. All rights reserved