Skip to content

perf: Remove libgit2/git2 dependency, replace with gix-object#12015

Merged
anthonyshew merged 2 commits into
mainfrom
shew/remove-libgit2
Feb 26, 2026
Merged

perf: Remove libgit2/git2 dependency, replace with gix-object#12015
anthonyshew merged 2 commits into
mainfrom
shew/remove-libgit2

Conversation

@anthonyshew

Copy link
Copy Markdown
Contributor

Summary

  • Remove git2 and libgit2-sys entirely from the dependency tree
  • Replace blob hashing with gix-object::compute_hash (already compiled transitively — zero new crates)
  • Collapse all #[cfg(feature = "git2")] dual codepaths into single implementations
  • Add regression test verifying blob hash output matches git hash-object

Why

libgit2-sys was a 25-second serial C compilation sitting on the critical build path. Every crate downstream of turborepo-scm was blocked waiting for it. Since gix-object is already in the dependency tree (via gix-index), this change removes 25s of serial C compilation with zero new crate additions.

What changed

Production code: The codebase already had CLI fallbacks (git subprocess calls) for every git2 operation — branch detection, SHA queries, ls-tree, status, worktree discovery. The git2 paths were just in-process optimizations. This PR removes the git2 paths and keeps the CLI paths as the sole implementation. The one exception is blob hashing (hash_object.rs) which now uses gix_object::compute_hash instead of git2::Oid::hash_file.

repo_index.rs: The gix-index path (reading .git/index directly) was already the preferred path with libgit2 as fallback. Now it's the only path.

turborepo-boundaries: Drops the gitignore check (status_should_ignore) which was already the fallback behavior when git2 was disabled. The glob patterns already exclude node_modules.

Tests: All git2 test fixtures replaced with Command::new("git") subprocess calls. Added test_blob_hash_matches_git_hash_object regression test that verifies empty files, text files, binary files, and large files all produce OIDs identical to git hash-object.

For reviewers

The -771 +289 line delta is mostly deletion of git2 codepaths that had CLI equivalents. The test_merge_base test needed git reset --soft instead of git checkout --detach to match git2's set_head_detached behavior (moves HEAD without resetting the working tree).

Remove the git2 and libgit2-sys dependencies entirely. libgit2-sys was a
25-second serial C compilation on the critical build path — the single
largest bottleneck in the build.

Production code changes:
- hash_object.rs: Replace git2::Oid::hash_file with gix_object::compute_hash
  (gix-object was already compiled transitively, zero new crates added)
- Remove all #[cfg(feature = "git2")] conditional compilation
- Collapse dual codepaths (git2 + CLI) into single CLI codepaths for
  ls-tree, status, worktree detection, and branch/SHA queries
- repo_index.rs: Use gix-index path unconditionally (was already preferred)
- turborepo-boundaries: Drop gitignore check (was already the fallback)

Test changes:
- Replace all git2 test fixtures with git CLI subprocess calls
- Add regression test verifying blob hashes match `git hash-object`
@anthonyshew anthonyshew requested a review from a team as a code owner February 26, 2026 21:21
@anthonyshew anthonyshew requested review from tknickman and removed request for a team February 26, 2026 21:21
@vercel

vercel Bot commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
examples-basic-web Ready Ready Preview, Comment, Open in v0 Feb 26, 2026 9:29pm
examples-designsystem-docs Ready Ready Preview, Comment, Open in v0 Feb 26, 2026 9:29pm
examples-gatsby-web Ready Ready Preview, Comment, Open in v0 Feb 26, 2026 9:29pm
examples-kitchensink-blog Ready Ready Preview, Comment, Open in v0 Feb 26, 2026 9:29pm
examples-nonmonorepo Ready Ready Preview, Comment, Open in v0 Feb 26, 2026 9:29pm
examples-svelte-web Ready Ready Preview, Comment, Open in v0 Feb 26, 2026 9:29pm
examples-tailwind-web Ready Ready Preview, Comment, Open in v0 Feb 26, 2026 9:29pm
examples-vite-web Ready Ready Preview, Comment, Open in v0 Feb 26, 2026 9:29pm
turbo-site Ready Ready Preview, Comment, Open in v0 Feb 26, 2026 9:29pm
turborepo-agents Ready Ready Preview, Comment, Open in v0 Feb 26, 2026 9:29pm
turborepo-test-coverage Ready Ready Preview, Comment, Open in v0 Feb 26, 2026 9:29pm

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

Metric Coverage
Lines 78.35%
Functions 49.91%
Branches 0.00%

View full report

@anthonyshew anthonyshew enabled auto-merge (squash) February 26, 2026 22:00
@anthonyshew anthonyshew merged commit fbf50e5 into main Feb 26, 2026
76 of 79 checks passed
@anthonyshew anthonyshew deleted the shew/remove-libgit2 branch February 26, 2026 22:05
github-actions Bot added a commit that referenced this pull request Feb 27, 2026
## Release v2.8.12-canary.3

Versioned docs: https://v2-8-12-canary-3.turborepo.dev

### Changes

- fix: Prevent peerDependencies from overwriting concrete dependency
specifiers (#12004) (`a038409`)
- ci: Trigger prysk integration tests via `cargo nextest` (#11999)
(`2053ede`)
- release(turborepo): 2.8.12-canary.2 (#12005) (`dccfdf0`)
- fix: Resolve correct nested package version in bun lockfile pruning
(#12008) (`95dff45`)
- refactor: Replace shell-based fixture setup with pure Rust (#12006)
(`a743e38`)
- fix: Resolve all lockfile pruning test failures (#12009) (`21dcaed`)
- perf: Extract query module into turborepo-query crate (#12007)
(`0604379`)
- refactor: Migrate dry-json prysk tests to Rust + insta snapshots
(#12010) (`2606f3f`)
- perf: Deduplicate petgraph, fixedbitset, and dashmap (#12011)
(`9b11ef6`)
- refactor: Migrate persistent-dependencies and task-dependencies to
Rust + insta (#12012) (`9aab7b5`)
- test: Add lockfile-tests fixture for issue #12013 (#12014) (`bae81f7`)
- perf: Remove libgit2/git2 dependency, replace with gix-object (#12015)
(`fbf50e5`)
- refactor: Migrate daemon, jsonc, query, edit-turbo-json tests to Rust
(#12016) (`bf730d5`)
- perf: Remove async-graphql from turborepo-lib (#12017) (`7c8a4a0`)
- refactor: Migrate inference and run-logging tests to Rust (#12018)
(`dc4f922`)
- refactor: Migrate run-caching and strict-env-vars tests to Rust
(#12020) (`c07645d`)
- fix: Mark lockfile-aware-caching/bun prysk test as flaky (#12021)
(`c60f0c1`)
- fix: Add nextest retries for flaky tests (#12027) (`9d90270`)
- refactor: Migrate prune and run-summary tests to Rust (#12022)
(`329bdb5`)
- ci: Increase Rust test partitions from 4 to 10 (#12028) (`0c1bd47`)
- fix: Add nextest retries for flaky prysk tests (#12030) (`9b66431`)
- ci: Use larger runners for macOS Rust tests (#12029) (`9479a54`)
- fix: Add nextest retries for flaky
prune_test::test_prune_composable_config (#12032) (`b47e099`)
- fix: Suppress npm upgrade notices in Rust integration tests (#12033)
(`f698b04`)
- ci: Disable flaky Rust unit tests from release pipeline (#12034)
(`829b351`)

---------

Co-authored-by: Turbobot <turbobot@vercel.com>
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.

1 participant