Skip to content

Commit

Permalink
Add monthly report for January 2025
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Jan 18, 2025
1 parent 245f513 commit d674a43
Showing 1 changed file with 87 additions and 0 deletions.
87 changes: 87 additions & 0 deletions etc/reports/25-01.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
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](https://github.com/GitoxideLabs/gitoxide/pull/1410) 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](https://github.com/GitoxideLabs/gitoxide/issues/1771) 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()`](https://github.com/GitoxideLabs/gitoxide/pull/1763) 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](https://github.com/frewsxcv/rust-crates-index/issues/181).

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](https://github.com/GitoxideLabs/gitoxide/pull/1762) 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](https://github.com/GitoxideLabs/gitoxide/security/advisories/GHSA-fqmf-w4xh-33rh) was reported by our esteemed and valued [Eliah Kagan](https://github.com/EliahKagan).

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](https://github.com/GitoxideLabs/gitoxide/pull/1764/files#diff-d7db1a1b581fbe40817d40632c4aacfb6a280c7bc5c5a6532629b96f7100de19R292).

Thank you!

## Community

### Experimental support for `gix blame`!

Thanks to Christoph's fantastic work (*and incredible patience*), the long-standing [Blame-PR](https://github.com/GitoxideLabs/gitoxide/pull/1453) was finally merged so we can now try `gix blame` in the wild.

Until [this PR](https://github.com/GitoxideLabs/gitoxide/pull/1743) 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](https://github.com/mhagger/diff-slider-tools), 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](https://github.com/extrawurst/gitui) one day.

### Starship with light-speed!

`gix status` has now [been integrated](https://github.com/starship/starship/pull/6476) 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](https://github.com/GitoxideLabs/gitoxide/issues/1771) 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)](https://github.com/Byron/byron/blob/main/timesheets/2024.csv) and [here (2025)](https://github.com/Byron/byron/blob/main/timesheets/2025.csv).

0 comments on commit d674a43

Please sign in to comment.