Using git as a one-person dev team is a lot different than when you have a handful of developers. With just one person, you really just need to make sure you're leaving yourself a decent trail of commit messages in case you need to roll back when you break something. As soon as you have two or three people on your dev team though, git becomes a much more powerful tool...if you use it correctly.
In the past couple months (since Rob Hameetman joined the team), we made two big improvements to our git strategy. In this blog post, I'll detail these improvements and give you some of the problems we were hoping to prevent in implementing them.
1. A branch naming strategy
As soon as Rob joined, we started using a strict git flow, but we didn't have any accepted strategy for naming our feature branches. Rob brought up the idea of implementing a standard naming schema for branches to help other developers see at a glance the motivation and nature of each in-progress branch.
This naming schema includes the name of the developer who owns the branch, the type of work being implemented, and a short summary of the feature. While this leads to rather long branch names (bash autocomplete helps here), it also makes branch names very descriptive and lowers the likelyhood that someone will do work on the wrong branch or accidentally make a pull request they didn't mean to. I find it very helpful when looking through all the branches I have locally as I often have lots of old ones sitting around before I remember to clean them up.
Here is the documentation Rob wrote for our new naming strategy:
- master: Always ready to be deployed. Merged weekly in release cycles.
- develop: This is the main branch off of which you should make new branches.
Our schema for naming our branches is developed with deep thought into existing philosophies on the subject and the nature of our work. The best way to organize branches across teams is to use "grouping tokens" with / separators.
Top-level branches- by which we mean branches that are based off of develop- follow a standard format which prioritizes a single responsible person for each branch. As such, the format is:
This will always be your name, even if you are not the person on the relevant Trello kanban card. This should usually just be your first name unless you need to clarify in order to avoid confusion.
A predefined type that establishes the nature of the work being done. A type may be one of the following:
- docs - Documentation
- ops - DevOps (Anything that affects the deployment pipeline. This includes commits for writing new tests.)
- feat - Features
- fix - Bugs
- exp - Experiments (Try to keep an eye on these and close them out if they get too old.)
A short (one or two words, if possible) description of the task. When using multiple words, be sure to use kebab-case. You don't want the length of these to get out of hand so try to be as concise as possible. Our suggestion is to keep it to one or two words, but not more than five or six.
Child branches follow a schema similar to XPath node query syntax (i.e. /parent/child/grandchild/etc) buffs out there ). The schema for this is:
Example 1: Joe is tasked with fixing a bug in the Assignments API whereby the Graider Reported Average Paper Length is including skipped students. The proper branch name for this would be joe/fix/skipped-students.
Example 2: Joe solved the problem but stormed out and quit when his build failed. Erin takes over to make the necessary changes so that the build succeeds. She starts by making a child branch of joe's branch. The proper name for her branch would be erin/fix/skipped-students/passing-build
Example 3: Tom notices that Erin's docblocks are not formatted consistently and decides to fix it. The proper branch name for this may vary depending on the circumstances. If Erin did not destroy her branch after merging, even though the nature of Tom's change has to do with documentation, the proper name for this branch would betom/fix/skipped-students/passing-build/docblock-formatting. If Erin's branch no longer exists, Tom would branch off of Joe's branch. Thus, the proper name would instead be tom/fix/skipped-students/docblock-formatting. If, however, Tom notices this too far into the future and Joe's branch is merged, only then would the proper name for his branch be tom/docs/docblock-formatting.
2. Pull request checklists for reviewers and reviewees
A couple years ago, Github released a pull request template feature that is really helpful when working on a repository with many different contributors. I also got a little obsessed with checklists a few years ago when I read Atul Gawandee's Checklist Manifesto, so I really liked the idea of bringing this into our PR workflow.
Unfortunately, we're using Bitbucket to host our private repositories, and they have decided not to implement this feature. While we may eventually migrate to Github, that's a lot of work, and not really a high priority yet, so we found a Chrome extension that does the same thing.
We created two checklists - one for the developer making the pull request and one for the reviewer of the pull request - to fill out during the review and merge process. The goal with these checklists was to minimize the risk that something would slip through the cracks and prevent developers from getting sloppy when reviewing PRs. We also hoped that this would force developers making PRs to double check things before they passed their code on to a team member, and so far it's been really helpful.
Both checklists are open source and currently available on Bitbucket snippets, but I'll include them as they stand today below:
- Add a link to the relevant Trello card(s) and move the card into the "Testing" column.
- Add appropriate unit and integration tests.
- Plan for any Ghost Inspector tests (to be added after merging).
- The CI has passed (check Codeship).
- Manually check any new or changed functionality.
- Manually check for accessiblity issues using WAVE.
- Update/create any ADRs or API documentation if needed.
- Attach a reviewer and included important notes in comments.
- Manually check any new or changed functionality.
- Unit and integration tests are sufficient and passing (check Codeship).
- Ghost Inspector tests are planned if required.
- Relevant ADRs and API documentation are updated.
- Questions or feedback have been left in the comments.
- Questions about code quality and improvements have been sufficiently addressed.
- When merged, move the Trello card(s) into the "Develop" column.
While our needs are still pretty minimal and our team is still tiny, in my experience, laying a good foundation for version control and change management are critical steps to building a strong engineering culture. These two improvements will likely change as our team does, but we feel they give us a strong push in the right direction.
What special tricks or tools does your team use for git? Let me hear about them on Twitter.