My interns are leaving today 😦 and I think the most important skill they learned this summer was how to use git. However, I had a hard time finding concise references to send them about my expectations, so I’m writing this up for next year.
How to Create a Good Commit
A commit is an atomic unit of development.
You get a feeling for this as you gain experience, but commit early and often. I’ve never, ever thought that someone broke up a problem into too many commits. Ever.
That said, do not commit:
- Whitespace changes as part of non-whitespace commits.
- Debugging messages (“print(‘here!’)” and such).
- Commented out sections of code.
- Any type of binary (in general… if you think you have a special case, ask someone before you commit)
- Customer data, images you don’t own, passwords, etc. Assume that anything you commit will be included in the repo forever.
- Auto-generated files (any intermediate building files) and files specific to your system. If it mentions your personal directory structure, it probably shouldn’t be committed.
Point #5 deserves a little extra mention: git keeps everything, so when in doubt, don’t commit something dubious. You can always add it later. When I was new at 10gen, I found a memory leak in MongoDB and was told to commit “what was needed to reproduce it.”
I committed a 20GB database to the MongoDB repo.
One emergency surgery later and the repo was back to its svelte self. So it is possible to remove commits if you have to, but try not to commit stuff you shouldn’t. It’s extremely annoying to fix. And embarrassing.
When you’re getting ready to commit, run git gui. This is the #1 best tool I’ve found for beginners learning how to make good commits. You’ll see something that looks sort of like this:
The upper-left pane is unstaged changes and the lower right is staged changes. The big pane shows what you’ve added to and removed from the file currently selected.
Right click on a hunk to stage it, or a single line from the hunk.
Click on this icon: to stage all of the changes in a file.
Note that notes.js is moved to the staging area (if only some parts of notes.js are staged, it will show up in both the staging and unstaged area).
Before you commit, look at each file in the staging area by clicking on its filename. Any stray hunks make it in? Whitespace changes? Remove those lines by right-clicking and unstaging.
git gui will also show you when you have trailing whitespace:
And if you have two lines that look identical, it’s probably a whitespace issues (maybe tabs vs. spaces?).
Once you’ve fixed all that, you’re ready to describe your change…
Writing a Good Commit Message
First of all, there are a couple of semantic rules for writing good commit messages:
- One sentence
- In the present tense
- No period
- Less than 80 characters
That describes the form, but just like you can have a valid program that doesn’t do anything, you can have a valid commit message that’s useless.
So what does a good commit message look like? It should clearly summarize what the change did. Not “changed X to Y” (although that’s better than just saying “Y”, which I’ve also seen) but why X had to change to Y.
Examples of good commit messages:
Show error message on failed "edit var" in shell
- Very nice “added feature”-type message.
Extra restrictions on DB name characters for Windows only
- Would have been nice to have a description below the commit line describing why we needed to change this for Windows, but good “changed code”-type message.
Compile when SIGPIPE is not defined
- Nice “fixed bug”-type message.
- I think this is the only case where you can get away with a 1-word commit message
Examples of bad commit messages:
- Doesn’t say what was added or why
Fix test, add input form, move text box
- A commit should be one thought, this is three. Thus, this should probably be three commits, unless they’re all part of one thought you haven’t told us about.
And once you’ve committed…
When you inevitably mess up a commit and realize that you’ve accidentally committed a mishmash of ideas that break laws in six countries and are riddled with whitespace changes, check out my post on fixing git mistakes.
Or just go ahead and push.