Why blame Entires Change With Version 2.52, and Other Release Notes
Blame Every File in a Folder
git blame gives you line-level detail on the who, what, and when of code changes. But what if you need the same information at the folder level—which commit last touched each file in a directory?
The natural workaround is to loop each file through git log -1. It gets the job done, but the underlying mechanism is inefficient with history. Each commit may be traversed several times as you blame each individual file, even though those traversals cover the same history.
Git 2.52 introduces git last-modified. Instead of repeating the blame process per file, the command walks the commit graph once and extracts the most recent commit for every file in a given path. The result is a command that Git can execute significantly faster than the log loop it replaces, as benchmarked in the following tests:
Benchmark 1: git ls-tree + log
Time (mean ± σ): 3.962 s ± 0.011 s [User: 2.676 s, System: 1.330 s]
Range (min … max): 3.940 s … 3.984 s 10 runs
Benchmark 2: git last-modified
Time (mean ± σ): 722.7 ms ± 4.6 ms [User: 682.4 ms, System: 40.1 ms]
Range (min … max): 717.3 ms … 731.3 ms 10 runs
Summary
git last-modified ran
5.48 ± 0.04 times faster than git ls-tree + log
This work has been in development across several years. GitHub engineers used it internally under the name blame-tree to populate repository metadata on the web since 2012. Recent open-source collaboration with GitLab contributors polished the code into a maintainable patch series, which finally landed in this release.
There are still some improvements pending for future versions, including an on-disk cache for previously computed results. You'll find git last-modified in every Git 2.52 installation.
Smarter Repository Maintenance: A New Geometric Path
Since Git 2.31, git maintenance has provided organized housekeeping for your local repository. Compared to the older, monolithic git gc approach, git maintenance manages several separate tasks (e.g., commit-graph writes, reflog expiry, and incremental repacking). Yet prior versions still had a missing piece:
git gcconsolidates the entire repository into a single packincremental-repackavoids a heavy repack but cannot prune unreachable objects
git gc's all-into-one operation can feel slow for very large storehouses.
Git 2.52 adds a geometric strategy to git maintenance. Its behavior is straightforward: it examines the packfiles and their object counts to see if they can be re-arranged into a geometric progression. If so, it combines just the right pacfiles—not the entire pack—and layers on top of it. When, however, this reorganization would lead the entire repository to land in one packfile, it triggers a normal git gc run, handling cleanup of unreachable objects as usual.
The underlying geometric repacking code, designed by GitHub’s maintenance team to handle a monorepo scale, has been present in Git since 2.33—but it was only reachable inside git repack internals, which made it an awkward utility. The new geometric maintenance task brings this performance gain into the standard git maintenance workflow.
With this addition, git maintenance handles both maintenance needs—performance-cheap repacking and cleaning stale objects—within one package, creating reliable upkeep for any repository size.
For more on this release, see the available documentation for these features at Git 2.52's official sites.
Reference Tooling Expands
Git 2.52 adds two new sub-commands to git refs, the low-level interface for inspecting and managing repository references. git refs list is an alias for git for-each-ref with the same options, while git refs exists mirrors git show-ref --exists for quickly checking whether a given reference is present. These commands introduce no new capabilities but consolidate common reference operations under one tool.
A New Home for Repository Introspection
Developers who script around Git often reach for rev-parse, which does far more than resolve commit identifiers. It also handles shell quoting, option parsing as a getopt replacement, printing GIT_ environment variables, and resolving paths within $GIT_DIR. Git 2.52 takes the first step toward relocating that functionality with the new, experimental git repo command, designed as a general-purpose tool for querying repository metadata. It can report whether a repository is shallow or bare, as well as its object and reference formats:
$ keys='layout.bare layout.shallow object.format references.format'
$ git repo info $keys
layout.bare=false
layout.shallow=false
object.format=sha1
references.format=files
The command also provides a git repo structure sub-command that prints statistics about repository layout and content:
$ git repo structure
Counting objects: 497533, done.
| Repository structure | Value |
| -------------------- | ------ |
| * References | |
| * Count | 2871 |
| * Branches | 58 |
| * Tags | 1273 |
| * Remotes | 1534 |
| * Others | 6 |
| | |
| * Reachable objects | |
| * Count | 497533 |
| * Commits | 91386 |
| * Trees | 208050 |
| * Blobs | 197103 |
| * Tags | 994 |
Default Branch Name Prepares for Change
Since Git 2.28 introduced init.defaultBranch, the configuration has defaulted to master, even though many users set it to main. In Git 3.0, the default will become main, meaning newly initialized repositories will use that branch name with no extra configuration. To preview this and other breaking changes scheduled for Git 3.0, the project can be built locally with the WITH_BREAKING_CHANGES build flag.
SHA-256 Interoperability Groundwork
Git 3.0 is slated to switch the default content-addressable hash from SHA-1 to SHA-256. Git 2.45 introduced the ability to write duplicate objects using both algorithms as an intermediate step toward interoperability. Git 2.52 continues that effort, laying the internal groundwork with the eventual goal of letting users push and pull between repositories that employ different hash algorithms.
Rust Enters the Codebase
This release marks the first optional use of Rust within Git, guarded behind a new WITH_RUST build flag. When enabled, Git employs a Rust implementation for encoding and decoding variable-width integers. Although this is a minor utility function, it establishes infrastructure for more substantial components to be rewritten in Rust. Rust support will become mandatory in Git 3.0.
Broader Bloom Filter Coverage
Git 2.52 extends changed-path Bloom filter usage to more pathspec scenarios. Previously, filters accelerated simple path queries, and recent work added support for multiple paths at once. Now, pathspecs containing wildcards in some components—such as foo/bar/*/baz—can still leverage Bloom filters for the non-wildcard portions of the path, preserving performance benefits in those mixed cases.
Performance Wins Across the Board
Multiple commands receive speedups in this release. git describe now employs a priority queue for a 30% improvement. git remote rename has been optimized for reference renaming. git ls-files can keep the index sparse in situations where it previously could not. git log -L avoids unnecessary tree-level diffs when processing merge commits, making it significantly faster. The xdiff diff and merge engine also benefits from a pair of optimizations, with more changes expected in future releases.
Sparse-Checkout Cleanup
Finally, sparse-checkout gains a new clean sub-command. git sparse-checkout clean helps recover from situations where changing the sparse-checkout definition leaves files present outside the desired checkout pattern. The underlying problem and why previous tooling struggled with it are detailed in the change's commit message, but users who have hit this issue can try the new command in Git 2.52.
For the complete list of changes, consult the release notes for Git 2.52 or any previous version in the Git repository.



