Skip to content

Tools for development

Git is our preferred version control system for managing code changes. We use Git to collaborate on projects, review code, and maintain a revision history of all changes.

To use Git effectively, we follow these best practices:

Create a new branch for each feature or bug fix

Section titled “Create a new branch for each feature or bug fix”

Create a new branch for each feature or bug fix, and merge it back into the main branch only after testing and review. This helps keep the main branch stable and avoids conflicts with other developers’ work.

We’re not super prescriptive on commit message format, but if you want to follow a standardised format, consider the Conventional Commits style. It uses a standardised format for commit messages that includes a type, scope, and subject. For example, a commit message might start with “docs: update README with new information” or “feat: add new feature to user profile page”.

Regularly push changes to a remote repository

Section titled “Regularly push changes to a remote repository”

Regularly push changes to GitHub to ensure that your work is backed up and accessible to others on the team. This also helps avoid loss of work due to hardware failure or other issues.

Open a pull request for every change, however small. See Reviews for how a PR gets checked before we merge it.

By following these guidelines, we can work together effectively and maintain a high standard of quality for our codebase.

A good revision history is essential for a project. It’s a valuable resource for understanding why the code is the way it is. If you spend time on your commit messages, it can make all the difference for future developers who look back on the project’s history.

Try not to be expedient with your commits. The first step to writing a good commit message is to give yourself the space to express your thoughts properly. This means that you should not try to cram your commit messages into a single line. This will give you sufficient pause for thought to allow you to ask yourself if the commit message is fit for purpose. Adios, git commit -m "Fix bug" commits.

Use Git’s patch option to pick out atomic commits

Section titled “Use Git’s patch option to pick out atomic commits”

The patch option lets you selectively choose the exact changes in a particular file that you’d like to stage. This is helpful when you want to commit only part of a file’s changes.

  • Use git add -p to interactively stage changes to a file and create atomic commits, making it easier to track changes and simplify the review process.

Until a commit is merged into the main branch, it can be modified or even deleted. Use the amend option to modify the most recent commit or create fix-up commits and squash them down with an auto-squash during a rebase.

  • Use git commit --amend to edit the message of a specific commit and commit --amend --no-edit if you don’t need to edit the message.

Use rebase to restructure commits before pushing

Section titled “Use rebase to restructure commits before pushing”

Let’s say you have a feature branch ready to push. You check the Git log and see that you have some poorly written commits, a reverted change, and two commits that straddle another that ought to have been committed together. You’re in rebase territory.

Use git rebase -i <commit> (e.g. git rebase -i HEAD~5 to rebase the last 5 commits) to interactively rebase the commit history and restructure commits, such as changing commit messages, squashing commits, and reordering commits. Use the options pick to keep a commit as-is, squash to combine a commit with the previous commit (up), and edit to stop at a specific commit for further changes. You can cut and move lines to re-order the sequence of commits too.

  • Don’t be afraid to try rebase. You can always use git rebase --abort to cancel it if you come unstuck.
  • Keep an eye on the helpful feedback from Git on how to use rebase properly.

Use Git’s pickaxe option to search through revision histories for any snippet of code across multiple commits and files. Git annotate can also be used to identify the last revision on a particular line.

  • Use git log -S <term> to search for changes that add or remove a specific term from the codebase.

Use GitHub for all code, whether public, private, or for a client.

We use Linear for tickets. See Ticket statuses for how we track a ticket’s progress, and Writing tickets for what goes in one.

We use GitHub Actions for continuous integration. See how a PR gets checked for what CI runs on every pull request.

Every project reports test coverage in CI. We aim for 85% code coverage, though this depends on the project. A pull request shouldn’t lower coverage.

Turn on Dependabot for every project. It opens pull requests to keep library dependencies up to date. That’s good practice, and dependency management is part of what we offer clients who pay for infrastructure support. Dependabot does this across all our projects, so nobody has to remember to.

GitHub’s Dependabot quickstart explains how to set it up.

See Port forwarding tunnels (this information is not public).