Why Commit Granularity Matters
A commit can go one of two ways. It can be a catch-all container for unrelated work — a bugfix here, a module rewrite there, a few new files for a feature that's still taking shape. Or it can be a focused unit of change that belongs to exactly one topic. The second kind is what keeps a codebase comprehensible over time.
Treating Git as a glorified backup system is tempting. When changes are bundled into commits without regard for their subject matter, though, the history loses meaning. There's no reason one change landed in one commit and another landed elsewhere. Reviewing such history is like sorting through a household junk drawer: everything is in there, but finding anything specific is miserable.

A little planning at commit time rewards the whole team with a readable history. Granular commits help explain complex changes in digestible increments. Even months later, when someone needs to understand why a particular revision exists, well-composed commits make that job far easier.

Leveraging the Staging Area
The central tool for composing better commits is the Staging Area. It exists precisely so developers can choose, with precision, which changes belong in the next commit. Git requires interaction with this area — unlike some other version control systems — but it's easy to circumvent its purpose with a blanket git add ..
That command stages every local change, whatever topic it belongs to. Sometimes that's perfectly fine. Often, however, it's worth stopping to ask whether all staged changes are really about one thing, or whether they'd be clearer as two or three separate commits. In most cases, smaller commits focused on a single topic are more readable than larger ones spanning several.
$ git add file1.ext file2.ext
That commands stages only the nominated files, leaving other work for future commits or further editing. Taking this deliberate moment to choose what makes the cut goes a long way toward cleaner history.
Partial File Staging
Sometimes even changes within a single file span multiple topics. For this, Git offers a more granular route. While git diff shows the exact changes in a working file, adding the -p flag to git add invokes patch-level staging:
$ git add -p index.html
Git will walk through the file's hunks of changes, asking for each whether it should be staged. Answering [Y] for one hunk and [N] for another lets you commit the first part of a file's changes while leaving the rest for later.

The result is a commit that is precise, focused and confined to a single logical change — even when that change shares a file with unrelated edits.
Considering Tests
Any serious discussion of commit quality has to address testing. Many teams won’t mark code as done unless it’s properly tested, and tests can be a decisive part of whether a commit is truly valuable.
A few myths about testing are worth rejecting:
- "Tests are overrated." Tests catch bugs before they reach production, where mistakes are most costly. Finding issues early is far cheaper than fixing them after release.
- "Tests cost valuable time." Well-written tests typically lead to faster development overall. Less time goes to hunting bugs, and a well-structured test often clarifies the thinking needed for the implementation itself.
- "Testing is complicated." This was arguably true years ago. Today, most mainstream languages and frameworks ship with strong support for setting up, writing and running tests.
Fold tests into your development routine and your codebase will almost certainly become more robust — and your own coding habits will sharpen as a result.
Crafting a Meaningful Commit Message
Commits don’t exist merely to back up code. They are the project's narrative, and the commit message is where that narrative is told. The author of a high-quality commit writes not just for the present self, but for every teammate who will later have to understand what happened.
Two parts make up a good commit message:
- A concise subject line that summarizes what changed.
- A descriptive body that covers the most relevant facts, as briefly as possible.
The subject line should, ideally, stay under 50 characters. If a short summary is hard to write, it may be a sign the commit covers too much ground. That's a cue to split the work into multiple commits rather than to accept a vague or overlong subject.
Separate the subject from the body with a blank line; Git will treat what follows as the message body. The body should answer three questions:
- What changed along with this commit?
- Why was this change necessary?
- Are there any peculiarities or caveats others should know?
Teams that agree on message conventions — character limits, wrapping rules and the like — tend to have better history quality overall.

In the end, a great codebase is built one commit at a time. The discipline of granular staging, testing and thoughtful messaging is what separates useful history from a disorganized pile of snapshots.



