5 Git Best Practices
By: Cam Dziurgot
Tags: Coding, Best Practices, Git, Project Management, Software

Git is arguably the most popular source control system for current software development. Once a project and team begins to grow, how the repository holding its code is maintained can start to affect the efficiency of the development.

Photo by Vlad Hilitanu on Unsplash

These best practices will help keep repositories clean, help resolve any issues before they arise, keep the technical debt for projects to a minimum, and make project tracking easier and more accessible for the teams as they grow.

1 . Tagging and Versioning with a CHANGELOG

Once a project starts developing more features, you need to start tagging your releases. Many teams now are releasing new code every two weeks, some more ambitious teams will have daily releases. As code is going out, having a structured tagging system and a CHANGELOG will make it easier for everyone to know what has changed in the project. The alternative is going through a history of commit logs. Tagging also give a team the ability to roll back to previous versions.

There are a lot ways to tag code. A standard many projects follow is SemVer versioning; more details here. Semantic Versioning is where you keep a MAJOR version digit for breaking changes in the application, MINOR version for changes that are small features that you don’t expect to break any existing functionality, and a PATCH version for small changes and bug fixes.

Along with SemVer, CHANGELOGS help keep team members up to date on what has changed with each release. This makes it easier for team members to switch off a project for a couple of months, then come back on and get up to speed quicker. It also helps with anyone that might be using your application or project in their own work. A standard to follow for keeping a CHANGELOG can be found here.

2 . Using a Branching Strategy

As feature development starts spanning months and weeks while small features are pushed to production, having an agreed upon branch strategy for development becomes crucial. For many teams developing under a Continuous Integration model, a popular strategy is Git Flow (documentation here).

Git Flow process

Git Flow is popular among teams that run Continuous integration and need constantly develop new features over several weeks while dealing with bug fixes that need to go live immediately. You have a master/main branch the code is kept in that is when development work is finish. Feature branches are made off that development branch and then merged back into the development branch once the features are finished. Then when a release is happening, development branch s merged into master, tagged and deployed into a testing environment, then to a production environment.

When bugs need to be patched immediately in production, a hot fix branch can be made off the master branch, code changes can be made, merged back into master, tagged, and deployed to production. Then master is merged back into the development branch.

3 . Utilizing a .gitattributes file

A few advantages to attribute files is no none sense diffs when updating images files. Another advantage is when a team has members using different operating systems, End of File characters can vary. When a small change is made in a file, a diff can show up that every line is changed.

Another advantage is not tracking the diffs in images or other files that are binary. Below is an example of a .gitattributes file pulled from GitHubs Help section.

# Set the default behavior, in case people don't have core.autocrlf set.

* text=auto



# Explicitly declare text files you want to always be normalized and converted

# to native line endings on checkout.

*.c text

*.h text



# Declare files that will always have CRLF line endings on checkout.

*.sln text eol=crlf



# Denote all files that are truly binary and should not be modified.

*.png binary

*.jpg binary

4 . Utilizing a .gitignore file

The reason for maintaining an ignore file is mainly to make sure your repository is not polluted files that aren’t needed; build files, dependencies, log files, and generally files that you or your team do not actively maintain. GitHub maintains a repository with a list of different .gitignore templates that can be used depending on the code base and project type, here.

5 . Set Coding Style Standards

Coding style may seem insignificant to projects, and could be considered a general project best practice, not just a git repository best practice. Either way, as teams grow, style differences begin to become more noticeable. The changes can start to show up in the same files, making code harder to read.

All the code in a project should look like a single developer wrote it.

There are a few different ways to keep coding standards. One is using a .editorconfig file. An EditorConfig uses plugins with various IDEs in order to automatically apply code styling when the file is saved. These styling rules that can be automatically applied can be how tabs are saved, number of spaces of tabs, and max line length.

Another method is using a linter. A linter is used to statically scan your code base for a set of rules. These rules can be set to look for specifically styling, like how putting the bracket of an if statement on a new line. Or rules can set coding best practices like not allowing fall through cases in switch statements. Here is a list of linters that can be found for various languages on GitHub.

Conclusion

These best practices will help teams as they grow, and as projects and code bases expand. Whether it is making code reviews clearer, or easier to find the source of a bug, using a few best practices can help a team move faster and avoid technical debt. Good luck implementing these best practices, and happy coding!