Back to Gitoxide

25 01

etc/reports/25-01.md

0.53.07.2 KB
Original Source

Welcome back to the first month of 2025! The year definitely starts off well with a complete implementation of no other than… gix status.

gix status

For a while now there was gix status, but it was unable to see changes between HEAD^{tree} and the current index. This was now rectified and gix status can serve as early demonstration of the newfound powers.

A notable limitation is that sparse repositories aren't yet supported, even though it probably won't take too much to get that done, just because there weren't enough famous last words in these reports yet. And finally, besides performing favorably compared to git status, performance seems to be inconsistent on other platforms.

This will require more investigation and I can't wait to see it fixed, as overall having an even faster git status implementation is a big deal for a lot of tooling.

Upstream and Remote

Given a tracking branch name, like refs/remotes/origin/feature, the new method called Repository:: upstream_branch_and_remote_for_tracking_branch() will find the name of its upstream branch along with the matching remote. It is as unwieldy as it is powerful, as performing this feat isn't quite as easy splitting some strings on a slash and recombining them to match the names that will work 99% of the time.

To capture the remaining 1% of correctness one will have to reverse-map the refspecs of all remotes to obtain the upstream branch from the local tracking branch (which served as input). If the result is unambiguous, a match means we have found the remote as well.

Various improvements

Besides some features, I felt that considerable time was spent on bugfixes as well.

Better ObjectDatabase failures

The title sounds like there should be no failures at all, instead of having 'better' ones, but please hear me out :D, it's an issue initially discovered in rust-crates-index.

When fetching from a remote, a pack will be written if it's not empty (which is a corner case, but not the norm). Additionally, the refs will have to be updated which will check for the existence of the tips of the commits that were sent. And that, that will force the new pack to be loaded.

It's probably already clear what the problem is, but… it is not that the process runs into file descriptor limits, at least not yet. Before that, gitoxide object database runs into the limited amount of files it can manage as internally as it uses a fixed-length slotmap.

By default, the object database starts up with twice as many slots as it would need to fully load the repository, or at least 32. Previously, when these slots were exhausted, it would actually go into an invalid internal state and at best simply not find the new objects, and at the worst panic.

That invalid state of course was never intended, and now it will correctly return an error that clearly states it's out of slots. It's still, however, hard to recover from it right after a fetch and one would probably have to repeat said fetch even though one probably wouldn't receive the pack again.

Submodules with Worktrees

Git is known for having a feature for every occasion! And often, these can be combined. Sometimes, these combinations aren't naturally working well together.

Let's look at submodules. When creating one, a single submodule repository in .git/modules/<name> maps to its checkout in the working tree. As there is only one, it makes sense for the configuration in .git/modules/<name>/config to point to the worktree checkout via core.worktree.

However, it's also perfectly viable to add another worktree to an existing submodule. Now, what previously happened is that the so-called linked worktree would point at the submodule repository, and there it would transitively pick up the core.worktree configuration to lead it astray.

The fix makes sure that this particular configuration key isn't picked up if it belongs to a 'common' (or shared) Git repository.

Git repositories are complicated, and opening them is absolutely not trivial.

A security vulnerability with 'too many bits'

gitoxide can checkout files, and it does so quickly and thus far correctly. At least so I thought before this vulnerability was reported by our esteemed and valued Eliah Kagan.

It turns out that the umask only matters when creating a file particularly when handling executable bits. But when running chmod on it, one will have to figure out the correct mode oneself based on the current file mode. This inherently is a TOCTOU problem, but that's not the vulnerability.

The issue here was that gitoxide would change the mode of possibly existing (and even newly created) files to 755 if the checked-out blob was executable, making them world-readable and world-executable even, and that's not good.

Eliah even contributed a fix for it with some masterful bit-twiddling.

Thank you!

Community

Experimental support for gix blame!

Thanks to Christoph's fantastic work (and incredible patience), the long-standing Blame-PR was finally merged so we can now try gix blame in the wild.

Until this PR lands it will often be significantly slower than git blame though, and Git currently has a couple of tricks up its sleeve that assure it remains the best implementation for some time to come.

However, in terms of correctness it seems we are already close and mostly content with the slider problem, which should already make it useful for some. It's notable that this implementation should eventually support the streaming of blame information, a feature that will allow for entirely new workflows in Git user interfaces one day.

Starship with light-speed!

gix status has now been integrated into starship which allows it to be way more efficient by retrieving the file-based status information only once and sharing that among the git_status and git_metrics modules. So if both are enabled, only the first one that executes will cost time. And that time is typically much lower than what git status would do, yielding very noticeable performance improvements at least on MacOS.

The gix status performance issue might be a reason to not go to warp right away though.

Gix in Cargo

With gix status now available I am planning to integrate it as soon as possible!

Cheers Sebastian

PS: The latest timesheets can be found here (2024) and here (2025).