Photo by vision webagency on Unsplash (Edited)

Laying out a git repository

How organises projects as well as why we do it in that way

Version control is one of the more fundamental pieces of software development. It allows developers to navigate through a projects history to understand who implemented each change, as well as why they did so. It is an invaluable tool for use while understanding any given issue.

  • branches
  • tags

Existing Standards

Defining a standard for how a project should be laid out is hardly a new endeavour. There is:

Determining the boundaries of a repository

There are usually many different components of a project that need to come together to have that project user facing and doing useful work. Things like the:

  • Infrastructure
  • CI/CD
  • Artifacts
  • Documentation
  • Replacing the existing application in production with the new application
  • Rolling back the application to its previous version in the case of failure
  • Creating testing environments

Democratised project tooling

Even though things such as Docker or CI/CD may require specialised knowledge that the application developers do not have any reason to learn, by seeing those changes in the same place and subject to the same standards as other parts of the application those developers get a better understanding of their own project lifecycle. They can use that knowledge to decrease the time required to understand and resolve issues that are associated with any changes in that process, such as configuration changes in CI/CD breaking asset compilation in the application.

Single view of changes

When understanding how and when a bug was introduced into a service the fewer places we must look and correlate the change the faster we can find and resolve the issue.

Coordinated Changes

There are times in which an application change and a configuration or environment change must happen at the same time. Examples include:

  • Newly exposed application configuration
  • A new application feature that requires a system library

The Standard

The standard is derived from the requirements as above. The directory layout is as follows:

$ tree .├── bin
├── build
│ ├── ci
│ └── container
│ ├── Dockerfile
│ └── etc
├── deploy
│ ├── ansible
│ │ └── playbook.yml
│ ├── docker-compose
│ │ ├── docker-compose.yml
│ │ └── mnt
│ │ └── app
│ └── helm
├── docs
├── LICENSE.txt
├── README.adoc
├── src
└── web
14 directories, 5 files


├── LICENSE.txt
├── README.adoc
├── .drone.yml
├── .arclint
  • README.adoc: Some basic description about the project
  • .drone.yml: The task runner / CI configuration for the project
  • .arclint: Configuration for the Arcanist lint runner


└── build


└── build
└── ci


└── build
└── container


└── deploy


└── deploy
└── helm
├── Chart.yml
├── templates
└── ...
  • The deployment definitions
  • The deployment definition configuration
└── deploy
└── helm
└── service-a
├── Chart.yml
├── templates
└── ...
└── service-b
├── Chart.yml
└── ..,


└── deploy
└── ansible

Docker Compose

└── deploy
└── docker-compose


└── docs


└── src


└── web

In Conclusion

Our tools shape our conceptual model of a project. When developing keeping things consistent reduces the amount we need to investigate given each different project before we can start diagnosing issues or adding features to that project and adopting a single project layout keeps things as consistent as possible. The things included in a git repository in projects are all the things that are needed to deploy a project to users or subsequently change that project’s behaviour, given consistent underlying infrastructure. The layout is fairly straight forward but is subject to iteration, and has thus been pushed to GitHub. Hopefully understanding how we structure projects will give you some guidance on how to structure your own projects, or invite questions as to whether your projects are currently structured to maximise clarity and consistency in your team.