Skip to content

[01/08] add gitoxide boundary and typed OID alias storage dependencies#95

Open
mjc wants to merge 7 commits into
asinglebit:mainfrom
mjc:mjc/gitoxide-spike-01-gix-boundary
Open

[01/08] add gitoxide boundary and typed OID alias storage dependencies#95
mjc wants to merge 7 commits into
asinglebit:mainfrom
mjc:mjc/gitoxide-spike-01-gix-boundary

Conversation

@mjc

@mjc mjc commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Why this PR exists:

  • This PR introduces the dependency and module boundary foundations used by the rest of the gitoxide migration stack.
  • It adds gix plus related worktree crates so later PRs can read Git data through gitoxide instead of continuing to spread libgit2-shaped reads through the app.
  • It adds iddqd as the future typed-ID storage dependency for commit/OID aliasing.
  • It also adds the small support dependencies needed by the upcoming graph/alias work: rustc-hash and smallvec.
  • It keeps interactive behavior unchanged; the only app-facing addition is the benchmark-only --exit-when-graph-complete flag used to measure the stack consistently.

What changed in this PR:

  • Adds the gitoxide dependency set:
    • gix
    • gix-worktree
    • gix-worktree-state
  • Adds future compact identity-storage dependencies:
    • iddqd
    • rustc-hash
    • smallvec
  • Adds src/git/gix.rs as the initial gitoxide boundary module.
  • Exposes git::gix from src/lib.rs.
  • Exposes git::test_support under #[cfg(test)] and moves shared test fixture helpers behind that boundary so later PRs can reuse them without expanding production behavior.
  • Adds small compatibility helpers touched by the setup work, including branch-name visibility/localisation test support.
  • Adds the benchmark-only --exit-when-graph-complete CLI path and graph-completion wait helper.
  • Updates Cargo.lock for the new dependency graph.

What the new git::gix boundary currently contains:

  • A shared history object-cache size constant.
  • A helper to enable the history object cache on a gix::Repository.
  • Commit-graph access helpers and a commit-count hint.
  • A branch-tip iterator for local and remote branches.
  • A small adapter for converting gitoxide errors into the existing git2::Error shape.

What iddqd is for, in a follow-on PR:

The graph pipeline needs to refer to the same commits from multiple layers: walker, batcher, buffer, renderer, heatmap, app state, and query integration.

Passing raw Git object IDs everywhere would keep cloning, hashing, comparing, and converting object IDs across those layers. It would also leak the libgit2/gitoxide boundary into too many call sites.

The intended follow-up is to store each commit object ID once and pass a small typed alias through the rest of the app. iddqd is added here so that storage choice can be reviewed separately from the later behavior migration.

Algorithm difference:

  • Adds dependency and helper wiring only.
  • Adds the initial gitoxide boundary module.
  • Adds shared test-support wiring used by later stack layers.
  • Adds a benchmark-only headless completion path so every branch can be timed the same way.
  • Does not change interactive graph walking.
  • Does not change query behavior.
  • Does not change rendering behavior.
  • Does not change mutating Git actions.
  • Does not yet introduce the actual commit alias map.

Performance story:

  • Enabling branch only; no direct interactive runtime win is claimed here.
  • The headless completion flag exists so the whole stack can be measured consistently without opening the TUI.

Benchmark Results for the whole stack

Command shape: hyperfine --warmup 5 './target/release/guitar /home/mjc/src/linux --exit-when-graph-complete'.

CPU: M1 MacBook Pro 16GB

Ref Total vs main User System CPU
main 2:37.28 1.00x 118.00s 7.88s 80%
01-gix-boundary 1:43.99 1.51x 97.85s 2.33s 96%
02-gix-oids 1:14.26 2.12x 65.41s 2.17s 91%
03-graph-walker 5.816s 27.05x 1.82s 0.74s 43%
04-queries-readonly 3.812s 41.26x 1.47s 0.42s 49%
05-actions-network 1.993s 78.91x 1.47s 0.26s 87%
06-app-integration 1.826s 86.13x 1.51s 0.10s 88%
06-app-integration 1.879s 83.70x 1.44s 0.11s 82%
07-draw-status 1.618s 97.21x 1.36s 0.08s 89%

CPU: 5950x Linux/ZFS

Ref Total vs main User System CPU
main 1:39.24 1.00x 96.16s 1.72s 98%
01-gix-boundary 1:46.41 0.93x 101.28s 3.82s 98%
02-gix-oids 1:10.85 1.40x 69.07s 1.78s 100%
03-graph-walker 2.094s 47.39x 1.59s 0.55s 102%
04-queries-readonly 1.856s 53.47x 1.58s 0.46s 110%
05-actions-network 1.862s 53.30x 1.60s 0.49s 112%
06-app-integration 1.639s 60.55x 1.40s 0.22s 98%
07-draw-status 1.632s 60.81x 1.34s 0.18s 93%
08-bench-docs 1.629s 60.92x 1.36s 0.19s 94%

Memory: 5950x Linux/ZFS

Ref Peak heap Peak RSS
main 1.26G 2.81G
01-gix-boundary 1.26G 2.82G
02-gix-oids 1.38G 2.63G
03-graph-walker 455.13M 1.15G
04-queries-readonly 436.12M 977.18M
05-actions-network 436.12M 978.61M
06-app-integration 419.89M 853.30M
07-draw-status 419.89M 916.59M
08-bench-docs 419.89M 988.71M

mjc added 7 commits July 1, 2026 12:35
(cherry picked from commit 122fdf1)
Wire a no-TUI entry point that loads the repo, skips workdir status to avoid
case-colliding paths on case-insensitive filesystems, waits for the graph
walker to finish, prints the commit count, and shuts down background tasks.
Copilot AI review requested due to automatic review settings July 1, 2026 21:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR lays the groundwork for a staged migration toward gitoxide by introducing a dedicated git::gix boundary module and adding the dependency set needed for upcoming graph/alias work. It also centralizes common Git test fixtures under git::test_support and adds a benchmark-only headless mode (--exit-when-graph-complete) to consistently measure graph completion.

Changes:

  • Add gitoxide-related dependencies (gix, gix-worktree, gix-worktree-state) plus future typed-ID storage deps (iddqd, rustc-hash, smallvec).
  • Introduce src/git/gix.rs as the initial gitoxide boundary and expose it via src/lib.rs.
  • Add benchmark-only graph-completion waiting/shutdown helpers and refactor tests to use shared git::test_support helpers (including a language guard).

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/tests/helpers/localisation.rs Uses shared language guard and switches temp language file creation to tempfile.
src/tests/helpers/keymap.rs Uses shared language guard to avoid cross-test localisation leakage.
src/tests/git/queries/remotes.rs Uses shared init_repo_at test helper for consistent repo setup.
src/tests/git/queries/diffs.rs Uses shared init_repo_at in temp repo helper; renames local seeded init helper.
src/tests/git/actions/reverting.rs Uses shared init_repo_at test helper for consistent repo setup.
src/tests/git/actions/rebasing.rs Uses shared init_repo_at test helper for consistent repo setup.
src/tests/git/actions/merging.rs Uses shared init_repo_at test helper for consistent repo setup.
src/tests/git/actions/cherrypicking.rs Uses shared init_repo_at test helper for consistent repo setup.
src/tests/git/actions/branching.rs Uses shared init_repo_at test helper for consistent repo setup.
src/tests/core/graph_service.rs Uses shared init_repo_at test helper for consistent repo setup.
src/tests/app/state/app.rs Adds tests for wait_until_graph_complete behavior.
src/tests/app/input/navigation.rs Uses shared init_repo_at and language guard in settings-language test.
src/tests/app/input/git.rs Uses shared init_repo_at test helper for consistent repo setup.
src/tests/app/draw/settings.rs Uses shared language guard for localisation-dependent rendering assertions.
src/main.rs Adds --exit-when-graph-complete mode and argument-to-repo-path parsing.
src/lib.rs Exposes git::gix and (test-only) git::test_support.
src/helpers/branch_visibility.rs Adds byte-slice refname parsing helper for gitoxide reference names.
src/git/test_support.rs Introduces reusable test fixtures for repos, worktrees, commits, and localisation guard.
src/git/gix.rs Adds initial gitoxide boundary utilities (commit-graph hint, branch tip iteration, error adapter).
src/app/app.rs Adds bootstrap helper, graph completion waiting, and background graph shutdown logic; improves disconnect handling in sync().
Cargo.toml Adds new dependencies for gitoxide and upcoming typed-ID/graph work.
Cargo.lock Updates lockfile for the new dependency graph.
Comments suppressed due to low confidence (1)

src/tests/git/queries/diffs.rs:66

  • init_seeded_repo_at uses Repository::init, which can pick the initial branch name from the developer/CI Git config (e.g. init.defaultBranch). That makes these tests less deterministic than the new shared test_support::init_repo_at, which pins the initial HEAD.

To keep submodule fixtures consistent across environments, reuse crate::git::test_support::init_repo_at here instead of Repository::init + manual user config.

fn init_seeded_repo_at(path: &Path) -> Repository {
    fs::create_dir_all(path).unwrap();
    let repo = Repository::init(path).unwrap();
    {
        let mut config = repo.config().unwrap();

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mjc

mjc commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

I did say I'd get around to this, so here we are!

There is still a bunch of libgit2 left to remove/narrow around diffs etc but I did the hardest bits in this 8-stack.

Sorry about how massive it is, but that was really unavoidable.

I will happily help get it all ship-shape and mergeable.

the test linux kernel repo I used is 2.3 million commits, 44 remotes.

libgit2's worktree support is the one relevant area where gitoxide/gix are not full-featured enough. So dumping it entirely will take quite a lot more work.

Happy to answer any questions or help in any way.

The CLI flag I added isn't required but it made profiling and heaptracking startup much easier...

@mjc

mjc commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

also - the later PRs look huge because they contain all the previous PRs in the stacks' changes. as these get merged they should get easier to review.

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.

2 participants