What should git commits look like? How should comments work? A brief review of some good practices, complete with examples where I've made mistakes myself.
2. What is a commit?
Changes
What they were based on (parent commits)
Message
Author (& optional committer), timestamp
A name (SHA)
3. What is a good commit?
Changes that do a single thing
What they were based on (parent commits)
Message that describes the thing clearly
Author (& optional committer), timestamp
A name (SHA)
4. What is a good commit?
Changes that do a single thing
What they were based on (parent commits)
Message that describes the thing clearly
Author (& optional committer), timestamp
A name (SHA)
5. Do a single thing
Only make one change per commit
Make the whole change in one commit
Avoid committing code that’s been
commented out
6. Do a single thing
Only make one change per commit
Make the whole change in one commit
Avoid committing code that’s been
commented out
7. One change per commit
Commits are objects in git, so we can
work with them using git revert, git
cherry-pick and git rebase
But this only works if a commit does one
thing
Yes, you can use interactive rebase to split
commits after the fact, but it’s painful
8. One change per commit
!
If you need to reformat or fix whitespace, that
is its own commit
Refactors are their own commits
Other bugs fixed are their own commits, but
ideally, don’t get sidetracked — note it down
for later
9. One change per commit
!
If you have multiple changes per commit,
it’s almost impossible to write a good
commit message (which we’ll shortly
discuss further)
git add -p is your friend, as is using
the index incrementally
10. Do a single thing
Only make one change per commit
Make the whole change in one commit
Avoid committing code that’s been
commented out
11. The whole change in one
Commits are much easier to review
Even if you review at a PR level, well-
sized commits make it easier to see the
structure of the change
Also important in later forensics eg git
bisect
12. The whole change in one
Check your commits before you push, or
at least before you make a PR
You can coalesce commits using git
rebase -i
You can force push your rebased changes
just before making a PR
13. The whole change in one
if you add commits in response to review
comments, you can rebase then force
push to the PR’s branch after code review
before merge
we could use a tag to indicate desire for
a final rebase step and avoid zealous
merges
14. Do a single thing
Only make one change per commit
Make the whole change in one commit
Avoid committing code that’s been
commented out
15. Avoid commented code
If it used to be live code, it’s in the history
If not and you “might need it later”:
put it in a commit (possibly on a different branch)
or stash it
or just leave it in your working tree
by the way you probably won’t need it later
16. What is a good commit?
Changes that do a single thing
What they were based on (parent commits)
Message that describes the thing clearly
Author (& optional committer), timestamp
A name (SHA)
17. Describe it clearly
Start with a short (50 chars) summary
Describe the effect not the code
Ideally use the imperative: “fix bug” not
“fixed bug” (matches git auto-messages
on merges for instance)
18. Describe it clearly
Start with a short (50 chars) summary
Describe the effect not the code
Ideally use the imperative: “fix bug” not
“fixed bug” (matches git auto-messages
on merges for instance)
19. A short summary
most of git (and particularly git
rebase -i, git show-branch) will
truncate if it can’t fit
lots of people’s terminal are 80 characters
wide (and git needs space for the SHA)
github is also designed for this length
20. A short summary
!
More detail follows in longer (72 chars)
lines
Maybe reference issue tracker — however
git history is likely to live longer, so don’t
omit key details of implementation (from
pragmatic planning)
21. Describe it clearly
Start with a short (50 chars) summary
Describe the effect not the code
Ideally use the imperative: “fix bug” not
“fixed bug” (matches git auto-messages
on merges for instance)
22. Describe the effect
No point describing the code changes: the code
changes are already part of the commit
However capturing intent, how these changes solve
the problem or satisfy the feature, is important
Helps code review (is the intent what I expect? does
the code match the intent?)
Helps future forensics: why is this code there or
written in that way?
23. Describe it clearly
Start with a short (50 chars) summary
Describe the effect not the code
Ideally use the imperative: “fix bug” not
“fixed bug” (matches git auto-messages
on merges for instance)
26. Too terse
!
Relies on the link to the github issue.
!
Better to be more specific here:
!
De-emphasise short utterances in search results
27.
28. Too terse
!
The intent is captured, but the context isn’t clear unless
you know the project well: this change is in metadata for
a Spacelog mission, and it configures how mission
timestamps are displayed.
!
Better would be:
!
Don’t show days in timestamps
!
The whole mission lasts less than a day.
29.
30. Playful and informal, but not terrible
!
The commit (there’s more) does actually escape all the
things (not previously escaped).
!
It would be helpful to list the things escaped, in case it
turns out we’d missed one.
31.
32. Too playful
!
The summary is pretty good (although it could have
mentioned that the commit also implements the confirm
email step itself).
!
The detail is taking playfulness too far: “carefully” refers to
the view which is defensive about using the confirmation
URL if logged in as another user already: spelling this out
would have been much better.
33.
34. Good level of detail
!
Summary captures the point.
!
Detail explains why, pulls out details of the RE (which are
difficult to read in the changeset).
!
Also notes that this was needed on OS X, so anyone
working on this in future has a concrete platform to test
against to see if they’re correct.
35.
36. Almost completely useless
!
Firstly, describing the way python works unless it’s a weird
corner case is a waste of time.
!
Secondly, it doesn’t explain what it was about sizes.max that
needed fixing.
!
Thirdly, the change doesn’t just take into account that
range() is exclusive at the top end — because it raises its
parameter by two, not just by one, without explanation.
37.
38. Just terrible
!
“Play with” is a big warning sign, because commits have
intent, but play does not.
!
Better to be explicit:
!
Improve error reporting around common problems
!
- show line number when can’t parse page or tape number
- when being verbose, print raw lines as we translate them
39. Reading
A Note About Git Commit Messages by
Tim Pope (http://tbaggery.com/
2008/04/19/a-note-about-git-commit-
messages.html)
What’s in a Good Commit? by Timo
Mihaljov (http://dev.solita.fi/2013/07/04/
whats-in-a-good-commit.html)