Highlights from Git 2.52 - The GitHub Blog
|

Highlights from Git 2.52 – The GitHub Blog

Spread the love
Highlights from Git 2.52 - The GitHub Blog

Quick Summary:

Rewrite the article below into a clear, simple, original, US-friendly tech update.
Make it 2 short paragraphs.
Never copy sentences.
Keep it factual.


Full Update

open source git project Git 2.52 just released With features and bug fixes from over 94 contributors, 33 of which are new. We last talked to you about the latest version of Git when 2.51 was released.

To celebrate this latest release, here’s a look at some of the most interesting features and changes GitHub introduced since last time.

If you’re an experienced Git user, you’re no doubt familiar with git blem, Git’s tool for finding out what is the most recent modification to each line at a given filepath. Git’s blame functionality is great for finding out when a bug was introduced, or why some code was written that way.

If you want to know which commit last modified a part of a given filepath, it’s quite easy to do git log -1 -- path/to/my/filesince -1 Will give us only the first commit that modifies that path. But what if instead you want to know which commit has most recently modified each file in a directory? Answering that question may seem hypothetical, but it’s not. If you’ve ever looked at the file list of a repository on GitHub, the middle column of information contains a link to the commit that most recently modified that path, along with (part of) its commit message.

GitHub’s repository file list, showing tree-level defect information.

The question remains: how can we efficiently determine which commit most recently modified each file in a given directory? You can imagine that you can calculate each tree entry, feed it git log -1 And collecting the output there, like:

$ git ls-tree -z --name-only HEAD^{tree} | xargs -0 -I{} sh -c '
    git log -1 --format="$1 %h %s" -- $1
  ' -- {}  | column -t -l3 
.cirrus.yml     1e77de10810  ci: update FreeBSD image to 14.3
.clang-format   37215410730  clang-format: exclude control macros from SpaceBeforeParens
.editorconfig   c84209a0529  editorconfig: add .bash extension
.gitattributes  d3b58320923  merge-file doc: set conflict-marker-size attribute
.github         5db9d35a28f  Merge branch 'js/ci-github-actions-update'
[...]

It works, but not efficiently. To see why, consider a case involving files A, BAnd C Presented by Commitments C1, C2And C3Respectively. blame Awe go from there C3 Back C1 to determine this C1 The latest commit to modify was AThat traversal passed C2 And C3But since we were only looking for modification AWhile attempting to assign blame we will ultimately revisit those commitments B And CIn this example, we visit those three commits a total of six times, which is twice the required number of history traversals,

Git 2.52 introduces a new command that provides the same information in less time: git last-modifiedTo understand how fast last-modified Compared to the above example, here are some very subtle Result:

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

Main functionality behind git last-modified Was written (originally said) by GitHub over several years. blame-tree in GitHub’s fork of Git), and it has driven our tree-level flaw since 2012. Earlier this year, we shared those patches With the GitLab engineers who did the cleanup years of development in one reviewable series The patches that came in this release.

The GitHub version of this command still has some features that have not yet made their way into the Git release, including an on-disk format for caching the results of previous runs. In the meantime, check out git last-modifiedAvailable in Git 2.52.

[source, source, source]

Returning readers of this series may remember our coverage git maintenance Permission. If you’re reading for the first time, or you could use a refresher, we’ve got you covered.

git maintenance is a Git command that can perform repository housekeeping tasks on a scheduled or ad-hoc basis. maintenance command can perform a task variety of tasksSuch as repackaging the contents of your repository, updating the commit-graph, eliminating old reflog entries, and much more. put together, maintenance This ensures that your repository continues to operate smoothly and efficiently.

By default (or when running gc Work), git maintenance depends on git gc To repack your repository internally, and remove any inaccessible objects. It has some shortcomings, namely git gc “All-in-one” repack to consolidate the contents of your repositories, which can be slow for very large repositories. As an alternative, git maintenance there is one incremental-repack Strategy, but it never cuts out anything unattainable.

Git 2.52 fills this gap by introducing a new geometric work within git maintenance Avoids all-in-one repackaging whenever possible, and prunes less frequently accessed objects. This new work uses tools (like geometric repacking) that were designed at GitHub and that have driven GitHub’s own repository maintenance for many years. Those tools have been in Git since 2.33, but it was awkward to use or find them because their implementation was buried inside git repackNo git gc,

geometric The function here works by inspecting the contents of your repository to determine if we can combine some number of packfiles to make one geometric progression By item count. If it can, it performs a geometric repack, which condenses the contents of your repository without pruning any objects. Alternatively, if a geometric repack will pack your entire repository into a single pack, a complete git gc Instead it is performed, which consolidates the contents of your repository and sorts out the inaccessible items.

Git 2.52 makes it easier to keep even your largest repositories running smoothly. see new geometric strategy, or any of the many other abilities git maintenance Can do in 2.52.

[source]


Now that we’ve covered some of the big changes in more detail, let’s take a closer look at a selection of some of the other new features and updates in this release.

  • Some new sub-commands added in this release git refsGit has a relatively new tool for providing low-level access to your repository. Give Feedback ReferenceBefore this release, git refs The context was able to migrate between backends (for example, to keep your repository store context data). retractable format), as well as verifying the internal representation of those references.

    git refs Now two new sub-orders are included: git refs list And git refs existsis a nickname for the former git for-each-ref And supports the same set of options. works like the latter git show-ref --existsAnd it can be used to immediately determine whether a given reference exists or not.

    None of these new sub-commands introduce new functionality, but they consolidate some common context-related operations into a single Git command rather than several individual ones.

    [source]

  • If you’ve ever done scripting around Git, you’re probably familiar with Git. rev-parse Permission. If not, you’d be forgiven for thinking so rev-parse Designed to resolve different ways of describing a commit by its full object ID. In reality, rev-parse The shell can perform functionality completely unrelated to resolving object IDs, including quotes, option parsing (as a replacement for getopt), local printing GIT_ Resolving paths inside environment variables $GIT_DIR And and many more,

    Git 2.52 introduces the first steps to giving some of this functionality a new home via its new git repo Permission. git repo The command – currently designated as experimental – is designed as a general-purpose tool for retrieving pieces of information about your repository. For example, you can check whether the repository is shallow or empty, as well as what type of objects and reference formats it uses, such as:

    $ 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

    New git repo The command can also print some general statistics about the structure and contents of your repository through git repo structure Sub-order:

    $ 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 |

    [source, source, source]

  • In 2.28, the Git project introduced this init.defaultBranch configuration options To provide a default branch name for any repository created git initSince its introduction, the default value of that configuration option was “master”, although there were multiple sets, init.defaultBranch Instead of “main”.

    Starting with Git 3.0, the default value for init.defaultBranch Will change to “Main”. This means that any repository created using Git 3.0 or newer git init Their default branch will be named “main” without requiring any additional configuration.

    If you want to get a glimpse of this, or any other planned changes for Git 3.0, you can build Git Locally WITH_BREAKING_CHANGES Build-flag to try out the new changes today.

    [source, source]

  • By default, Git uses SHA-1 to provide Content-Addressable Hash Of any item in your stock. In Git 3.0, Git will instead use SHA-256 which offers more attractive security properties. In our coverage of Git 2.45, we talked about some new changes that enable writing separate copies of new objects using both SHA-1 and SHA-256 as a temporary step toward interoperability between the two.

    In Git 2.52, the rest of the work towards interoperability begins. Although the changes in this release are focused on laying the groundwork for future interoperability features, the hope is that eventually you can use a Git repository with one hash algorithm while pushing to and pulling from another repository using a different hash algorithm.

    [source]

  • Speaking of other bleeding-edge changes to Git, this release is the first to (optionally) use Rust code for some internal functionality within Git. This mode is optional and is protected behind a new WITH_RUST Make a flag. When building with this mode enabled, Git will use rust implementation for encoding and decoding variable-width integer,

    Although this release only introduces a Rust version of some small utility functionality, it establishes the infrastructure for rewriting much of the more interesting parts of Git in Rust.

    Rust support is not yet mandatory, so Git 2.52 will continue to run fine on platforms that do not have a Rust compiler. However, Jung’s support Will be required for Git 3.0At which point many more components of Git will likely depend on Rust code.

    [source, source, source]

  • Longtime readers may remember our coverage of the changed-path Bloom filter within Git in 2.28. If not, change path bloom filter is a probabilistic data structure that can predict which file path was modified by a commit (relative to its first parent). Since Bloom filters never have false negatives (i.e. indicating that a commit did not modify some path when in fact it did), they can be used to speed up many path-scope traversals throughout Git (including last-modified Above!).

    Recently, we covered new ways to use Bloom filters within Git, such as providing multiple paths of interest at the same time (for example, git log /my/subdir /my/other/subdir) which were not previously supported with Bloom filters. At that time, we wrote that there were ongoing discussion About supporting Bloom filters in Git’s more expressive PathSpec syntax.

    This release provides the results of those discussions, and now supports the performance benefits of using Bloom filters in even more scenarios. An example here is when a pathspec contains wildcards in some, but not all of its components, e.g. foo/bar/*/bazWhere Git will now use its Bloom filter for non-wildcard components of the path. To read about even more scenarios that can now take advantage of Bloom Filters, check out the link below.

    [source]

  • This release also saw several performance improvements in several areas of the project. git describe learned to use a priority queue To speed up performance by up to 30%. git remote Tried some new tricks to optimize renaming contexts with this rename Sub-order. git ls-files Can keep the index sparse in cases where this was not the case before. git log -L became quite fast By avoiding some unnecessary tree-level differences when processing the merge. At the end, xdiff (the library that powers Git’s file-level diff and merge engine) benefited from a pair of optimizations (HereAnd Here) in this release, and even more customization It will probably be released in the future.

    [source, source, source, source]

  • Last but not least, some updates to Git sparse-checkout Convenience, which learned a new “clean” sub-command. git sparse-checkout clean This can help you overcome difficult cases where some files are left outside your sparse-checkout definition when changing which part of the repository you check out.

    The details of how one could get into this situation, and why it was so difficult to recover from it with pre-2.52 equipment alone, are surprisingly technical. If you’re interested in all the gory details, this commitment There is all the information about this change.

    Meanwhile, if you use sparse-checkout And have you ever had trouble cleaning when changing your switch? sparse-checkout definition, give git sparse-checkout clean A detour with Git 2.52.

    [source]

This is just a sample of the changes from the latest release. See the release notes for more information 2.52Or any previous version In git repository,

written by

Taylor Blau is a Principal Software Engineer at GitHub where he works on Git.

Source: github.blog

Published on: 2025-11-17 12:54:00

Categories: Git,Open Source

Tags:

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *