Building a Reftable-Compatible Git Smartlog

A native Git implementation that works with any repository backend

The Problem

If youโ€™ve used git-branchless, you know how useful git sl (smartlog) is. It shows a beautiful tree view of your local branches, making it easy to see what youโ€™re working on without the noise of everyone elseโ€™s remote branches.

But thereโ€™s a catch: git-branchless doesnโ€™t work with reftable repositories.

What is Reftable?

Reftable is a new ref storage backend for Git that improves performance for repositories with many refs. Instead of storing each ref as a separate file (the traditional approach), reftable stores refs in a compact, indexed format. This is especially beneficial for large monorepos.

The problem? Git-branchless relies on the traditional ref storage format and fails on reftable repos.

The Solution: git-smartlog

I built a native Git implementation of smartlog that works with any Git repository, including reftable ones. It uses only Gitโ€™s plumbing commands, which are backend-agnostic.

What It Looks Like

Hereโ€™s the output of git lg (my alias for git-smartlog):

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘ย ย Git Smartlog - Branch-centric repository viewย ย ย ย ย ย ย ย ย ย ย โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Baseline: master

โ‹ฎ
โ—‡ 84c4031 10h NGT-3034: utils for drawing bBox on pdp (#82406)
โ”ฃโ”โ”“
โ‹ฎ โ—ฏ 9d76c6d 10h Fix checkout page login redirect to preserve original request URL
โ‹ฎ โ”ƒ
โ‹ฎ โ—ฏ 5041aaf 9h Add DV to control checkout login redirect behavior
โ‹ฎ โ”ƒ
โ‹ฎ โ—ฏ 48737e1 9h Add cxWebCheckoutPreserveUrlOnLogin to serverComponentDynamicValuesList
โ‹ฎ โ”ƒ
โ‹ฎ โ—ฏ d7c3e84 9h Update checkout server component to use withPlatformServerComponentDvClient
โ‹ฎ โ”ƒ
โ‹ฎ โ— 0226ab8 8h (แ… fix-checkout-login-redirect) Remove unused ServerComponentType import
โ‹ฎ
โ—‡ bc24a39 4h (master) [CHATPLAT-3915] Update event names for chat disconnect/connect/reconnect events

Key Features

  • Tree structure with Unicode box-drawing characters (โ‹ฎ, โ—‡, โ—, โ—ฏ, โ”ฃโ”โ”“, โ”ƒ)
  • Fork points from master/main (โ—‡)
  • Branch commits (โ—ฏ) with the branch head marked (โ—)
  • Current branch indicator with arrow: (แ… branch-name)
  • Compact time format (8h, 1d, 5w, 4mo)
  • Only local branches - no noise from remote branches
  • Works with reftable repos - uses native Git plumbing commands

How It Works

The implementation uses only Gitโ€™s plumbing commands, which work regardless of the ref storage backend:

1. Find All Local Branches

git for-each-ref --format='%(refname:short)' refs/heads

This lists all local branches without relying on filesystem structure.

2. Find Fork Points

For each branch, find where it diverged from master:

git merge-base --fork-point refs/heads/master $branch

This gives us the commit where the branch forked off.

3. Get Branch Commits

Get all commits unique to the branch:

git log --format='%h|%ar|%s' $branch ^master

The key optimization here: we get the hash, date, and message in one Git call instead of calling git log separately for each commit.

4. Render the Tree

The script processes each branch and renders:

  • Fork point (โ—‡) with timestamp
  • Commits in the branch (โ—ฏ) in chronological order
  • Branch head (โ—) with branch name
  • Current branch gets an arrow indicator (แ…)

Performance Optimizations

The initial implementation was slow because it called Git commands for every commit. Here are the optimizations:

  1. Batch commit data: One git log call per branch instead of one per commit
  2. Eliminate redundant calls: Since we reverse the commit list, the first commit is always the branch head - no need to call git rev-parse to check
  3. In-memory caching: Store branch head hash in a variable instead of calling Git repeatedly

These optimizations reduced the number of Git subprocess calls from O(commits) to O(branches).

Installation

  1. Clone the repo:
git clone https://github.com/Kimeiga/dotfiles.git
cd dotfiles
  1. Add the git-spells directory to your PATH in your shell config:
# In ~/.zshrc or ~/.bashrc
export PATH="$HOME/path/to/dotfiles/git-spells:$PATH"
  1. Add the alias to your .gitconfig:
git config --global alias.lg '!git-smartlog'
  1. Use it:
git lg

Code

Usage

# Basic usage
git lg

# Verbose mode (shows commit author)
git lg -v

# Include remote branches
git lg -r

# Show help
git lg -h

Why Not Just Use git log โ€”graph?

You might wonder: โ€œCanโ€™t you just use git log --graph?โ€

The problem with git log --graph is that it shows all branches by default, including:

  • Remote branches from other developers
  • Release branches
  • Tags
  • Merge commits cluttering the view

Even with filters like --branches --not --remotes, you lose the master commits that serve as fork points, resulting in a linear history instead of a tree.

Git-smartlog solves this by:

  1. Showing only local branches
  2. Including master commits as fork points (โ—‡)
  3. Hiding irrelevant master history
  4. Clearly marking which commits belong to which branch

Comparison with git-branchless

Featuregit-branchlessgit-smartlog
Works with reftableโŒโœ…
Tree visualizationโœ…โœ…
Shows local branches onlyโœ…โœ…
PerformanceExcellent (Rust)Good (Bash + Git)
DependenciesRust binaryJust Git + Bash
CustomizableLimitedEasy to modify

Future Improvements

Possible enhancements:

  • Add color customization options
  • Support for showing stashes
  • Integration with Git worktrees
  • Option to show commit authors inline
  • Configurable baseline branch (not just master/main)

Conclusion

Building git-smartlog taught me a lot about Gitโ€™s internals and the importance of using the right abstractions. By using Gitโ€™s plumbing commands instead of relying on filesystem structure, we created a tool that works across different Git backends.

If you work with reftable repositories or just want a lightweight alternative to git-branchless, give git-smartlog a try!


Links: