/yags

The Last Git Branching Model You'll Ever Need

MIT LicenseMIT

Yet Another Git Strategy

The Last Git Branching Model You'll Ever Need

Key Benefits

  • Opinionated
  • Simplifies CI/CD
  • Supports Hotfixes
  • Good Tooling Support
  • Works with all sizes of teams
  • Improves Collaboration

Table of Contents

Overview

Graph

How It Works

We have one main branch in our Git-Repository called develop. This is our current development version, which is always deployed to our staging environment. All other branches are started off of this default branch. We also have a production branch. This is the code that is currently running in production.

Feature Branches

Generally, new code is written in new, short-living branches, however this model does allow for small and concise changes to be pushed directly into the develop branch. This is only acceptable if the changes are small or cosmetic, have already been tested and don't require a code review.

For all other code, you should create a new branch off of develop. These have a naming convention: <type>/<branch-name> (e.g feat/user-info-api)

$ git checkout develop
$ git checkout -b feat/my-new-feature

While working, track your progress in a draft (github) or Work In Progress Pull-Request (gitlab) and request a review from at least one teammate when you have finished your feature. When all checks pass (assuming you have set up CI/CD) you squash and merge the branch into develop (It's recommended to require a linear history and disable other merge types on your respective git host).

Commits

When commiting your code to these branches or develop, you also need to follow a naming convention (based on Conventional Commits):

  <type>[optional scope]: <description>

  [optional body]

  [optional footer(s)]
$ git commit -m "feat: add database user model" \
  -m "BREAKING: This changes some names in our rest-api"

Releases

Before releasing a version to production, it is recommended to sanitize-check your current staging environment — even if all tests pass. If you are confident, the next step is to (optionally) commit a version bump to develop:

$ git checkout develop
$ # bump your version to v0.1.0
$ git commit -m "chore: bump version to v0.1.0"
$ git tag v0.1.0
$ git push --tags

The final step then is merging this to your production branch:

$ git checkout production
$ git merge develop --ff-only
$ git push

Pre-Releases

Pre-Releases are just tagged development versions. To for example automate pushing your library to npm or similar, you need to add a release step to your CI/CD system that runs on every tag *-{alpha,beta}.*

$ git checkout develop
$ # bump your version to v0.1.0-beta.0
$ git commit -m "chore: bump version to v0.1.0-beta.0"
$ git tag v0.1.0-beta.0
$ git push --tags

Hotfixes

Hotfixes should be created as pull-request from a fix-branch directly to production. These can then be reviewed and squash-merged like normal branches.

$ git checkout production
$ git checkout -b "hotfix/fix-password-hash"

After a hotfix lands in production, a more elaborate fix can be created for develop or the fix can be cherry-picked:

$ git checkout develop
$ git cherry-pick 3af9286 # the commit sha of the hotfix

CI/CD

Continuous Integration and Continuous Delivery are crucial parts of YAGS. Depending on your setup, this can look very different, but the general recommendation is:

  • on every commit, anywhere: Run all tests and try to build
  • on every commit to develop: Deploy to your staging environment
  • on every commit to production: Deploy to your production environment

Commit/Branch Types

These add human machine-readable meaning to your commit messages and branches (based on the Angular Commit Convention / Conventional Commits)

  • feat - A new feature
  • fix - A bug fix
  • chore - Changes that don't affect any code, e.g. releases
  • build - changes in the build system
  • docs - Documentation
  • style - Cosmetic code changes
  • refactor - A code change that doesn't fix/add anything new
  • perf - A code change that improves performance
  • test - Adding or correcting tests

Recommendedations

Tools

While this git strategy will work with any combination of build/test tools, these can serve as a good starting point for new projects

NodeJS/JavaScript/Typescript

  • Pre-Commit Hooks with Husky
    • one hook running your tests
    • one hook running commitlint
  • ESLint for linting TypeScript/JavaScript code (optionally with my eslint preset)
  • release-it with @release-it/conventional-changelog and github releases enabled

Opensource Projetcts

These are some recommendations specifically for opensource-projects. They don't really have a lot to do with this strategy but could be helpful.

Inspiration

I've been heavily inspired by Trunk Based Development, the GitHub Flow and the GitLab Flow. With YAGS, I've aimed to take the best Parts of all of these and create a lightweight, opinionated and very practical alternative.