Use Git and Markdown to Store Your Team’s Documentation and Decisions

Do you sometimes feel like Bill Murray in Groundhog Day? Reliving the same day over and over again? I sure feel like that in some discussions with my team: revisiting the same discussion multiple times, because we fail to document decisions properly. Redrawing that diagram one more time, to come to the same conclusion. Searching for that one document in your email? Sifting through several versions of the same document, not sure which version is the latest? 

Next time around you can avoid these situations, using simple tools that your team is already using: Git and Markdown. Add Architecture Decision Records into the mix to capture the important decisions and the context in which those decisions were made.

Documentation should be an artifact of your software development process

Documentation can only add value if everybody knows where to find it and can edit it easily. For development teams that means keeping the documentation as close as possible to the source code. Putting both in the same version control repository instantly makes sure everybody knows where it is and how to edit it. The most often used solution for version control is Git. The Stack Overflow Survey of 2018 reported that 87.2% of the developers consider Git their favorite version control system. It is a powerful, distributed version control system, developed with speed in mind. Perfect to keep track of changes in your documentation, as Git keeps a record of who changed what and why.

Storing both code and documentation together allows the team to treat the code as documentation and supplement where necessary with documentation as code. Meaning all code should be self-explanatory as much as possible, but when additional documentation is necessary, you treat your documentation as an artifact of your software development process. Just like the code, documentation is under version control, written in plain text and subjected to code reviews.

You already have all the tools you need

The most often used tool to write documentation in plain text is Markdown. All major software development tooling, such as Gitlab, Azure DevOps & GitHub, support Markdown files nowadays. Markdown is a lightweight markup format, that converts easily into web pages. You might have seen it as a file in one of your repositories. However, it can also be used to document other aspects of your application. Because the files are stored in Git as plain text, it is easy to include documentation changes in your merge requests. The web interface of your Git repository will automatically convert the Markdown format to a nicely formatted page for everyone to read. Nothing is keeping you from starting right now, the tooling is already present, all it takes is one text file!

Getting it right

Finding the right level of documentation for your team can be quite a struggle. The Agile Manifesto calls for working software over comprehensive documentation, which is often wrongly interpreted as not having any documentation at all. There’s a lot of wiggle room between “no-documentation-at-all” and “everything-documented-to-a-tee”. Lightweight, easy to maintain documentation is the sweet spot you should aim for. Avoid going too heavy on the details, as keeping everything up to date will become a burden as your documentation grows. Include too little details and your documentation will not add value.

Architecture Decision Records (ADR) is a technique to help your team document decisions made. It is originally intended to record architecture related decisions, but I’ve had good results documenting a wider range of decision types. ADR provides a template to motivate to your future self why certain decisions have been made. In a Markdown, you clarify which options have been considered and why the chosen option appeared to be the best at that point in time. You include the goal you were trying to achieve and any negative side effects you consciously accept by choosing this option. 

“In the context of <use case/user story u>, facing <concern c> we decided for <option o> to achieve <quality q>, accepting <downside d>.”

Consistently expand the collection of decision records in your project and this collection grows to become a valuable source of information for the developers that may join your project after you. They can use it as a sensemaking tool for the code base, to figure out why things evolved as they did. We’ve all been in situations where the inherited code made no sense; Architecture Decision Records can help you navigate those kinds of situations with more confidence.


  • Install a Markdown extension for Visual Studio Code to get a live preview right in your editor.
  • Make sure to add or adjust documentation for each user story. Add a check to your team’s Definition of Done as a reminder if necessary. 
  • Consider using Behavior Driven Development, to reduce the manual effort involved with updating documentation and use your acceptance tests as living documentation.
  • Start with recording your decisions and don’t get hung up on the tooling around ADR. Starting is far more important because, in the end, it’s just a bunch of text files!
  • Non-technical people may struggle with Git, pair with them to teach them how to use Git. Alternatively, you can show them how to create branches through the UI and edit the documentation there. As a result, everybody can contribute and the documentation can still be reviewed. All Git repositories with a web UI support this workflow.
  • Looking to migrate existing documentation to Markdown? Have a look at the Pandoc project, it can convert between many different file formats, including Word.

How Do You Know Something Is A Bug? – Using Mental Models and Oracles in Testing

Did you ever find a problem of which you weren’t sure it was a bug? You probably thought it over, looked up the requirements or discussed with a team member. Perhaps you figured it out by yourself, the requirements made things clear or your team member could help you out. Either way, you needed some source of information to recognise the problem as a bug. You used your mental models and oracles.Read more →

Migrating App Engine to Go 1.11 – the price of vendor lock-in

If you are using App Engine on the Google Cloud Platform (GCP) you shouldn’t be too surprised when receiving an email stating the current version you are using is being deprecated. Chances are you haven’t read Google’s deprecation policy, which also applies to App Engine (listed here). which basically states that if Google decides to upgrade their services and deprecate older version, they can. And will. And you will be forced to follow along.

So of course, the email which came on June 27, 2019 should not have come as a surprise to you:

Hello Google App Engine Customer,

We’re writing to let you know that Go versions prior to 1.11 are no longer supported on App Engine, and new deployments using these language versions (1.6, 1.8, and 1.9) will not be available starting October 1, 2019.

This left about 3 months to upgrade.

Read more →

Where to begin when joining your first Scala Spark project

Man, Apache Spark is some powerful stuff! Add a fancy and fun language called Scala and you feel like you can do a whole lot of cool things with a lot of flexibility! This is my current standpoint on the subject, after a short year of working with this setup. The first month was a completely different story. Let me share some tips that really helped me out when I started working on an existing Scala-Spark codebase.

Read more →

Quality pattern 1: Treat your acceptance criteria as tests

This is the first blog in the series after my last week’s introduction to the five quality patterns in Agile development, to deliver the right software with great quality. This blog is about a pattern that I think is absolutely necessary for a team to accelerate, deliver with quality and keep on doing this over time as an application expands. Your acceptance criteria should be your tests. That sounds simple enough, but it’s often not the case. By changing the way you refine stories your acceptance criteria can become your tests as well. Let me guide you through it.

Read more →

Start with GraphQL today by converting your Swagger schema

Swagger-to-graphql allows you to generate a GraphQL schema given a Swagger (OpenAPI) schema. It avoids the need to code a GraphQL schema so you can get started with GraphQL quickly. It can run in your datacenter using NodeJS, but it also runs in the browser for experimentation. That means you can try it online with your own schema. There are also public Swagger schemas available in the OpenAPI directory.


Read more →

Using metrics to find the pain points in a legacy codebase

When you are new to a codebase, you may realise that it’s new for you, but not new to the world. It’s code that has been around for ages and is hard to change, it’s hard to maintain. This is legacy code by definition, and it’s your job to work with it. Even if code hasn’t been around for long, or if it was perfect when the project started, it easily gets worse over time. I see it as the second law of thermodynamics, which says that the entropy of an isolated system does not decrease over time, but evolves towards an equilibrium of maximum entropy.
The entropy – or disorder – of large, badly tested classes which we are asked to change. In this post, I will explain how I like to approach such a codebase. Is it hopeless? If not, where do we start cleaning it up?

Read more →

Five quality patterns in Agile development

In this blog series, I’ll discuss five quality patterns in Agile development to deliver the right software with great quality.

For years now companies have been adopting Agile ways of working and mostly the Scrum framework as their way to develop software. Scrum is all about working in dedicated teams on small increments of working software. Software that can potentially be released every single sprint. I’m sure you agree with me that this means that this software is therefore always tested every sprint as well. How could we otherwise release it right? This blog is about a trend I have noticed in a lot of companies that after time teams have more and more issues delivering quality software that conforms to business requirements.

Read more →

Share This