Movatterモバイル変換


[0]ホーム

URL:


Skip to contentSkip to sidebar
/Blog
Try GitHub CopilotAttend GitHub Universe

Highlights from Git 2.46

Git 2.46 is here with new features like pseudo-merge bitmaps, more capable credential helpers, and a new git config command. Check out our coverage on some of the highlights here.

Orange rectangle with the Git logo and white text overlaid, which reads "Git 2.46 is here!"
|
|9 minutes
  • Share:

The open source Git project justreleased Git 2.46 with features and bug fixes from over 96 contributors, 31 of them new. We last caught up with you on the latest in Git back when2.45 was released.

Before we get into the details of this latest release, we wanted to remind you thatGit Merge, the conference for Git users and developers is back this year on September 19-20, in Berlin. GitHub andGitButler are co-hosting the event, which will feature talks from developers working on Git, as well as those developing tools in the Git ecosystem. The call for proposals (CFP) closes on August 8. Check outthe website to learn more.

With that out of the way, here is GitHub’s look at some of the most interesting features and changes introduced since last time.

Faster traversals with pseudo-merge bitmaps

Returning readers of these posts will remember our coverage of reachability bitmaps. If you’re new around here or need a refresher, here’s a quick overview. When Git needs to fulfill a fetch request, it starts with a set of commits that the client wants but does not have, and another set that the client already has and does not want. Given this information, Git needs to determine which commits (and trees, blobs, etc.) exist between the two sets in order to fulfill the client’s fetch request. Once it has this information, it generates apackfile to send to the client containing the objects that it requested.

So, how does Git determine the set of objects to send between the “haves” and “wants”? One way to do this is to walk backwards through history, starting with each commit in the “wanted” set, marking them as interesting, then examining their parents, and so forth until you have no more interesting commits left. When Git encounters a commit along the way, it can either continue the walk (if the commit isn’t reachable from any of the “haves”), or not (otherwise).

This naive object walk determines the set of objects to send, but can be slow depending on the size of the “haves” or “wants” set, the number of commits between the two, how deep the intermediate trees are, and so on. In order to optimize this computation, Git usesreachability bitmaps to more quickly determine the set of objects to send. Bitmaps store the set of objects reachable from some set of commits, encoding this set as abitset where each bit uniquely identifies a single object. Here’s an example of that in action:

Reachability traversal using pack-bitmaps without pseudo-merge bitmaps enabled.

In the above example, each commit is represented by a circle, with boxes indicating a handful of references (likerefs/heads/main,refs/heads/foo, etc). In the bottom-left there are three bitmaps for commitsC(0,1),C(0,3), andC(0,5). To determine the set of objects to send, Git starts by walking from each of the given references backwards along each commit’s parents, marking reachable commits with the color green. If a commit is already colored green during the traversal, we can stop early. When Git encounters commitC(0,5), it sees that that commit has a bitmap, which indicates the set of objects reachable from it. Whenever this happens, Git can quickly mark all of those objects reachable without actually having to walk along that portion of history.

So, bitmaps can speed-up many object traversals like the above. But notice that there is still a lot of manual object traversal taking place from the other branches, likefoo,bar, and so on. Git could write more bitmaps, but doing so can be expensive1.

In Git 2.46, Git introduced experimental support for a new kind of bitmap, called apseudo-merge reachability bitmap. Instead of storing bitmaps for individual commits, pseudo-merge bitmaps store the set of objects reachable from multiple commits, rather than any single one. If the client wants commits reachable from, say,foo,bar, andbaz, it suffices to have a single pseudo-merge bitmap corresponding to those commits. Here’s an example of the same traversal from earlier, but this time with pseudo-merge bitmaps:

Reachability traversal using pack-bitmaps with pseudo-merge bitmaps enabled.

Notice that there’s a new bitmap in the lower-left hand corner, corresponding to the pseudo-merge between commitsC(1,1),C(2,2),C(0,7), andC(3,4). The first three are all part of the explicit “wants” set, andC(3,4) is implicitly wanted since it is reachable from thebaz andquux is implicitly wanted since it is reachable from thebaz andquux branches.

Git starts its traversal in the same way, walking backwards from each of the starting commits. At each point, it checks whether or not any pseudo-merges are usable: that is, whether the commits they describe are all either explicitly or implicitly wanted by the client. When Git starts walking backwards fromrefs/heads/baz, it marksC(3,4), and determines that the pseudo-merge is usable. Once this happens, all of the commits corresponding to the bits in the pseudo-merge are marked. Finally, Git performs a couple of remaining manual traversal steps backwards fromrefs/heads/quux until the whole walk is complete.

This post just covers the tip of the iceberg with pseudo-merge bitmaps, which have a ton of new configuration options to determine how pseudo-merges get selected and organized in large repositories. The new configuration (as well as the feature itself) is still considered experimental, but you can get started by enabling pseudo-merges in your repository like so:

# configure pseduo-merge bitmaps$ git config bitmapPseudoMerge.all.pattern 'refs/(heads|tags)/'$ git config bitmapPseudoMerge.all.threshold now$ git config bitmapPseudoMerge.all.stableThreshold never# then generate a new *.bitmap file$ git repack -adb

GitHub will be rolling out pseudo-merge bitmaps in the coming short while, so expect a follow-up post from us with an even deeper dive into the inner workings of pseudo-merge bitmaps when we do.

[source,source]


  • At the end of our coverage of pseudo-merge bitmaps above, we used thegit config command to show how to tweak your repository’s.gitconfig file to enable bitmaps. Veteran Git users will know that this command does a whole lot more than just setting configuration options. It can list all configuration settings, get a single one (or multiple, matching aregular expression), unset settings, rename or remove sections, and even open a.gitconfig in your$EDITOR of choice.

    In the past, these options were all hidden behind different command-line options, like--get,--get-all,--unset, and--remove-section, to name a few.

    Git 2.46 shipped a new user-interface for this command, grouping its many capabilities into a few top-level sub-commands, making it much easier to use. For instance, if you want to list all of the configuration settings in your repository, you can simply rungit config list. If you want to get a single setting, you can rungit config get <name>. If you want to narrow your results down further to just those matching a regular expression, you can use the--regexp option along with theget sub-command.

    These new command-line options and sub-command modes organizegit config’s various functions much more neatly, and make the command a lot easier to use while still retaining backwards compatibility with all existing invocations. To learn more about the new modes, check outthe documentation for git-config(1).

    [source]

  • We’ve written about Git’scredential helper mechanism inprevious posts from this series. If you’re not familiar, this mechanism is used to provide credentials when accessing repositories that require them. Credential helpers translate between Git’scredential helper protocol and other applications likeKeychain.app, orlibsecret.

    However, HTTP authentication in Git is practically limited to protocols that require a username and password. For services that want to useBearer authentication, sensitive credentials can be stored in thehttp.extraHeader configuration option, which requires storing sensitive information in plaintext.

    Git 2.46 enhances the credential helper protocol with a few new tricks with its newauthtype andcredential fields. The protocol was also extended to support holding onto arbitrary state for each credential helper, as well as multi-round authentication for protocols like NTLM and Kerberos. Together, the new credential helper capabilities enable removing sensitive data from thehttp.extraHeader configuration, and pave the way for implementing protocols like NTLM and Digest.

    If you’re curious to learn more, you can check out some of the new protocol changeshere.

    [source]

  • Inour last post, we talked about Git’s preliminary support for a new kind of reference storage backend,reftable. Readers who are curious to learn about more of the details behind this new storage backend are encouraged to check out that post. But a high-level description is that reftable is a new, binary format for reference storage. It is designed to have near constant-time lookup for individual references, efficient lookup of the entire reference namespace through prefix compression, and atomic updates that scale with the size of the update, not the total number of pre-existing references.

    Reftable support is still evolving within Git. In our last update, we said that you can initialize a new repository with the reftable backend by runninggit init --ref-format=reftable /path/to/repo.git. In Git 2.46, you can now convert existing repositories to use the reftable backend by running the newgit refs migrate --ref-format=reftable command.

    Note that reftable support is still considered experimental, and thegit refs migrate command hassome known limitations when converting repositories to use the new reftable backend. But if you like to live on the bleeding edge, or have a repository that you have a non-reftable copy of, you can experiment with reftable today.

    [source]

  • If you’ve used Git long enough, you may have encountered some of its “advice” messages when performing subtle or unsafe operations, like checking out a detached HEAD state:

    $ git checkout HEAD^Note: switching to 'HEAD^'.You are in 'detached HEAD' state. You can look around, make experimentalchanges and commit them, and you can discard any commits you make in thisstate without impacting any branches by switching back to a branch.[...]

    These advice messages are meant to provide helpful tips when performing operations that may have unintended consequences (like committing on a detached head state, which makes it easier to lose your commits when not being careful). You can also disable different kinds of advice messages if you are comfortable with the potential consequences. In the above example, you can rungit config set advice.detachedHead false to tell Git to suppress the aforementioned advice message.

    But each advice message must be enabled or disabled individually. So, it can be a hassle when scripting, for example, to constantly maintain and update the list of different kinds of advice messages.

    In Git 2.46, Git has a new top-level option,--no-advice, which disables all advice messages. You can use this new option when scripting to avoid cluttering yourstderr output with advice messages like the above.

    [source]

  • Git has a comprehensive test suite written primarily in Shell scripts, containing tens of thousands of integration tests2. Though these Shell scripts have been an effective way to test many components of Git, they are not without drawbacks. They can be slower on platforms where the overhead to spawn new processes is higher, like Windows.

    They also can sometimes prove awkward for testing lower level components of Git, like its implementation of theprogress meter. For components like the progress meter, Git often implements a low-leveltest helper which can manipulate whatever component it is testing through a line-oriented protocol that can then bedriven from shell scripts.

    Git has begun to convert some of its integration tests to unit tests, making it easier to directly test some of Git’s lower level components. For some of the details on how these conversions have gone thus far, check out some of the source links below.

    [source,source,source,source,source,source,source,source,source]

The rest of the iceberg

That’s just a sample of changes from the latest release. For more, check out the release notes for2.46, orany previous version inthe Git repository.

Notes


  1. Both expensive to generate, and expensive to use. Expensive to generate because it necessarily means walking through more of history to generate*.bitmap files. But also expensive to use, since bitmaps areOR’d together, so having lots of bitmaps means we spend a lot of time decompressing those bitmaps and thenOR’ing them together at query time. 
  2. The exact number of tests varies based on what machine you’re running on, since some tests only run when certain packages are installed, or certain file system properties are met. On my machine, runningmake test ran more than 31,000 tests. 

Written by

Taylor Blau

Taylor Blau

@ttaylorr

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

Related posts

GitHub Copilot

For the Love of Code: a summer hackathon for joyful, ridiculous, and wildly creative projects

That idea you’ve been sitting on? The domain you bought at 2AM? A silly or serious side project? This summer, we invite you to build it — for the joy, for the vibes, For the Love of Code 🧡

Git

Git security vulnerabilities announced

Today, the Git project released new versions to address seven security vulnerabilities that affect all prior versions of Git.

Git

Highlights from Git 2.50

The open source Git project just released Git 2.50. Here is GitHub’s look at some of the most interesting features and changes introduced since last time.

Explore more from GitHub

Docs

Docs

Everything you need to master GitHub, all in one place.

Go to Docs
GitHub

GitHub

Build what’s next on GitHub, the place for anyone from anywhere to build anything.

Start building
Customer stories

Customer stories

Meet the companies and engineering teams that build with GitHub.

Learn more
GitHub Universe 2024

GitHub Universe 2024

Get tickets to the 10th anniversary of our global developer event on AI, DevEx, and security.

Get tickets

We do newsletters, too

Discover tips, technical guides, and best practices in our biweekly newsletter just for devs.


[8]ページ先頭

©2009-2025 Movatter.jp