# Git fixup explained

Quite often we must modify a file that has been already committed to the local repository. In this case, we often end up with commit messages like: “Fixed typo.”, “Added missing parameter.”, “Removed redundant import.”

The problem occurs frequently, but we don’t want to have such commits in our git history. Fortunately, there are at least two options to get rid of them.

# git rebase -i

The simplest solution is to create that artificial commit with any message we want and then squash it with another commit. The message does not matter, because nobody is going to see it anyway.

In the first example, I created 4 commits. I want to squash the last one with the second one.

1
git log — oneline


Now, I am going to run the interactive rebase of commits between the current HEAD and the three last commits.

1


I must move the commits around. The “Fixed a typo in second change.” commit must be below the second commit. Additionally, I have to change the command from pick to fixup.

Don’t forget to save the file opened by git rebase!

Done, I have commit history without artificial commits.

# git commit — fixup

When I think that I may forget to run git rebase, I use git commit with the fixup parameter to automatically move the commit in the proper place and mark as fixup of another one.

In this example, I have three commits. Now I have modified the file again, and I want to commit my changes as a part of the “Second change.” commit.

1
git log --oneline


I need the identifier of the commit I want to modify. In this case 1e30877

1
git commit --fixup 1e30877


Git created a commit marked as a fixup, but it is in the wrong place! I need to move the things around again.

First, I must check which commit was not affected by my recent change. I need its identifier. In my example it is: 7dbe2a9

Now I must run an interactive rebase with the autosquash parameter.

1
git rebase -i --autosquash 7dbe2a9


It is going to open the rebase text editor we saw in the first example, but this time all changes have been automatically applied.

All I have to do is saving the file.

# Change only a part of a file

Sometimes we want to fix a commit, but we have made many changes in the file, and only some of them should be squashed with a past commit. In such situations, we can use the patch parameter of the git add command to add only a part of the file to the commit.

Imagine that I have made two changes in the file, but only one of them should be used as a fixup.

1


This command opens a file view with all the changes I have made since the last commit. I can add a chunk of the file to the next commit (stage the change) or leave it unstaged.

In my example, the chunk suggested by git is too large. I want only the first modification. Fortunately, it is possible to split a chunk into smaller parts.

Now, I have to decide whether I want the chunk or not.

I won’t explain how to add chunks or split them because there is an excellent explanation on StackOverflow.

Now I can use git commit with the fixup parameter to mark my changes as a fixup and then run the rebase to modify the commits. There is one little issue. I have not added the second chunk to the commit, so when I run the rebase I get information about unstaged changes.

I can stash them, do the rebase, and unstash them back, but there is a shortcut. I can run rebase with the autostash parameter:

1
git rebase -i --autosquash 7dbe2a9 --autostash


# One more shortcut

We don’t want to type autosquash and autostash every time we do a rebase, so we are going to enable them in the git configuration permanently.

1
2
git config --global rebase.autosquash true
git config --global rebase.autostash true


Now, all I must type is the identifier of the last unaffected commit:

1
git rebase -i 7dbe2a9


Remember to share on social media!