git fixup

When using git sometimes you want to make a change and include it with the previous commit. The easiest way to do this is:

$ git add <files> $ git commit --amend --no-edit

Sometimes you want to include your change in a commit before the previous one. To do this takes a few steps.

fixup! and --autosquash

The general way to edit history in git is with git rebase -i . This does an interactive rebase, which allows you to re-order, remove, edit, and squash commits.

When you do git rebase --help , you find this documentation about --autosquash :

--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). This option is only valid when the --interactive option is used.

So if we have a commit with the message fixup! <commit-hash> where <commit-hash> is the hash of the commit you want your changes to be included in, we can do git rebase -i --autosquash to get the rebase command to automatically re-order the commits and mark them for being squashed.

$ git add <files> $ git commit -m "fixup! <commit-hash>" $ git rebase -i --autosquash

Then the interactive rebase editor opens and you have to save and exit. This isn’t as nice of a workflow as git commit --amend --no-edit because you need to make a new commit, and open a text editor during the interactive rebase.

git fixup <commit-hash>

We can add a new git command git fixup by adding an executable called git-fixup on our path.

Here is the contents of my git-fixup script:

#!/bin/bash if [ "$#" -ne 1 ] ; then echo "usage: git fixup <commit>" else COMMIT = $( git rev-parse " $1 " ) numstaged = $( git diff --cached --numstat | wc -l ) if [ $numstaged -gt 0 ] then git commit -m "fixup! $COMMIT " fi GIT_SEQUENCE_EDITOR = true git rebase -i --autosquash --autostash $COMMIT ^ fi

To use this script, save it with the name git-fixup somewhere in you PATH . Make sure you make it executable. Then you simply find the commit hash of the commit you want to modify and type:

$ git add <files> $ git fixup <commit-hash>

This is very similar to the git commit --amend --no-edit workflow.