Published on

Git - The power of fixup & autosquash

Authors

NB: I published this article originaly at medium. I decided to move it to my personal blog since I have had one ;) .

Real programmer life

Imagine you are working on the branch feature-X and you have 2 commits:

  • second-commit-id second commit
  • first-commit-id first commit

You realize that in the first commit, you have a typo mistake. Then you create a new commit to fix the typo, but the problem is you don’t want to have a dedicated commit to fix a mistake from another commit and the added commit does not intend to add any value to your current feature.

You can easily to fix it by using git commit --fixup and git rebase --autosquash. Let’s me show you what are they and how to use them:

git commit --fixup

Some Javascript code

git commit --fixup=<commit>  -- construct a commit message for use with rebase --autosquash

Basically, the commit that you are going to create to fix the typo, instead of you use git commit -m "fix type", You should mark it as the fixup for the first commit.

git commit --fixup=first-commit-id

You can check the result by: git log --oneline

9e98aa0 fixup! First commit
ce13566 Second commit
c797a94 First commit

You can see the indicator fixup! and the following message of the first commit.

git rebase --autosquash

git rebase --help

--autosquash, --no-autosquash
           When the commit log message begins with "squash! ..." (or "fixup!
           ..."), and there is already a commit in the todo list that matches
           the same ..., automatically modify the todo list of rebase -i so
           that the commit marked for squashing comes right after the commit
           to be modified, and change the action of the moved commit from pick
           to squash (or fixup). A commit matches the ...  if the commit
           subject matches, or if the ...  refers to the commit’s hash. As a
           fall-back, partial matches of the commit subject work, too. The
           recommended way to create fixup/squash commits is by using the
           --fixup/--squash options of git-commit(1).

           If the --autosquash option is enabled by default using the
           configuration variable rebase.autoSquash, this option can be used
           to override and disable this setting.

And now is the time to squash commits with the command:

git rebase -i upstream-branch --autosquash

The upstream-branch is the target branch that you want to merge your feature.

Git will show you in an editor the result like this:

pick c797a94 First commit
fixup 9e98aa0 fixup! First commit
pick ce13566 Second commit

Notice that the fixup commit is placed right after the first commit. You save the editor and complete. Check the result by git log --oneline:

11804b6 Second commit
dbbff15 First commit

You can see IDs of your commits may be changed because basically, you have modified the content of the commits.

Is that all?

Of course, no. There are some more applications of fixup commits. Especially when you ask for review you code. After the first reviews, reviewers would happy if you use fixup commits to modify your pull requests, and they won’t need to review from the start but focus on the adding fixup ones. It saves time for people and then saves money for companies. For example:

pick dbbff15 First commit
fixup afa2cee fixup! First commit
fixup d6f0da6 fixup! First commit
pick 11804b6 Second commit
fixup d8e4185 fixup! Second commit

And after the reviewing process done, you can rebase with autosquash before merging your PRs.

Enjoy programming!