← Blog

Guide · · 4 min read

What a GitHub commit actually is, in plain English

A commit is one saved batch of changes with a note attached. What it records, how to read the message prefixes, and why the message often tells you almost nothing.

DevSummary Team

A commit is one saved batch of changes to the code, with a short note describing it. That is the whole concept. GitHub’s documentation puts it as recording changes to one or more files in your branch, which is closer to saving a version of a document than to anything exotic.

If you are not an engineer and you have been nodding along in meetings, this page is the ten minutes that makes the rest of GitHub legible.

What a commit records

Every commit carries four things:

  • The changes themselves. Which files, and exactly which lines were added, removed or altered.
  • Who made them. The author, from their git configuration.
  • When. A timestamp.
  • A message. A one-line description the developer wrote, sometimes with a longer body underneath.

Git also assigns each commit a unique identifier, a long string of letters and numbers called a hash. You will see the first seven characters of it everywhere, something like 4e9c1af. It is just a name, so that any commit can be pointed at unambiguously.

Taken together, the commit history is the project’s diary. Unlike most diaries, it is complete: nothing gets into the product without passing through it.

What a commit is not

A commit is not a feature. This is the misunderstanding that causes the most confusion in practice.

One feature usually takes many commits. Adding a login screen might be a commit for the form, one for the API endpoint, three for fixing what broke, and one for a typo in a label. A single commit is more like a keystroke than a chapter. Counting them tells you nothing about how much shipped.

A commit is also not necessarily live. Code gets committed long before customers see it. Between the commit and the customer sit code review, a merge, and a deployment, and any of those can take days. A busy commit history and a quiet product are entirely compatible.

Reading the message

Most teams follow a loose convention where the first word signals the kind of work. The widely used version is the Conventional Commits specification, which formally defines two types and recommends several more:

PrefixWhat it means
featA new feature was added
fixA bug was patched
refactorThe code was restructured without changing what it does
perfSomething was made faster
testTests were added or updated
docsDocumentation only
build / ciChanges to how the project is built or deployed
choreRoutine maintenance with no visible effect
styleFormatting only, no behaviour change

The specification defines feat as introducing a new feature and fix as patching a bug. The rest are conventions borrowed from the Angular project and adopted widely.

There is also BREAKING CHANGE, which can appear as a footer or as an exclamation mark before the colon, as in feat!:. That one is worth knowing: it means something that used to work a certain way no longer does, which is the kind of change that generates support tickets.

So feat: add invoice export reads as a new capability, and chore: bump dependencies reads as housekeeping. That much you can now do at a glance.

Why the message still will not tell you much

Here is the limit. Commit messages are written by developers, for developers, at the moment they finish a piece of work. They describe the code, not the consequence.

fix: handle null customer on webhook retry is a perfectly good commit message. It is also completely silent on the only question a founder has, which is whether the payment problem that has been generating refund requests for two weeks is now solved. The message names the mechanism. You wanted the outcome.

Two more reasons not to over-trust the message:

  • Prefixes are a convention, not a rule. Nothing enforces them. Plenty of repositories have messages like wip, fixes, or asdf, all of which shipped real code.
  • The label reflects intent, not size. A chore can rewrite a third of the codebase. A feat can be a button.

If you want to know what actually changed, the change itself is the source of truth, not the sentence attached to it. That is the difference between a report built on commit messages and one built on reading the code.

What to look at instead

For a specific question, GitHub’s interface answers it directly. The commit history on a repository shows every change in order. The blame view shows who last touched each line. Pull requests group commits into a unit of intent and usually carry a title someone wrote deliberately, which makes them better reading than individual commits.

For the recurring question, none of that scales. Nobody wants to read a commit history weekly, and the person who could translate it for you is the person whose time you are trying to protect. That is the case for a scheduled summary rather than a browse, which is covered in the guide to GitHub reporting for non-technical stakeholders.

If your job is to pass that summary upward, how to report engineering progress to non-technical stakeholders covers the format.

Two practical follow-ons: if you want to run the numbers yourself, generating a commit report from the command line shows the exact commands. If you would rather it arrived on its own, sending a weekly GitHub digest to Slack covers the delivery options.

DevSummary reads the code changes rather than the commit messages, which is why its reports describe what customers can now do instead of which functions moved.

Knowing what a commit is will not tell you what your team shipped. It will tell you why nobody has been able to answer that question from the commit log alone.

More posts