DEV Community

Cover image for Do your commits pass this simple test?
Jonathan Irvin
Jonathan Irvin

Posted on

Do your commits pass this simple test?

Photo by William Iven on Unsplash

Frequent.
Descriptive.
Atomic.
Decentralized.
Immutable.

I'll leave it up to your imagination to come up with a clever mnemonic to remember that acronym above.

I love writing about Git and SCM in general because I believe it's crucial to proper CI/CD practices. It's how we submit our code. It should matter.

I've come up with a solid metric for measuring the success and value of a commit. It has 5 key points I've mentioned above.

Frequent

When did you last commit? 2 seconds ago or 2 hours ago. The longer you wait, the more trouble you will have with having your commits tell a story. How long did you wait before your last commit?

Descriptive

Click. That's usually the sound a camera makes when it takes a picture. That's the same idea when Git captures a diff of your changes and you put your label on it. I've found Git commit messages are oftentimes more useful than code comments. Can you describe your change verbosely, yet concisely?

Atomic

Are you the type that throws everything in a laundry bin or do you sort your clothes before washing? We can relate laundry to commit messages, in a way. Your commit should only have related changes. Each commit should be easy to revert. Keep your commits small and relevant and you will never have to undo hours of work. Did you keep this commit small and only containing relevant changes, not ALL changes?

Decentralized

This one is super easy. Git doesn't automatically upload your commits to the "Cloud". Everything is local until you push your commits to a separate repo. Most of us humans use GitHub or something like it. Have you pushed this commit yet?

Immutable

A commit is a commitment. Once it's done, do your best to avoid changing it. That means timestamps, authors, and even the contents should never change after it's saved. Is your commit a "forever commit"?

Top comments (27)

Collapse
 
gypsydave5 profile image
David Wickes • Edited

Can you describe your change verbosely, yet concisely?

To put it concisely: no.

Or, to be more verbose:
NOOO

😉

Collapse
 
sublimegeek profile image
Jonathan Irvin

Very true. I'm not a fan of squashing commits because you lose the history (in a way) of each commit message. One of the tools I use in troubleshooting or continuous development is relying on the commit messages of other developers from a quick git blame on a file I'm working on. 9/10 times, the commit message is much more useful than a code comment.

Collapse
 
ewoks profile image
Beeblebrox

I agree 100%, but if squashed there is not too much use of blame no?

Collapse
 
eljayadobe profile image
Eljay-Adobe

Color me envious. I wish we used Git at work on my project. Frequent, small check-ins would jibe with how I work. As well as frequent branching.

At work, we use a centralized version control system. Check-ins are large and infrequent, and have to have been compiled and tested before check-in, because each check-in triggers the CI/CD build server. And breaking the build causes other developers to break out the pitchforks and torches.

Compiling the project takes between ten minutes to an hour, depending on how much gets touched. (Although long in the tooth, Lakos's Large-Scale C++ Software Design is highly applicable to my project. Wish we could apply it. Alas.)

Collapse
 
jaytedgar profile image
JayTEdgar

Do you have a recommendation for how frequently one should make changes? For instance, I am working on a new feature today, and I plan on committing after I'm done in about three hours. Does that make sense?

Collapse
 
bosepchuk profile image
Blaine Osepchuk

Commit frequency depends on the task and your workflow. We use feature branches with git.

When I'm adding a feature to an existing code base or fixing a defect, I usually do a bunch of refactoring commits. I try to keep similar changes together. So I'll get commit messages like:

  • run codestyle tool
  • refactor variable names (using refactor tool)
  • update documentation
  • add more unit tests

And then I'll write commits for the new code:

  • add new class x that does y with unit tests
  • add new class a that does b with unit tests
  • etc.

If it gets too big I break it into multiple pull requests. 8-10 commits per pull request is about as high as I'll go.

My main goal is to make my code changes reviewable. Having the refactoring changes separate from manual changes makes code much easier to review.

I also like the idea of using commits like a ratchet. So I'll commit when I'm about to move from a change that I'm sure about to one that I'm tentative about. Then I can revert quickly if I feel I've gone down the wrong path without losing the changes I was sure about.

Collapse
 
sublimegeek profile image
Jonathan Irvin • Edited

I start with everytime you hit save. Can you describe your change in one sentence? Commit it. Then after you get into the rigor of committing that frequently, then you can begin to scale back. It's more art than science.

Collapse
 
jaytedgar profile image
JayTEdgar

Every time I save? Good lord! I save at least once every 2 minutes.

Thread Thread
 
sublimegeek profile image
Jonathan Irvin

Lol, but you get my point. It's extreme, but you have to think about the changes you made. Adding classes and methods can constitute a commit.

Collapse
 
dan503 profile image
Daniel Tonon

I think there is one that you missed "format".

A commit should look like this (although the long description isn't always necessary)


Short title saying what commit does

Long description with as many characters as you want explaining why the commit was needed.

Collapse
 
sublimegeek profile image
Jonathan Irvin

This is what I'd meant by descriptive. I'm implying the format of the git commit message.

Collapse
 
dandevri profile image
Danny de Vries

Writing good commit messages is also crucial.
chris.beams.io/posts/git-commit/

Collapse
 
sublimegeek profile image
Jonathan Irvin

Totally agree. That's why I shortened this article down to just "descriptive". I'm implying the commit message should be descriptive.

I just x-posted my larger article from Medium. Check it out dev.to/sublimegeek/check-out-these...

 
stargator profile image
Stargator

I certainly don't recommend spending hours on a message. And in your example of the branch names containing the task number, we do that too.

But if branch 2345 is branched off of 1900, then some new commits are added to 1900. By looking at the commit history of 1900, how would you tell when 2345's commits ended and 1900's started?

Date, time, and author may be useful. But that would take more mental power than simply having "2345" at the start of all of 2345's commits and "1900" at the start of all of 1900's commits.

My team's backend branches off of each other quite a bit and sometimes the frontend team does it as well.

So those 2nd-tier branches depend on a 1st tier branch that isn't even completed. So the 1st tier branch could still change as time goes on, from new commits to changing the history of the branch.

That would cause conflicts to occur when the 2nd-tier branch tries to merge into master (after the 1st tier supposedly does) or when it rebases back onto the 1st tier branch.

It all just depends on the team's workflow, the team size, and the complexities of your tasks.

Ideally, nothing would get started that depends on changes that haven't been merged into master.

But in real-life messes happen, and having clear intent and purpose in the commit messages would be beneficial.

If you are spending hours on your commit message, maybe the work was too much for a single commit or you are overthinking the message.

Collapse
 
theodesp profile image
Theofanis Despoudis

I suppose the second point makes sense if you are creating specialized branches or when you are working locally and before you push your changes you want to show a unified picture in your log.

Collapse
 
simo97 profile image
ADONIS SIMO

Thank for this small an concise article about best practices on the commits usage

 
sublimegeek profile image
Jonathan Irvin

Had to look that up. For those unfamiliar: git push --force-with-lease

Collapse
 
ferricoxide profile image
Thomas H Jones II

Yes and no. If your team's overarching strategy is fork-and-branch, you can still maintain your full commit-history in your fork.

Collapse
 
qm3ster profile image
Mihail Malo

That's an incredibly inappropriate acronym.
Good on you!

Collapse
 
sublimegeek profile image
Jonathan Irvin

What's the point of squashing?

 
beyrem_makh profile image
beyrem Makhlouf

Yes
But if your branch live for days, we may stay need to have multiple commit
I used to revert my own code before merging my PR

Thread Thread
 
stargator profile image
Stargator

To continue on @beyrem_makh 's point, even if you know your commits will be squashed if you ever need to revert a commit, drop it, or edit it then having clear commit messages would be helpful.

For example, if I've been working on a branch for a few days, but another task is dependent on those changes before it can get started. Then another developer may branch off of my branch and start their work.

Some time later, my branch is squashed into master. But before the second branch can be squashed in, that author will need to know which commits were for one task and not the other.

If neither developer worked on both branches, than it's easier to tell.

But if either of them did or both tasks on worked on by the same person, then having a clear commit message is critical.

On my teams, we include the task number we are working on in the commit message. Always the first thing typed out.

Collapse
 
beyrem_makh profile image
beyrem Makhlouf

It's applicable even in feature branch