Code Time Capsules: Effective Git Commits

Close-up view of effective Git commits with branching lines in a code repository.
Photo by Yancy Min on Unsplash

Engineers often find themselves grasping for context.  “Who wrote this code?”  “Why was this change made?”  “Judy worked on this code but she won the lottery.”  We find ourselves picking through our codebase as though it was a dig site.  It can be exhausting to probe deeply into the code, finding long buried artifacts written in strange yet somewhat familiar language without context and trying to reconstruct a dinosaur from scattered bones.  What if instead these ancestors of ours had taken the time and care to meticulously document and catalog their intent? Can we use Git commits as a scroll of record to help ourselves and those who come after us?

Small commits, effective titles

Let’s take a look at the output of the git log –oneline command:

$ git log --oneline
a619791 Update blog name
ab57c08 Update link to new LinkedIn profile
7bd7970 Add git blog post
c491536 add my linked in
e21d6c0 Add resume and about links
20698d9 Add links
17812ca Initial commit

The `--oneline` option combines two other options. `--abbrev-commit` which  condenses the 40-bit git hash to 7 characters (`a6197917e91adbbbdad6e188390e67e495c679bb` becomes `a619791`) and `--pretty=oneline` which only prints the commit hash and the title of the commit. The title is the first line of the commit message.  Each line of the log output is the abbreviated commit hash followed by the title.

My goal with commit messages is to show the most useful information to the reader as soon as possible focusing on why the changes were made, not what changes were made. Fewer changes in a single commit can make it easier to create a title to communicate why we changed the code. This means that when someone starts digging into the git log they can very quickly gain context about the “why” of the code. These summaries can also be used for other purposes. I have been on teams that needed to create a list of changes to publish as a change log with an update and the git log should have made it an easy task but instead we had to dig through many commits as well as the ticketing system.

Let’s look at some examples of how short, informative summaries can enhance the use of our tools. We can more closely examine these lines from  git log –oneline:

e88d97b add link to workplace
a619791 Update blog name
ab57c08 Update link to new LinkedIn profile

We can see at a glance what has happened recently in our repository.  We have effectively used the title to quickly and succinctly show what our team has been contributing.  We can and should be using the body of the commit to add more context to our changes, but a well written title brings the most important information to the surface.

Good commit message titles can also enhance our experience in our other tools such as our IDE.  Here is an example from Visual Studio Code using a git plugin to display details about our code changes. We can see the title of the first commit (`e88d97b`) from the above example. 

Screenshot displaying a Git commit update in Visual Studio Code, showcasing code collaboration.

Without running any commands or leaving the IDE environment, we can see exactly why that line was changed.

Small Commits are Portable

Another advantage of small commits is that these changes can be pulled into other branches easily. If I find a typo or a small bug or I want to refactor a variable name or any small change that would be useful on another branch, it can easily be cherry picked from my current working branch using the git cherry-pick <commit hash> command. Here is the git log from a feature branch to add links to the header of a blog:

13499c2 add link to twitter
e9d321a add link to workplace

We decide we want the code for “added link to our workplace”, but do not want to include the Twitter link.  From another branch we can cherry pick the changes from commit `e9d321a` into our working branch. Here is what happens when we use the cherry-pick option:

$ git status
On branch january_10_release
nothing to commit, working tree clean

$ git cherry-pick e9d321a
[january_10_release b393988] add link to workplace
 Date: Wed Jan 3 14:33:28 2024 -0600
 1 file changed, 5 insertions(+)

Now those changes have been added onto our current working branch with the commit `b393988`.  See the `git log –oneline` output below:

$ git log --oneline
b393988 add link to workplace
a619791 Update blog name
ab57c08 Update link to new LinkedIn profile
7f04e10 Add date to New Year's post

Why did the hash change?  To generate a commit hash, the value of the previous commit hash is included in the calculation.  If we say we are cherry picking a commit that is not correct. We are actually only cherry picking the changes that commit represents.

If we had made the change to add the workplace link and the change to add the Twitter link in a single commit it would have been more difficult to grab only the changes we wanted and may also have caused conflicts when merging both branches back into main.

Below we have merged our `january_10_release` branch into the `main` branch.  We can now rebase the `add_more_links` branch to replay our commits after all of the commits that exist on the `main` branch.

$ git checkout main
Switched to branch 'main'

$ git merge january_10_release
Updating a619791..b393988
Fast-forward
 index.html | 5 +++++
 1 file changed, 5 insertions(+)

$ git checkout add_more_links
Switched to branch 'add_more_links'

$ git rebase main
warning: skipped previously applied commit e9d321a
hint: use --reapply-cherry-picks to include skipped commits
hint: Disable this message with "git config advice.skippedCherryPicks false"
Successfully rebased and updated refs/heads/add_more_links.

Here git recognizes that main and add_more_links have changes in common and does not apply the changes of that commit to our working branch.

2199de7 add link to twitter
b393988 add link to workplace
a619791 Update blog name
ab57c08 Update link to new LinkedIn profile
...

Our git history for the `add_more_links` branch now matches what is in the `main` branch, down to the new commit hash `b393988`.  Our changes to add the Twitter link have also been replayed.

Conclusion

With this knowledge we should be able to leave our codebase with the context needed for our colleagues and ourselves to quickly understand the context of a commit.  For many reasons we can’t always remember our reasoning behind what we did a week, month, or year ago, If we leave a trail of breadcrumbs in the form of small commits with well written summaries we can do our team a huge favor in the future instead of leaving them bones to pick through.

Author

  • Mike Beasterfeld is a Senior Software Engineer at Integral with over two decades of experience in the software development industry. He has worked with many languages across many platforms including automation, deployment, web development on the front end and back end, and mobile apps. Away from a keyboard you can find him cooking a new recipe, tending to his garden, or enjoying the company of an ever changing number of canine companions.

Scroll to Top
Copy link