keyboard-shortcut
d

fine grained commits

6min read

an image

Beginner git

When you start learning git, you simply want to stage all of your changes. To keep the workflow as simple as possible, you memorize git add . and git commit -m.

As you use git more and review other people's work, you start to notice that some people's PRs are incredibly tidy and well formed, where others just have swathes of arbitrary file changes. When you look at the commits in some PRs you can see that they are all logically grouped with only the changes relevant to the message in that commit. How are they doing this? Surely this is just how they are presenting their information, sure they don't think in this way.

Staging only specific changes

The way these fine-grained logical commits are achieved is by only staging small changes at a time. Rather than staging a whole file, a whole folder or just EVERYTHING git allows you to stage just a few lines at a time.

There are a couple of nice ways to do this...

git add --patch

Git works on this concept of "patches". Previously when people wanted to update their code base with someone else's changes they would share a patch file. A patch file is just a series of changes you want to communicate.

When staging your changes in git, rather than using git add . or git add <specific_file> you can instead ask git to break the changes down into small collections of changes with git add -p.

This brings up an interactive prompt where you can choose to select or reject specific changes to be added to stage. All the commands are helpfully listed, but there is one in particular that is incredibly helpful. If the "change" is too big, you can ask git to break it into smaller patches using s. This works quite well, but sometimes it isn't capable of breaking changes to a single line.

This tool is incredibly helpful for building logical commits but also makes sure that you know exactly what you are preparing to commit.

Lazygit

git add -p works really nicely 95% of the time, but sometimes the "group" of changes identified in a patch is too large.

Lazygit is a git TUI (terminal user interface) that allows an incredibly powerful git workflow. It has many features, but the main feature relevant for this article is how it asks what you want to stage. If you only want to stage individual lines from a file lazygit make this super simple with its beautiful UI. You simply enter the file of your choice, scan through the changes with up/down and then hit space bar to stage an individual line.

Lazygit makes staging individual morsels of code incredibly straight-forward.

VSCode (or any IDE really)

If you prefer clicking, most IDEs also offer a git diff tool that is capable of staging individual patches. Some even allow you to stage individual selections within a patch.

Conclusion

Whatever tool you use, make sure to stage only what you need for a specific commit. This will allow you to create a series of logically structured commits that make life much simpler for whoever is reviewing your code.