Some version control best practices you might want to follow. (Up to you, though.)
Version control isn’t just process for process sake. It ensures that the work you—and your team members—do is consistent, high-quality, and productive.
If you don’t follow version control best practices, you may frustrate your fellow developers and also make it:
- Harder to roll back changes that break your builds,
- More difficult you and team members to understand why changes were made in the first place, and
- More likely that your code’s organizational integrity will suffer.
All of these things will slow you and your teammates down and delay the delivery of value to your end users.
In short: If you don’t follow version control best practices, your development pipeline will be a hot mess. As apps get more complex and receive more feedback from users, these best practices ensure that you’re collaborating and shipping as efficiently as possible.
Here, we’ll take a look at eight version control best practices that developers need to follow. Memorize and practice these and your fellow developers will thank you.
1. Use a Version Control System
You can't really implement any best practices if you're not using a VCS —distinct, remote server backup for your app—to protect your project from conflicts, computer crashes, and data loss.
A VCS makes it easier to integrate work done by different members, allows multiple developers on your team to work on an app at once, and enables the reference of historical project information.
Additionally, a VCS can be used to protect important app assets, including:
- Intellectual property such as source code for customer and internal apps
- Product designs that multiple developers will consult when building code
- Export or compliance documentation that needs to be available for reference in a central location
- Videos, graphics, and images created by your team to be used across your builds
- Business documents for stakeholder and developer reference
Tip: Make sure you commit semantically to your VCS to avoid filling up the server with unrelated files from your local computer.
2. Break Up Commits into Related Changes
You should break up commits into smaller, related changes so it’s clear what bugs or features you’re fixing or adding. This makes it easier for your team members to review your code and reverse changes if it breaks the build later.
If you don’t break up your commits into smaller chunks of related changes, it will be harder for you and your team to clearly understand the purpose of each commit and walk it back if it creates errors later on. By following this best practice, each distinct change you make to your codebase will match to a new version number that can be referenced later on if needed.
When you commit, break up your commits by purpose (i.e., one commit per bug fix, infrastructure task, refactoring task, or user-visible change).
For example, say you’re working with features 1, 2, and 3 and fixing bugs A, B, and C within them. This should result in at least six distinct commits.
Additionally, commits should be done atomically, meaning that all files related to your commit are sent together so your reviewers and team members don’t have to hunt down additional information to make it work.
3. Commit Often
Commit often to break down how much work you need to do between commits and make it easier for your team members to review your code. If you don’t follow this best practice and instead commit large, infrequent chunks of code at once, it’ll be harder for you and your team to see, detect, and fix conflicts. Kind of like trying to find a needle in a haystack.
As a rule of thumb, don’t commit more than 400 lines of code, and limit your changes to one purpose per commit (see best practice #2). Smaller, frequent commits make it easier and faster for your team members to review your code and integrate changes.
Additionally, by following this best practice, merge conflicts are less likely to be missed and cause problems later.
4. Write Clear Commit Messages
Write clear commit messages so you—and your fellow developers—will have the details needed to understand why a change was made and what it does. If your commit messages are too short, unclear, or absent altogether, it’ll be harder for your future self and your teammates to understand the purpose of the work you did.
Your commit messages should be a max of 50 characters and separated from the body of your code by a blank line. Each time you commit, focus on answering two questions in the accompanying message:
- Why was the change made?
- How does it differ from previous versions?
Additionally, use the present tense so that your notes match the generated messages from commands like git merge.
Finally, make sure to include the issue ID, requirement ID, or JIRA ticket.
5. Adopt, Then Follow, a Branching Plan
Work with your team to adopt and then follow a branching plan to track different lines of development, avoid merge conflicts, prevent overwriting of existing changes, and avoid lost updates.
There’s a lot of discussion around what branches are, why they matter, and what strategy is best. For our reference here, a branching strategy is a set of rules that describe:
- When developers should branch
- What branch they should create new branches from
- When branches should be merged back together
- Which branch they should ultimately merge back to
If you don’t follow an agreed-upon branching strategy, you end up with a Wild West of commits: developers branch at random when they feel it's appropriate, new branches are created from many older branches, and there isn’t an agreed-upon point that said new branches should be merged back to. Basically, it’s chaos.
Instead of cultivating chaos, sit down with your team and get familiar with git workflows. Then, decide which one you all prefer, and commit to following that branching plan moving forward.
6. Avoid Commits with Incomplete Work
Test and review before you commit to make sure your code works as expected and doesn’t conflict with other changes made by other developers (or your past self). If you commit incomplete work to your team members, it will basically function as an inside joke: the code makes sense to you, but other developers won’t be able to understand it because it relies on local, personal information.
To avoid committing incomplete code, make sure to finish the work you start before leaving for the day. Additionally, don’t commit code just because there’s something in your local repo or because you need a clean working copy to start new changes.
If you can’t finish a task before leaving for the day or working on something else, use git’s stash feature to save incomplete work.
7. Test and Review Before You Commit
Test and review before you commit to make sure your code works as expected and doesn’t conflict with other changes made by other developers (or your past self). If you don’t do this, you’re playing Russian roulette with your changes, and no one will know if it works or not until it fails.
Instead, review your commit before merging into a shared repo by submitting changes for code review or as a pull request. Doing so ensures that a new set of eyes can check it for conflicts and makes your team more aware of the changes that are happening around them.
This increased attention to code quality and changes will result in a higher quality of code and increase efficiency by allowing for code reuse.
Tip: Include code formatting with linters, a tool that analyzes source code, to ensure reviews and tests are comprehensive.
8. Make Sure Commits Are Traceable
Make sure commits are traceable so you and your fellow developers can easily reference them later on if related changes come up or if your change needs to be undone and reanalyzed.
If you don’t follow this best practice, it will be difficult for your team to find the change causing issues if the build breaks later, ballooning cycle times and frustrating people along the way.
To improve security and auditing ability, store the author of the change and additional information, such as review comments, with the commit. By doing so, you or another developer will be able to pinpoint the code’s origin later on if it causes issues in testing further down the line.
Follow Version Control Best Practices to Save Your Skin and Your Code
Version control doesn’t just ensure that your code is clean and ships fast; it’s also a good way to CYA. If you dutifully follow these best practices, you help ensure good code hygiene (and also make sure your teammates don’t hate you).
Version control best practices are your insurance against messy, difficult-to-follow code and against hours wasted in the future hunting down the source of problems.
If you’re ready to integrate these best practices into your development flow, check out how Shortcut uses clojure.spec, Datomic, and webhooks to integrate with version control systems. And then use one of our VCS integrations to connect GitHub, GitLab, or Bitbucket to Shortcut.