Git Rev News: Edition 132 (February 28th, 2026)

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.

Discussions

Support

  • Slow git pack-refs –all

    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.

Other News

Various

Light reading

Easy watching

Git tools and sites

  • mise-en-place or 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.
    • A monorepo is a software-development strategy in which the code for a number of projects is stored in the same repository. See for example the monorepo.tools site, first mentioned in Git Rev News Edition #84.
  • difi is a TUI tool that helps you review and refine Git diffs before you push. Written in Go using the Bubble Tea library, under MIT license.
  • deff is a TUI tool providing interactive, side-by-side file review for Git diffs with per-file navigation, vertical and horizontal scrolling, syntax highlighting, and added/deleted line tinting. Written in Rust, under MIT license.
  • ec (easy-conflict) is a terminal Git mergetool with a 3-way TUI and Neovim integration. Written in Go, under MIT license.
  • Maiao: Gerrit-style code review workflow for GitHub. Maiao brings the power of stacked pull requests to GitHub, enabling you to break large features into small, reviewable commits where each commit becomes its own PR. Provides a git review command. Written in Go, under MIT license.
  • Diffs, aka @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.
  • Gitnuro is a multiplatform Git client, based on JetBrains Compose and JGit. Written in Kotlin, under GPL 3.0 license.
  • RelaGit - the elegant solution to graphical version control, is a multiplatform Git GUI written in TypeScript. Under LGPL 3.0 license. RelaGit is in early beta stage.
  • SourceGit is an open-source Git GUI client that supports Windows, macOS, and Linux. Includes built-in conventional commit message helper, and support for using AI to generate commit messages. Written in C#, using the Avalonia cross-platform UI framework, under MIT license.
  • git-toolbelt is a suite of useful Git commands that aid with scripting or every day command line usage. Written in shell, under BSD-3-Clause license.
  • sqldef is a CLI tool for diffing two SQL schemas. You can use it to manage the migration of RDBMSs using regular SQL DDLs. Supported databases: MySQL, MariaDB, TiDB, PostgreSQL, SQL Server, and SQLite3. Written in Go, under MIT license (for everything except parser, which is under Apache 2.0 license). Compare with:
  • Fresh File Explorer is a VS Code file explorer which shows only recently modified files based on a combination of Git history and your pending changes. Written in TypeScript, under MIT license.
  • Git Remote Color is a VS Code extension that automatically colors your VS Code workspace based on the git remote URL: every repository gets its own unique, consistent color. Inspired by the Peacock extension, but fully automatic using a deterministic hash of the git remote.
  • commit-prophet is a command line tool that predicts which files are more likely to have bugs using Git history patterns and co-change analysis. Written in Python, under MIT license.
  • Majutsu provides a Magit-style interface for Jujutsu (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.
  • The Missing GitHub Status Page is a third-party service that tracks 90 days uptime; created because GitHub stopped updating its GitHub Status page with aggregate uptime numbers.

Releases

Credits

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.