A timesaver: watch how a commit, a range or a whole project was built up, instead of reading a diff line by line, with every option run for real on a sample repository.
▶Prefer to watch? This short video explains what gitlogue is for, then replays commits on a real Ubuntu 24.04 machine, with on-screen captions and no voiceover. Click to play, or watch it on YouTube.
gitlogue: replay Git commits in the terminal, as if a ghost developer typed each change by hand.
gitlogue -c HEAD~2 replay one commit
gitlogue -c HEAD~3..HEAD --order asc replay a range, oldest first
gitlogue --author ben only one person's commits
gitlogue diff replay your staged changes before you commit
gitlogue is a terminal program that reads a Git repository and plays its commits back as an animation. For each commit you see the changed files, the code being typed in with syntax highlighting, the hash and the author, and the git commands that were run. It reads the history and changes nothing in the repository. It is useful for seeing how a change was built up, for walking through a branch before a review, for looking over your own staged work before you commit it, and for letting a project's history play on a spare screen.
This page is the written version of the Timesavers video. Every option below was run for real, in an Ubuntu 24.04 container with gitlogue 0.12.1, on a sample repository of seven commits by two made-up people over three weeks (a tiny Python to-do program). The screens shown are the real screens from that run, at one moment of the animation. A page cannot show the animation or its colours, so watch the video for that. The section "What was not run" lists the options that were not tried.
What gitlogue is for
The project describes it as a terminal-based screensaver that replays Git commits as if a ghost developer were typing each change by hand. Characters appear, vanish and change with natural pacing and syntax highlighting. That is the whole idea, and it has some practical uses:
see how a commit was built up the replay shows the typing in order, which reads differently from a finished diff
walk through a range before review a range of commits plays oldest first, one after the other
check your own work gitlogue diff replays what you have staged, before you commit
look at one person's work filter by author name or email
show a project's history to others on a spare screen, or in a talk, with a theme you like
It does not replace git log, git show or git diff: those give you exact text you can search and copy. gitlogue gives you the story of a change. It needs a terminal that can show colours and a repository with some history.
Install and the sample repository
The project's README gives an install script, which downloads a release binary. Read a script before you run it. This one is short: it asks the GitHub API for the latest release, downloads the tarball for your platform, unpacks the one binary and moves it to ~/.local/bin. It does not check a checksum, so if that matters to you, download the release yourself and check it. In the lab:
$ curl -fsSL https://raw.githubusercontent.com/unhappychoice/gitlogue/main/install.sh -o install.sh
$ bash install.sh
Installing gitlogue v0.12.1 for x86_64-unknown-linux-gnu...
Downloading from https://github.com/unhappychoice/gitlogue/releases/download/v0.12.1/gitlogue-v0.12.1-x86_64-unknown-linux-gnu.tar.gz...
Successfully installed gitlogue to /home/ubuntu/.local/bin/gitlogue
Make sure /home/ubuntu/.local/bin is in your PATH:
export PATH="$PATH:/home/ubuntu/.local/bin"
$ gitlogue --version
gitlogue 0.12.1
On Ubuntu a new login shell found it without further work, because the default profile adds ~/.local/bin to the PATH when that directory exists. Other install routes are listed in the project's README (cargo, and some package managers). They were not run.
The sample repository is a tiny Python to-do program called tasks-demo, built for this page with seven commits by Ann Lee and Ben Ortiz. The history, as git log --oneline shows it:
$ git log --oneline
f27cdb0 (HEAD -> main) Document the commands in the README
e96bd54 Keep tasks in a JSON file
c63cca6 Fix: refuse an empty title
f492d64 Add tests for add and done
d0db6e5 Add a done command
47dedfb Add the add and list commands
5643bf3 Start the tasks project
All the people, files and dates are made up. Nothing here is a real project.
Replay one commit
-c (or --commit) takes a commit. HEAD~2 is the commit two before the latest, "Fix: refuse an empty title" by Ann Lee. -s sets the typing speed in milliseconds per character (the default is 30, shown later in the config file); a small number is faster.
$ gitlogue -c HEAD~2 -s 10
The screen opens with a short "No commit loaded" splash, then travels to the commit's date, opens the file and types the change. This is the screen part-way through:
~ tasks.py +2 -0 5
6 def add(title):
7 if not title.strip():
8 raise SystemExit("tasks: a task needs a title")
9 TASKS.append({"title": title, "done": False})
10 print("added:", title)
11
12
13 def show():
14 for i, t in enumerate(TASKS, 1):
15 mark = "x" if t["done"] else " "
16 print(f"{i}. [{mark}] {t['title']}")
17
18
19 def done(number):
────────────────────────────────────────────────────────────────────────────────────────────────────
hash: c63cca6 💾 [main c63cca6] Fix: refuse an empty title
author: Ann Lee 📝 1 file changed - immortalized forever!
On the left is the list of changed files with their counts (tasks.py +2 -0: two lines added, none removed). In the middle is the code with line numbers and the cursor where the typing is. At the bottom left are the hash and the author, and at the bottom right is a running log: the date it arrived at, the commit, and the git commands the ghost developer "runs". When the commit is done the program ends by itself and gives the prompt back.
The repository was not changed. In the lab, git status was clean and HEAD, the branch and the files were the same after a replay as before.
Replay a range of commits
-c also takes a range. HEAD~3..HEAD means the commits after HEAD~3 up to HEAD, so the last three. --order asc plays them oldest first (the other values are desc and random).
$ gitlogue -c HEAD~3..HEAD --order asc -s 5
The three commits play one after another: "Fix: refuse an empty title", "Keep tasks in a JSON file", and "Document the commands in the README". This is the last one, part-way through:
~ README.md +6 -0 1 # tasks
2
3 A tiny command-line to-do list.
4
5 ## Use it
6
7 python3 tasks.py add buy milk
8 python3 tasks.py done 1
9 python3 tasks.py
────────────────────────────────────────────────────────────────────────────────────────────────────
hash: f27cdb0 ~ git add README.md
author: Ann Lee ~ git c
A new file shows with a + in front of its name, a changed file with a ~. The range took about 24 seconds at this speed and the program ended by itself after the last commit. A range is the most useful form for walking through a branch before a review: gitlogue -c main..my-branch is the same idea (that exact range form with a branch name was not run, only HEAD~3..HEAD was).
Only one person's commits
--author takes a name or an email address, matched as part of the text and ignoring case. Without -c, gitlogue looks through the whole history. Here Ben's three commits, oldest first:
$ gitlogue --author ben --order asc -s 5
It played "Add a done command", "Add tests for add and done" and "Keep tasks in a JSON file", and then ended. This is the middle one:
tests/ 1 import tasks
+ test_tasks.py +14 -0 2
3
4 def test_add():
5 tasks.TASKS.clear()
6 tasks.add("buy
7
────────────────────────────────────────────────────────────────────────────────────────────────────
hash: f492d64 🕰 Arrived at 2026-10-08 10:55:00
author: Ben Ortiz 📍 Location: commit f492d64 by Ben Ortiz
Without --author and without -c, gitlogue picks commits itself (in random order unless you set --order) and keeps playing until you press q. In the lab, q ended a run like that and gave the prompt back. The help also lists --before and --after to limit the dates, with examples like 'yesterday' and '1 week ago'. They were not run.
Pick a theme
There are 17 themes for the code colours. gitlogue theme list prints them, and -t chooses one for a single run:
$ gitlogue theme list
Available themes:
- ayu-dark
- catppuccin
- dracula
- everforest
- fluorite
- github-dark
- gruvbox
- material
- monokai
- night-owl
- nord
- one-dark
- rose-pine
- solarized-dark
- solarized-light
- telemetry
- tokyo-night
$ gitlogue -c HEAD~2 -t nord -s 5
The same replay in the nord theme, part-way through (a page cannot show the colours, which is the point of the option, so see the video for that):
~ tasks.py +2 -0 2
3 TASKS = []
4
5
6 def add(title):
7 if not title.strip():
8 raise SystemEx
9 TASKS.append({"title": title, "done": False})
10 print("added:", title)
11
12
13 def show():
14 for i, t in enumerate(TASKS, 1):
15 mark = "x" if t["done"] else " "
16 print(f"{i}. [{mark}] {t['title']}")
────────────────────────────────────────────────────────────────────────────────────────────────────
hash: c63cca6 🕰 Arrived at 2026-10-12 10:55:00
author: Ann Lee 📍 Location: commit c63cca6 by Ann Lee
To make a theme the default, gitlogue theme set NAME writes it into the config file. It also creates the file with every setting and its default, as the lab shows:
$ gitlogue theme set nord
Theme set to 'nord' in /home/ubuntu/.config/gitlogue/config.toml
$ cat ~/.config/gitlogue/config.toml
# gitlogue configuration file
# All settings are optional and will use defaults if not specified
# Theme to use for syntax highlighting
theme = "nord"
# Typing speed in milliseconds per character
speed = 30
# Show background colors (set to false for transparent background)
background = true
# Commit playback order: random, asc, or desc
order = "random"
# Loop the animation continuously
loop = false
# Ignore patterns (gitignore syntax)
# Examples: ["*.png", "*.ipynb", "dist/**"]
ignore_patterns = []
# Speed rules for different file types (pattern:milliseconds)
# Examples: ["*.java:50", "*.xml:5", "*.rs:30"]
speed_rules = []
The command-line options override the file for one run. The file is also where a typing speed, a playback order and a loop setting can be made permanent. The settings for ignore patterns and per-file speed rules are in the file too, and were not run.
Replay your own staged changes
gitlogue diff replays the changes you have staged, with the "commit" being your working tree. It is a way to look over your own work before you commit it. Make a change, stage it and replay it:
$ printf 'def count():\n return len(TASKS)\n' >> tasks.py
$ git add tasks.py
$ gitlogue diff -s 8
~ tasks.py +2 -0 37 if argv[:1] == ["add"]:
38 add(" ".join(argv[1:]))
39 elif argv[:1] == ["done"]:
40 done(int(argv[1]))
41 else:
42 show()
43
44
45 if __name__ == "__main__":
46 main(sys.argv[1:])
47 def count():
48 return len(TAS
────────────────────────────────────────────────────────────────────────────────────────────────────
hash: working 📝 Staged changes
author: Working Tree 📁 1 file changed
The footer says hash: working and author: Working Tree, and the log line says Staged changes, because this is not a real commit yet. The two new lines appear at the end of the file. gitlogue diff --unstaged does the same for changes you have not staged (that flag is in the help and was not run). Nothing is committed or changed by the replay.
The options at a glance
-p, --path <PATH>
-c, --commit <HASH_OR_RANGE>
-s, --speed <MS>
-t, --theme <NAME>
--background [<BOOL>]
--order <ORDER>
--loop [<BOOL>]
-w, --watch
--license
-a, --author <PATTERN>
--before <DATE>
--after <DATE>
-i, --ignore <PATTERN>
--ignore-file <PATH>
--speed-rule <PATTERN:MS>
-h, --help
-V, --version
-p, --path the repository to read (the current directory by default)
-c, --commit one commit, or a range such as HEAD~3..HEAD
-s, --speed milliseconds per typed character (default 30)
-t, --theme the colour theme for this run
--order random, asc or desc
--author commits whose author name or email matches
--before, --after limit the dates
-i, --ignore leave out files that match a pattern (gitignore syntax)
--speed-rule a different typing speed for some files, like '*.xml:5'
--loop play again and again
-w, --watch replay new commits as they are made
--background show or hide the background colours
The lab ran -c, -s, -t, --order, --author, the theme commands, diff and q. The rest come from the help text and were not run.
What was not run in the lab
Only -c, -s, -t, --order, --author, gitlogue theme list and set, gitlogue diff and the q key were used. These options were not run: -p with a valid repository path (only its two error messages were seen), --before and --after, -i and --ignore-file, --speed-rule, --loop, -w (watch mode, which replays new commits as you make them), --background, diff --unstaged, and the speed and theme settings other than the ones shown. The install was the project's script, on Linux x86_64 only. The other install routes (cargo, package managers) were not tried. A large repository, very large commits and binary files were not tried: the sample commits change a few lines of text. The colours of the themes cannot be shown on this page and were checked only by eye in the video.
Common problems and tips
Nothing seems to happen for a few seconds. Each replay opens with a short "No commit loaded" and time-travel splash before the typing starts. Wait for it.
The replay is too slow, or too fast. Use -s with a number of milliseconds per character: -s 5 is quick, -s 30 is the default. Put the speed you like in the config file.
It keeps playing and does not end. A run without -c, or with a filter that matches many commits, goes on playing commits. Press q to stop it. A single commit or a short range ends by itself.
Error: Not a Git repository: . (or any parent directories). That is what gitlogue printed when it was started in a folder that is not a Git repository. Run it inside a repository, or point it at one with -p. With -p /nonexistent it printed Error: Path does not exist: /nonexistent, so -p is read. Pointing -p at a real repository from another directory was not run.
The colours look wrong. Try another theme with -t. Themes are made for dark or light backgrounds, and a terminal with few colours will look poor.
Tips. Use -c with a range to walk through a branch before a review, and gitlogue diff to look over your own staged work. Use a small -s when you only want the shape of a change. For a talk or a screen recording, pick a theme with good contrast and a larger terminal font, and keep the window about the size of the screens above.