# git-graph: a terminal git history graph that follows your branching model

> git-graph is a Rust command line tool that draws a git history graph in the terminal and arranges it according to a named branching model, such as GitFlow or GitLab Flow, or one you define yourself in a TOML file. The point is not a prettier log, it is a graph that matches how your team actually branches.

**git-bahn/git-graph** — Command line tool to show clear git graphs arranged for your branching model

- Repository: https://github.com/git-bahn/git-graph
- Stars: 996 · Forks: 58
- Language: Rust
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/git-bahn-git-graph

## The graph is arranged, not just drawn

Most git history graphs answer the question of what happened. git-graph tries to answer a different one, which is how the history should be read given the way your team branches.

The tool is described as a command line tool to visualize Git history graphs in a comprehensible way, following different branching models. The project ships a comparison image showing the same history rendered by git-graph and by other tools and git clients, using the GitFlow model, and it says plainly that GitFlow was chosen for its complexity. Any other branching model is supported, including user-defined ones.

That framing explains the feature list. You get structured graphs directly in the terminal, pre-defined and custom branching models with their own colouring, different styles including an ASCII-only style with no special characters, and custom commit formatting in the same spirit as the format option of git log.

The ASCII-only style is a small detail with a real audience. Terminal emulators disagree about what they can render, and a graph that draws with box drawing characters breaks in a log file, over a serial console or in a CI transcript. A style that uses nothing but ASCII solves that, and the fact that it is a first class option rather than a fallback suggests the author has been bitten by it.

There is also an interactive sibling. If you want a terminal application with a full interface rather than a one-shot command, the readme points to git-igitt, which is based on git-graph.

## Three install routes, and none of them need a compiler

The installation section offers a pre-compiled binary first, which is the right default for a tool you are only going to run.

Download the latest binaries for your platform, unzip them somewhere, and optionally add the git-graph directory to your PATH environment variable. There is no build step and no toolchain requirement, which is worth noting for a Rust project, since compiling it yourself is a perfectly reasonable alternative but not a prerequisite.

The second route is cargo, for anyone with Rust installed:

```bash
cargo install git-graph
```

The third is a homebrew package:

```bash
brew install git-graph
```

The homebrew route is the one to pick if you want the tool to keep up with releases without thinking about it, and the cargo route if you want a pinned version tied to your own toolchain. The manual binary is the one to pick if you are putting the tool on a build server or a locked down machine.

One detail in the usage section catches people out. git-graph needs to be on the PATH, or you have to use the full path to the executable, and the readme shows a Windows style example of that path. It is obvious once you read it and annoying the first time it happens.

## Selecting a model, and setting one per repository

The branching model can be chosen per invocation or pinned to a repository, and the two commands are easy to confuse.

To run with a specific model, for example the simple one, you pass the model option:

```bash
git-graph --model simple
```

To set the model for the current repository permanently, you use the model sub-command:

```bash
git-graph model simple
```

The difference matters when you script things. The option form is what you want in a shell function or an alias, where the model is decided at call time. The sub-command form writes a setting into the repository, which is the one you want when a team has agreed on a model and every clone should show the graph the same way.

The full command line help is a standard two invocations away:

```bash
git-graph -h
git-graph --help
```

For styles and for commit formatting, the readme defers to the manual, which is the right place for a tool with this many knobs. The commit formatting follows the same idea as the format option of git log, so a team that already has a log format string can reuse it rather than learning a second dialect.

The result is a tool that can be run bare, with a model, with a style, with a format, or with all three, and the point of it is that those four choices describe how to read the history rather than how to colour it.

## Custom models are TOML files in your config directory

The custom model mechanism is the part that makes git-graph more than a pretty printer, and it is refreshingly simple.

Branching models are configured using files in the models directory under the application data directory for git-graph, and the readme spells out where that is on each platform: on Windows it is under the Roaming folder of the user profile, on Linux it is the.config directory in the home folder, and on macOS it is the Library Application Support directory in the home folder.

Any TOML file in the models directory can be used, by file name, in the model parameter or via the model sub-command. If a model is defined in a file called my-model.toml, you select it like this:

```bash
git-graph --model my-model
```

So the workflow for a team with a branching scheme that nobody has formalised is to write a TOML file, drop it in that directory on each machine, and refer to it by name. The files are plain text and shareable, which is what makes the convention worth having.

The details of the available fields live in the manual, in a section on custom branching models. The readme does not enumerate them, and that is reasonable, since the manual is linked more than once and a field list in the readme would drift. The trade is that the model format is only documented in one place, so if you are reading this article instead of the manual, treat the TOML file as something to copy from the manual's example rather than to design from scratch.

## Four limitations, and the first one is a real constraint

The limitations section is short and unusually important, because the first item changes how you have to write commit messages.

Summaries of merge commits, meaning the first line of the message, should not be modified. The tool needs them to categorise merged branches. This is the whole design in one sentence: the graph is built by reading the merge summaries and deciding which branch each merge brought in, and a rewritten summary destroys the information the renderer needs. If your team has a commit hook that normalises or templates merge messages, this tool will not read your history correctly, and you will need to change the hook or change the tool.

The second limitation is that only the primary remote repository, origin, is supported. A repository with a fork as the origin, or a workflow where upstream is the remote you care about, will be missing references.

The third is that octopus merges are not supported, meaning merges with more than two parents. Merge commits with exactly two parents are the normal case, so this bites rarely, but it bites hard in repositories that use a merge queue with more than two heads.

The fourth is a platform quirk rather than a design limit. On Windows PowerShell, piping to file output does not work properly because of an encoding change, and the suggestion is to use the default Windows console instead. That is a small thing to know before you spend an afternoon wondering why your redirected output is mangled.

## The Rust build and what the manifest reveals

The manifest is a good place to look for what the tool actually depends on, and it is a sensible list.

```toml
name = "git-graph"
version = "0.8.0"
license = "MIT"
edition = "2021"
rust-version = "1.83.0"
```

The interesting dependency is git2, the Rust binding to libgit2, which is how the tool reads the repository history directly rather than by shelling out to git. The regex crate handles the commit format strings, serde and serde_derive plus the toml crate handle the model files, and clap 4 with the cargo feature provides the command line parsing. crossterm is the terminal handling library, yansi and atty handle colour and terminal detection, platform-dirs finds the application data directory that the model files live in, chrono handles timestamps, and textwrap handles the wrapping of long lines with unicode width awareness.

Two dependencies are worth a second look. The svg crate is there, which is what allows the tool to emit a graph as a vector image rather than only as characters, and gleisbau is a German word for the short railway carriage that connects to the others, and it is the library doing the graph layout itself. The layout is the product, and it has its own dependency for a reason.

The release profile is tuned for a distributed binary, with optimisation level 3, link time optimisation enabled, a single codegen unit and the debug and overflow checks switched off. The result is a small, fast binary, which matches the pre-compiled binary install path being the recommended one.

The package is published to crates.io as git-graph, and the manifest points its repository field at the upstream project, so the copy you are looking at is a mirror or fork of the original rather than the canonical home.

## Conclusion

git-graph is worth installing if your repository follows a fixed branching model and the default git log output stops making sense once you have more than a handful of long-lived branches. It is a poor fit for repositories with octopus merges, for teams that push to remotes other than origin, or for anyone who edits merge commit summaries, because the tool depends on those summaries to categorise branches. Before you adopt it, run it on a real branch in your repository and check that the categorisation matches your model, and if you need a custom model, start from the manual section on custom branching models rather than guessing the TOML fields.

## FAQ

### How do I install git-graph?

Download the pre-compiled binary for your platform from the releases page, unzip it and optionally add the directory to your PATH, or install it with cargo install git-graph, or with brew install git-graph. No compiler is needed for the binary or homebrew routes.

### How do I define a custom branching model in git-graph?

Custom models are TOML files placed in the models directory under the application data directory for git-graph, which is the Roaming folder on Windows, .config in the home folder on Linux, and Library Application Support on macOS. Any file name can then be used with git-graph --model my-model, where my-model matches the file name.

### What are the limitations of git-graph?

Merge commit summaries must not be modified, because the tool needs them to categorise merged branches. Only the primary remote repository origin is supported, octopus merges with more than two parents are not supported, and piping output to a file on Windows PowerShell changes the encoding and does not work properly.

### Is there an interactive version of git-graph?

Yes. The readme points to git-igitt, an interactive git terminal application based on git-graph, for users who want a full interface rather than a one-shot command.

## Sources

- [git-bahn/git-graph on GitHub](https://github.com/git-bahn/git-graph)
- [Issues](https://github.com/git-bahn/git-graph/issues)
- [License: MIT](https://github.com/git-bahn/git-graph/blob/master/LICENSE)
- [README](https://github.com/git-bahn/git-graph/blob/master/README.md)
- [Releases](https://github.com/git-bahn/git-graph/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/git-bahn-git-graph
