Skip to content

Add gitoxide as Git backend - #96

Merged
lukaslueg merged 3 commits into
lukaslueg:masterfrom
Byron:master
Jan 4, 2026
Merged

Add gitoxide as Git backend#96
lukaslueg merged 3 commits into
lukaslueg:masterfrom
Byron:master

Conversation

@Byron

@Byron Byron commented Jan 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #66

Highlights

  • The actual implementation is very simple
  • The git2 implementation was simplified and I find the whole implementation easier to understand than before.
  • Integration tests are made to test all available Git backends at once.
    • Note that it seems the feature-gate around these testbox tests isn't required, but I left that unchanged.

Shortcomings

  • gix needs Rustc v1.82, but built is on v1.81. That's not a problem as long as gix` isn't the default.
    • strangely enough, git2 pulls in url which has dependencies that need v1.83 by now, but CI doesn't have issues.
  • The performance in relation to overrides isn't optimal. To fix this, one would have to split get_repo_description() into dirty and tag. This is inherited though, and that could be fixed in a follow-up. Right now, if dirty is overridden, but not tag, it would still compute dirty but ignore the computed value.
  • Thanks to a lack of release build mode for build scripts, gix might be slower for describe() than it has to be. I'd be OK with this for now, thinking that one day they might build these scripts in release mode or make that configurable.

Tasks

  • impl
  • unit-tests
  • integration tests pass
  • make sure there is gix-specific integration tests
  • address PR review

@Byron Byron left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is best reviewed with Hide Whitespace enabled.

Image

PS: It's interesting that CI runs for the previous commit but won't for the one I just force-pushed for a minor adjustment.

Comment thread .github/workflows/check.yml Outdated
Comment on lines +43 to +60
check-gix:
name: cargo check (gix)
runs-on: ubuntu-latest
strategy:
matrix:
toolchain:
# It should always run on stable
- stable
# 1.82 is the MSRV of `gix`, but 1.83 is needed for icu_collections and friends, which is pulled in by `git2` via `url`.
- "1.83"
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.toolchain }}
- run: cargo check --no-default-features --features gix
- run: cargo check --all-features

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this could go away if built could upgrade to an MSRV of v1.82.

Comment thread .github/workflows/check.yml Outdated
strategy:
matrix:
toolchain: [stable, "1.83"]
toolchain: [ stable, "1.83" ]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wasn't intentional, but an IDE thing that I just now noticed.

Comment thread src/git.rs Outdated
///
/// # Errors
/// Errors from `git2` are returned if the repository does exists at all.
/// or if any operation on the repository fails, `None` is returned.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was done as the error was always ignored, so it's easier to go with Option from the beginning.

Comment thread src/lib.rs
Comment on lines +356 to +360
//! /// Can be overridden using `BUILT_OVERRIDE_{pkg_name}_GIT_COMMIT_HASH_SHORT`.
//! pub static GIT_COMMIT_HASH_SHORT: Option<&str> = Some("ca2af4f");
//! ```
//!
//! ### `gix`

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started out with Copilot, but replaced everything except for these docs. Maybe review extra diligently, they might have subtle errors.

- Added gix dependency with minimal features (max-performance-safe)
- Created git_shared module to share code between git2 and gix
- Implemented gix-based git operations in new gix module
- git2 takes priority when both features are enabled
- Tests pass for both implementations
- Adjusted integration tests to validate `gix` as well.
- Document gix as alternative to git2 for git operations
@lukaslueg

Copy link
Copy Markdown
Owner

Thanks for the PR! Some nits:

  • We can bump MSRV all the way to 1.85, in order to accommodate Bump cargo-lock to 11.0 #95 as well; no need to actually bump dependencies in this PR.
  • I'd prefer to keep get_repo_description() -> Result<Option<>> instead of swallowing errors as in -> Option (same for get_repo_head). Even if errors are ultimately ignored by the caller, the functions themselves should not make that decision; especially because those functions are part of the public API.
  • Am I correct to understand that the "dirty detection" through gix now works the same way as libgit2? There was some discussion about this way back...

Could you make these changes?

@Byron

Byron commented Jan 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks a lot for the timely review! I will be hitting the keyboard to address it in a separate commit.

  • We can bump MSRV all the way to 1.85, in order to accommodate Bump cargo-lock to 11.0 #95 as well; no need to actually bump dependencies in this PR.

Great, I will bump it to 1.85 and remove the CI special case.

  • Am I correct to understand that the "dirty detection" through gix now works the same way as libgit2? There was some discussion about this way back...

Yes, that's all good now. And I say that with the disclaimer that I have no memory about that discussion whatsoever.

  • I'd prefer to keep get_repo_description() -> Result<Option<>> instead of swallowing errors as in -> Option (same for get_repo_head). Even if errors are ultimately ignored by the caller, the functions themselves should not make that decision; especially because those functions are part of the public API.

Ouch, sorry for that. I didn't realise these were public, but now saw that they are (quite sneakily) exported via the util module. For a moment I thought I should provide similar methods with gix, but that won't be possible after all as it exposes the git2::Error type.
And while there probably can be a solution for this, I suppose that can be figured out in a follow-up once there is demand.
Meanwhile, I will just restore the original signature for the git2 version.

Tasks

  • msrv to 1.85
  • revert git2 function signature and implementation.

@Byron
Byron force-pushed the master branch 2 times, most recently from 6ea30ea to 8105273 Compare January 3, 2026 15:51
@Byron

Byron commented Jan 3, 2026

Copy link
Copy Markdown
Contributor Author

Under the assumption that CI is green this could be it.

But please also let me note that I am not at all sure that I have implemented the MSRV change correctly, as there is some special sauce that I probably got wrong. Thus I hope you could finish the MSRV change for me if adjustments are needed, you should be able to push straight into my branch, and that works automatically if you checked out with gh pr checkout 96.

Thanks again, I am excited to see this long-standing effort to finally come to fruition.

PS: Please do feel free to rewrite my commits as well or squash them, my signature isn't important.

@lukaslueg
lukaslueg merged commit b86b1ba into lukaslueg:master Jan 4, 2026
13 checks passed
@lukaslueg

Copy link
Copy Markdown
Owner

Thanks for the PR.

I'm going to make some changes on top of this. Critically, CI currently does not actually execute the git-tests at all with only the gix-feature enabled, as git2 is needed for setup (--features gix compiles but does not execute any git-specific tests)

@Byron

Byron commented Jan 5, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for merging!

I didn't have time to double-check this, but not running gix specific integration tests when gix is set would be a major bug that I would have expected to catch.

And from all I can tell, gix is executed with cargo test --features gix and cargo test --features gix --no-default-features

These correspond to the following lines in the CI configuration:

  - run: cargo test --no-default-features --features gix
  - run: cargo test --no-default-features --features git2
  - run: cargo test --all-features

The --all-features one will also run unit-tests for gix and not for git2. Maybe something else is missing, but I think the coverage is already there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Could be possible to switch to gix?

2 participants