Using Solid Git Repository Workflow
Have you ever been in a situation where you made incorrect changes to the main branch, ended up breaking the production, and then messed up the entire Git history? Me too. To never have to deal with that again, check out this blog post on some best practices I've come to rely on related to Git workflow configuration.
Git is a standard versioning tool in software development. You can also consider it a ‘free and open source distributed version control system, designed to handle everything from small to large projects with speed and efficiency’. The software is used for:
“…tracking changes in any set of files, usually for coordinating work among programmers collaboratively developing source code during software development. Its goals include speed, data integrity, and support for distributed, non-linear workflows.” - Wikipedia
Once you are familiar with how Git works, you will eventually realize that there are quite a few commands that are possible to use in the wrong situation. To prevent such mistakes from happening, let’s configure your Git repository for a more protected workflow.
Protected Branches and Merging via Pull Requests
The most basic rule to you should abide by is disabling direct push to any branches that are configured for releases (such as main or staging). The alternative is to implement new changes in the feature branch and merge them via a pull request. This approach forces you to do one extra check - at least a quick visual one - in order to end up with a much more solid implementation.
You can configure such protected branches in the Git remote provider settings, GitHub or Gitlab. for example. A typical protected branch rule can look like this:
Branch name: main
Allowed to push: No one
Allowed to merge: Maintainers
Protected branches are relevant even when the repository has only one contributor. The rules should apply for all team members regardless of the role in a team, expertise, etc. It is easy to forget to check out the new feature branch. I tried to push to the wrong branch several times because of that.
Require Rebase Before Merge
Imagine working on a project with multiple team members. In this situation, a person can release new changes to your target branch at the same time you are working on changes in your own feature branch.
By default, Git allows you to merge these changes from the outdated branch, as long as there is no conflict. However, ‘no merge conflict’ does not mean ‘working implementation’. Merging in this way is not considered a safe approach because tests were not using your code in combination with the latest version. A solution for this problem is rebasing:
$ git rebase origin/main
By rebasing before you do a code review, you are making sure to compare any changes made with the latest version. You could also see this as a way of wanting to add new changes without mixing them.
Clean Git History Log
Having a clean Git history log is also a fundamental aspect of having a protected workflow. This is because sometimes new releases can contain a bug, even with a code review process and solid test coverage present.
Usually, the situation becomes apparent when something stops working. At this point, it is helpful to go through the latest changes and then identify the commit with the source of the issue. You should be able to revert the commit until a fix can be provided. It goes without saying that it is much easier to make this type of change when your Git history log is well-structured.
The first general rule for a well-strutted Git history log is to have well-sized commits (the smaller the better), all of which are ready to release. In other words, tests or required refactoring should always be part of commits containing new features.
Besides that, spend time on the commit message name. The name should describe changes well, and ideally, there should be no need for additional commit description information. It is also possible to introduce a strict commit message format, such as Conventional Commits. This format allows you to automate managing your product version and changelog.
- fix: delete subscription when it is processed
- feat: automated subscription processing
- refactor!: subscription request body structure
- feat: exports API
The takeaway here is that if you are able to spend just a few minutes on setting up a solid Git workflow, you will end up preventing hours of issue-fixing down the road. For example, the protected branch configuration takes about five minutes in GitHub - but would take many more minutes to repair.
Are you interested in working with things like Git repository workflow? Feel free to send us an email at firstname.lastname@example.org or check out our careers section for available developer positions!