On committing well

39
On Committing Well James Aylett

Transcript of On committing well

Page 1: On committing well

On Committing WellJames Aylett

Page 2: On committing well

What is a commit?

Changes

What they were based on (parent commits)

Message

Author (& optional committer), timestamp

A name (SHA)

Page 3: On committing well

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)

Page 4: On committing well

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)

Page 5: On committing well

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

Page 6: On committing well

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

Page 7: On committing well

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

Page 8: On committing well

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

Page 9: On committing well

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

Page 10: On committing well

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

Page 11: On committing well

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

Page 12: On committing well

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

Page 13: On committing well

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

Page 14: On committing well

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

Page 15: On committing well

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

Page 16: On committing well

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)

Page 17: On committing well

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)

Page 18: On committing well

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)

Page 19: On committing well

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

Page 20: On committing well

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)

Page 21: On committing well

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)

Page 22: On committing well

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?

Page 23: On committing well

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)

Page 24: On committing well

How about some examples?

Page 25: On committing well
Page 26: On committing well

Too terse !

Relies on the link to the github issue. !Better to be more specific here: !De-emphasise short utterances in search results

Page 27: On committing well
Page 28: On committing well

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.

Page 29: On committing well
Page 30: On committing well

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.

Page 31: On committing well
Page 32: On committing well

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.

Page 33: On committing well
Page 34: On committing well

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.

Page 35: On committing well
Page 36: On committing well

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.

Page 37: On committing well
Page 38: On committing well

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

Page 39: On committing well

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)