Tips for a disciplined git workflow February 25, 2019 on Drew DeVault's blog

Basic git usage involves typing a few stock commands to “sync everyone up”. Many people who are frustrated with git become so because they never progress beyond this surface-level understanding of how it works. However, mastering git is easily worth your time. How much of your day is spent using git? I would guess that there are many tools in your belt that you use half as often and have spent twice the time studying.

If you’d like to learn more about git, I suggest starting with Chapter 10 of Pro Git (it’s free!), then reading chapters 2, 3, and 7. The rest is optional. In this article, we’re going to discuss how you can apply the tools discussed in the book to a disciplined and productive git workflow.

The basics: Writing good commit messages

You may have heard this speech before, but bear with me. Generally, you should not use git commit -m "Your message here". Start by configuring git to use your favorite editor: git config --global core.editor vim, then simply run git commit alone. Your editor will open and you can fill in the file with your commit message. The first line should be limited to 50 characters in length, and should complete this sentence: when applied, this commit will… “Fix text rendering in CJK languages”. “Add support for protocol v3”. “Refactor CRTC handling”. Then, add a single empty line, and expand on this in the extended commit description, which should be hard-wrapped at 72 columns, and include details like rationale for the change, tradeoffs and limitations of the approach, etc.

We use 72 characters because that’s the standard width of an email, and email is an important tool for git. The 50 character limit is used because the first line becomes the subject line of your email - and lots of text like “[PATCH linux-usb v2 0/13]” can get added to beginning. You might find wrapping your lines like this annoying and burdensome - but consider that when working with others, they may not be reading the commit log in the same context as you. I have a vertical monitor that I often read commit logs on, which is not going to cram as much text into one line as your 4K 16:9 display could.

Each commit should be a self-contained change

Every commit should only contain one change - avoid sneaking in little unrelated changes into the same commit1. Additionally, avoid breaking one change into several commits, unless you can refactor the idea into discrete steps - each of which represents a complete change in its own right. If you have several changes in your working tree and only need to commit some of them, try git add -i or git add -p. Additionally, every commit should compile and run all tests successfully, and should avoid having any known bugs which will be fixed up in a future commit.

If this is true of your repository, then you can check out any commit and expect the code to work correctly. This also becomes useful later, for example when cherry-picking commits into a release branch. Using this approach also allows git-bisect to become more useful2, because if you can expect the code to compile and complete tests successfully for every commit, you can pass git-bisect a script which programmatically tests a tree for the presence of a bug and avoid false positives. These self-contained commits with good commit messages can also make it really easy to prepare release notes with [git-shortlog][shortlog], [like Linus does with Linux releases][linux-announcement].

Get it right on the first try

We now come to one of the most important features of git which distinguishes it from its predecessors: history editing. All version control systems come with a time machine of some sort, but before git they were mostly read-only. However, git’s time machine is different: you can change the past. In fact, you’re encouraged to! But a word of warning: only change a future which has yet to be merged into a stable public branch.

The advice in this article - bug-free, self-contained commits with a good commit message - is hard to get right on the first try. Editing your history, however, is easy and part of an effective git workflow. Familiarize yourself with git-rebase and use it liberally. You can use rebase to reorder, combine, delete, edit, and split commits. One workflow I find myself commonly using is to make some changes to a file, commit a “fixup” commit (git commit -m fixup), then use git rebase -i to squash it into an earlier commit.

Other miscellaneous tips


  1. I could stand to take my own advice more often in this respect. ↩︎

  2. In a nutshell, git bisect is a tool which does a binary search between two commits in your history, checking out the commits in between one at a time to allow you to test for the presence of a bug. In this manner you can narrow down the commit which introduced a problem. [shortlog]: https://git-scm.com/docs/git-shortlog [linux-announcement]: https://lkml.org/lkml/2019/1/6/178 ↩︎

Have a comment on one of my posts? Start a discussion in my public inbox by sending an email to ~sircmpwn/public-inbox@lists.sr.ht [mailing list etiquette]

Articles from blogs I read Generated by openring

Status update, August 2020

Hi! Regardless of the intense heat I’ve been exposed to this last month, I’ve still been able to get some stuff done (although having to move out to another room which isn’t right under the roof). I’ve worked a lot on IRC-related projects. I’ve added a znc-i…

via emersion 2020-08-19 00:00:00 +0200 +0200

What's cooking on Sourcehut? August 2020

Another month passes and we find ourselves writing (or reading) this status update on a quiet, rainy Sunday morning. Today our userbase numbers 16,683 members strong, up 580 from last month. Please extend a kind welcome to our new colleagues! Thanks for read…

via Blogs on Sourcehut 2020-08-16 00:00:00 +0000 +0000

Go 1.15 is released

Today the Go team is very happy to announce the release of Go 1.15. You can get it from the download page. Some of the highlights include: Substantial improvements to the Go linker Improved allocation for small objects at high core coun…

via The Go Programming Language Blog 2020-08-11 11:00:00 +0000 +0000

North Pacific Logbook

The passage from Japan (Shimoda) to Canada (Victoria) took 51 days, and it was the hardest thing we've ever done. We decided to keep a logbook, to better remember it and so it can help others who wish to make this trip.Continue Reading

via Hundred Rabbits 2020-07-31 00:00:00 +0000 GMT