Welcome to the 132nd edition of Git Rev News, a digest of all things Git. For our goals, the archives, the way we work, and how to contribute or to subscribe, see the Git Rev News page on git.github.io.
This edition covers what happened during the months of January and February 2026.
Martin Fick started the discussion by reporting a significant
performance issue where git pack-refs --all was taking over five
minutes to complete on a large repository (~3M refs) hosted on an
NFS filesystem. This delay was particularly problematic for Gerrit
servers because Git holds the packed-refs.lock for nearly the
entire duration, blocking other reference updates. Martin noted that
JGit was able to perform the same operation in under 20 seconds on
the same repository, suggesting the bottleneck was specific to the
Git implementation.
The packed-refs file is used by Git to store a large number of
references in a single sorted file to avoid the overhead of many
small “loose” reference files. However, updating this file requires
rewriting it entirely, and Git typically verifies that objects exist
and “peels” tags (finding the underlying object a tag points to)
during this process.
brian m. carlson replied to Martin, suggesting that the slowdown
might be occurring in should_pack_ref() because Git needs to
verify that the object at the end of a reference actually
exists. brian also pointed out that NFS was likely a major factor,
as the network latency involved in opening many pack files and
checking loose objects can be substantial. He suggested setting
receive.unpackLimit to 1 to reduce the number of loose objects
created in the first place.
Jeff King (alias Peff) explained that the packed-refs file stores
“tag-peeling” information, which requires Git to open each object
for newly written refs via peel_object() to read its header and
determine its type. Peff noted that this logic resides in
write_with_updates() within packed-backend.c.
Martin conducted further testing using strace and drop_caches to
eliminate filesystem caching interference. He discovered that while
the actual write() calls were fast, there were long gaps—up to
four minutes in total—where the program was not making any system
calls. Martin hypothesized that this “hidden” time was spent by the
kernel handling page faults for mmap()ed memory over NFS.
Patrick Steinhardt concurred that NFS was frequently a source of
such performance issues, mentioning that GitLab had eventually
sunsetted the use of NFS for this reason. Patrick suggested using
perf(1) to generate a flame graph to see exactly where the CPU was
spending time.
Martin provided a summary of a flame graph, which showed about
one-third of the time spent in _memcmp_sse4_1 and another third in
unpack_object_header_buffer(), both accompanied by high page fault
rates. He also noticed significant time spent in a function he
identified as packed_refs_store_create().
Peff corrected the function name to packed_ref_store_create() and
noted that Git might be performing an extra linear pass through the
packed-refs file if it lacks certain header tags. He discovered
that JGit-generated files were missing the sorted and
fully-peeled traits in the header. Without the sorted tag, Git
reads the entire file linearly to verify its order before it can
perform binary searches. Peff suggested that JGit should be updated
to write these markers.
In a final breakthrough, Martin tested adding these tags
manually. He found that while the sorted tag did not provide a
major boost, adding the fully-peeled tag was the “trigger” that
dropped the execution time from over five minutes to under four
seconds. The absence of the fully-peeled tag was forcing Git to
re-peel every reference by looking up the objects in the pack files
over the slow NFS connection.
Following that discovery, a fix was proposed for JGit in Change 1230152. Adithya Chakilam submitted the patch, titled “pack-refs: Add sorted/fully-peeled flags,” to ensure JGit produces packed-refs files that Git can process efficiently.
This resolution not only fixes the immediate performance issue for Gerrit servers but also ensures that any environment using a mix of JGit and Git will benefit from reduced lock contention and faster reference updates.
Various
git fast-import commit signature handling options,
and more data being available in git repo structure output.Light reading
:(optional) prefix;
see the ‘pathname’ entry in the “Values” section of the git config manpage.node_modules, target, .venv), copies env/config patterns,
and can launch your AI coding agent directly in the new worktree.git filter-repo or BFG RepoCleaner to rewrite history might be a choice).
They can also access authentication information if embedded in .git/config.git_odb_backend and git_refdb_backend interfaces
against PostgreSQL through libpq).
He acknowledges that right now gitgres is just a neat hack,
as it currently does not implement delta compression;
nevertheless it might be a good solution for small instances of software forges
for small projects.
robots.txt).Introducing jjq, a local merge queue for jj
by Paul Smith on his blog.
Jujutsu (jj) is a Git-compatible
version control system written in Rust, which was first mentioned
in Git Rev News Edition #85.
Easy watching
Git tools and sites
mise, a CLI tool that is
the front-end to your dev env
(managing dev tools like node, python, cmake, terraform, etc; and
managing tasks used to build and test projects),
introduced monorepo tasks,
allowing you to manage tasks across multiple projects in a single repository,
with each project maintaining its own tools, environment variables, and tasks.
git review command.
Written in Go, under MIT license.
av,
a command-line tool that helps you manage your stacked PRs on GitHub.
It was mentioned in Git Rev News Edition #115.@pierre/diffs,
is an open source diff and file rendering library built on
the Shiki syntax highlighter.
It supports split (side-by-side) or stacked (unified diff) layout,
different diff highlight styles, in-line highlighting, wrapping, and line numbers.
Includes an annotation framework for injecting comments and annotations, and more.
Written in TypeScript, under Apache 2.0 license.
Intended for use in web applications.
Diffs is in early active development—APIs are subject to change.
jj),
offering an efficient way to interact with JJ repositories from within Emacs.
Primary project license is GNU GPL v3 or later,
but it was previously distributed under MIT license terms.This edition of Git Rev News was curated by Christian Couder <christian.couder@gmail.com>, Jakub Narębski <jnareb@gmail.com>, Markus Jansen <mja@jansen-preisler.de> and Kaartic Sivaraam <kaartic.sivaraam@gmail.com> with help from Bruno Brito, Michael Ryzhikov and Shreyansh Paliwal.