Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. It is an essential tool in an open source developer's toolkit.
This article covers why and how to use the
git rebase --interactive (
-i for short) command. This is considered an intermediate Git command, but it can be very useful once you start working with large teams.
This command is one of the most powerful in Git. The
git rebase command helps you manage multiple commits, including:
- Flatten (or squash in Git terminology) several commits so that they look like they were all done at once
- Delete one of the commits
- Split one commit into two
- Reorder the commits
git rebase command can rewrite your repository's commit history by rearranging, modifying, and even deleting commits. So let's get started!
Helpful instructions in the rebase message
git rebase -i interface is, as its long form
--interactive flag implies, an interactive interface. It provides a list of commits, and then you choose what actions you want Git to take on each of them. Taking no action is a valid choice, but at least one commit must be marked as the one to squash, or the rebase is functionally meaningless.
- p, pick — Pick this commit to keep.
- e, edit — Edit this commit to amend the commit message.
- r, reword — Use this commit, but also edit it.
- s, squash — Squash this commit into a previous commit. When performing a
git rebase -i, you must have at least one commit marked as squash.
- d, drop — Delete this commit.
Suppose you have two commits, and you want to squash them into one. This is achieved by using
git rebase -i HEAD~2 (that's two commits from your current position) command and by putting the word squash before the commit.
$ git rebase --interactive HEAD~2
Running this command gives you a list of commits in your text editor that looks something like this:
pick 718710d Commit1. pick d66e267 Commit2.
If you want to make a single commit from two commits, then you have to modify the script to look this:
pick 718710d Commit1. squash d66e267 Commit2.
Finally, save and exit the editor. After that, Git applies all the changes and opens an editor to merge the two commits:
# This is a combination of 2 commits. # This is the 1st commit message: Fuse smoke test versioning. # This is the commit message #2: Updated the code. # Please enter the commit message for your changes.
Saving this results a single commit that introduces the changes of two previous commits.
Suppose you have three commits, and you want to change their order such that Commit3 is first, Commit2 is second, and then third is Commit1. Run
git rebase -i HEAD~3 to make this happen:
$ git rebase --interactive HEAD~3
This script is opened in your editor:
pick 8cfd1c4 Commit1 pick 718710d Commit2 pick d77e267 Commit3
Modify the script like this:
pick d77e267 Commit3 pick 718710d Commit2 pick 8cfd1c4 Commit1
When you save and exit the editor, Git rewinds your branch to the parent of these commits, and applies d77e267, then 718710d, and then 8cfd1c4 as the commit numbers are not matching.
Delete a commit
Suppose you have two commits and want to get rid of the second one. You can delete it using the
git rebase -i script.
$ git rebase -i HEAD~2
This script is opened in your editor:
pick 8cfd1c4 Commit1 pick 718710d Commit2
Place the word drop before the commit you want to delete, or you can just delete that line from the rebase script.
pick 8cfd1c4 Commit1 drop 718710d Commit2
Then save and exit the editor. Git applies the changes and deletes that commit.
This can cause merge conflicts if you have many commits later in the sequence that depend on the one you just deleted, so use it carefully. But you have an option to revert the changes.
Rebase with caution
If you get partway through a rebase and decide it's not a good idea, use the
git rebase --abort command to revert all the changes you did. If you have finished a rebase and decide it's wrong or not what you want, you can use
git reflog to recover an earlier version of your branch.
Rebasing is powerful and can be useful to keep your repo organized and your history clean. Some developers like to rebase the main branch so that the commits tell a clear story of development, while others prefer for all commits to be preserved exactly as they were proposed for merging from other branches. As long as you think through what your repo needs and how a rebase might affect it, the
git rebase command and the
git rebase -i interface are useful commands.