Rewriting Git History | git rebase -i
The git rebase -i command
Running git rebase with the -i flag starts an interactive rebase session. Instead of moving every commit unchanged onto a new base, interactive rebase lets you modify individual commits. You can use it to delete, split, edit, and reorganize an existing series of commits. It is essentially an enhanced version of git commit --amend.
Usage
git rebase -i <base>
Rebases the current branch onto <base> using an interactive rebase session. This command opens an editor where you can enter commands for each commit being rebased. Each command controls how that commit is moved onto the new base. You can also reorder commits by editing their order directly in the editor.
Additional notes
Interactive rebase lets you freely rewrite and polish the visible history. This gives developers considerable flexibility because even if development produced a messy sequence of commits, it can be reviewed and organized afterward.
Many developers use interactive rebase to make a feature branch look clean before merging it into master. With interactive rebase, you can squash unimportant commits together, delete unnecessary commits, and clean up everything before committing it to the official repository. To someone reading the history later, the feature development appears to have progressed smoothly as a well-planned series of commits.
Example
The following example rewrites the example from the non-interactive git rebase page using the interactive command.
# Start a new feature
git checkout -b new-feature master
# Edit files
git commit -a -m "Start developing a feature"
# Edit more files
git commit -a -m "Fix something from the previous commit"
# Add a commit directly to master
git checkout master
# Edit files
git commit -a -m "Fix security hole"
# Begin an interactive rebasing session
git checkout new-feature
git rebase -i master
The last command opens an editor and displays the two commits from the new-feature branch with related information.
pick 32618c4 Start developing a feature
pick 62eed47 Fix something from the previous commit
The pick command before each commit can be changed to another rebase command. In this example, use squash to combine the two commits:
pick 32618c4 Start developing a feature
squash 62eed47 Fix something from the previous commit
After saving and closing the editor, the rebase starts. Another editor window then opens so you can enter the commit message for the combined snapshot. After entering the message, rebase completes, and you can confirm with git log that the commits were combined.
Git Tutorial: git rebase -i example
Remember that the combined commit uses an ID different from both original commits. In other words, this commit is actually a new commit.
Finally, run a fast-forward merge to integrate the cleaned-up feature branch into master:
git checkout master
git merge new-feature
The power of interactive rebase appears in the rewritten master history. The commit with ID 62eed47 disappears completely from the history. To someone who does not know what happened, it looks as if the new-feature developer completed the work with only the necessary, well-organized commits. In this way, rebase helps clean up project history and make it easier to understand.