Skip to content

[02/08] replace commit identity storage with gix-backed aliases#96

Open
mjc wants to merge 15 commits into
asinglebit:mainfrom
mjc:mjc/gitoxide-spike-02-gix-oids
Open

[02/08] replace commit identity storage with gix-backed aliases#96
mjc wants to merge 15 commits into
asinglebit:mainfrom
mjc:mjc/gitoxide-spike-02-gix-oids

Conversation

@mjc

@mjc mjc commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Stacked on mjc/gitoxide-spike-01-gix-boundary.

Why this PR exists:

  • PR 1 added the gitoxide and iddqd dependencies.
  • This PR starts using them for commit identity storage.
  • The old Oids structure stored raw git2::Oid values in a Vec and used a HashMap<git2::Oid, u32> for alias lookup.
  • This PR moves the internal OID store to gix::ObjectId, stores alias records in an iddqd::IdHashMap, and keeps the public alias path centered on small u32 aliases.
  • The app still has git2 call sites, so this is not a full gitoxide migration yet. It is the commit-identity storage layer that lets later PRs keep moving the graph/query code toward gix-backed data.

What changed:

  • Replaces Oids internals with:
    • gix::ObjectId for stored object IDs.
    • IdHashMap<OidRecord> for OID → alias lookup.
    • Vec<ObjectId> for alias → OID lookup.
  • Adds explicit git2gix OID conversion helpers.
  • Adds IntoGixOid so existing git2::Oid call sites can cross the boundary while the rest of the stack is migrated.
  • Adds get_existing_alias for non-interning alias lookup.
  • Adds get_alias_by_prefix so SHA-prefix navigation can find an existing alias without stringifying and reinserting OIDs.
  • Adds reserve/shrink helpers for alias storage.
  • Updates app, graph service, walker, worktree, stash, navigation, and reflog paths to use the new alias APIs instead of directly reading oids/aliases.
  • Updates heatmap generation to build from sorted aliases instead of directly reading the old raw OID vector.

Algorithm difference:

  • Commit identity is still represented externally by small aliases in graph/UI structures.
  • The backing identity store is now gix::ObjectId plus typed iddqd records instead of git2::Oid plus a standard hash map.
  • Existing git2 behavior is preserved by converting back to git2::Oid at remaining git2 call sites.
  • SHA-prefix lookup now validates hex input and compares prefix nibbles directly against stored object bytes instead of allocating/stringifying OIDs.
  • Heatmap counting now uses fixed-size count arrays for the 53-week grid and can also be fed through a streaming HeatmapCounts helper.
  • Graph ordering, alias identity, stash/reflog/worktree lookup, parent/child navigation, and heatmap semantics are intended to remain equivalent.

Performance story:

  • This should reduce OID churn in the identity layer by centralizing OID ownership and avoiding repeated direct access to raw git2::Oid collections.
  • Prefix lookup avoids to_string().starts_with(...) scans and uses byte/nibble comparison instead.
  • Heatmap counting now avoids an intermediate map and uses a fixed-size array for the rendered grid.
  • No whole-app speedup is claimed here. Any runtime win should be measured in the later graph/query PRs.

Benchmark Results for this PR

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
02-gix-oids 1:14.26 2.12x 65.41s 2.17s 91%

CPU: 5950x Linux/ZFS

Ref Total vs main User System CPU
02-gix-oids 1:10.85 1.40x 69.07s 1.78s 100%

Memory: 5950x Linux/ZFS

Ref Peak heap Peak RSS
02-gix-oids 1.38G 2.63G
Top 10 heaptrack allocation sites for `02-gix-oids`
  1. 18210838 calls, 70.52M peak - git__calloc
  2. 17431852 calls, 21.44M peak - git__substrdup
  3. 6613871 calls, 18.44M peak - commit_parse
  4. 4576967 calls, 0B peak - inflateInit2_
  5. 4514697 calls, 265.92M peak - git__strndup
  6. 4209519 calls, 279.42K peak - git_commit_list_insert
  7. 2765451 calls, 366.68M peak - alloc::raw_vec::RawVecInner<>::finish_grow
  8. 2096782 calls, 0B peak - git_commit_list_insert_by_date
  9. 847866 calls, 472.20K peak - git_delta_apply
  10. 484765 calls, 24.61M peak - alloc::sync::Arc<>::make_mut

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 begins the migration of commit-identity storage from git2::Oid to a gitoxide-friendly representation by backing the alias store with gix::ObjectId and iddqd::IdHashMap, while keeping the external identity model as compact u32 aliases. It also updates SHA-prefix lookup and heatmap generation to avoid allocation-heavy OID stringification, and introduces test infrastructure to stabilize language/global state and git repo fixtures.

Changes:

  • Replaced core::oids::Oids internals with gix::ObjectId storage + iddqd-backed alias records, with explicit git2gix conversion and a transitional IntoGixOid boundary.
  • Reworked SHA-prefix navigation to validate hex input and match against OID bytes/nibbles (no to_string() scanning / reinterning).
  • Updated heatmap counting to use fixed-size arrays (and a streaming HeatmapCounts helper), and adjusted graph/app/test call sites accordingly.

Reviewed changes

Copilot reviewed 33 out of 34 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/tests/helpers/localisation.rs Uses stable tempfile paths and adds a language guard to prevent global-language test interference.
src/tests/helpers/keymap.rs Adds language guard and removes manual language reset in keymap localisation test.
src/tests/helpers/heatmap.rs Adds tests for new heatmap counting + streamed helper + prefix matching behavior.
src/tests/git/queries/remotes.rs Switches test repos to shared init_repo_at fixture.
src/tests/git/queries/diffs.rs Switches test repos to shared init_repo_at fixture and renames a local seeded init helper.
src/tests/git/actions/reverting.rs Switches test repos to shared init_repo_at fixture.
src/tests/git/actions/rebasing.rs Switches test repos to shared init_repo_at fixture.
src/tests/git/actions/merging.rs Switches test repos to shared init_repo_at fixture.
src/tests/git/actions/cherrypicking.rs Switches test repos to shared init_repo_at fixture.
src/tests/git/actions/branching.rs Switches test repos to shared init_repo_at fixture.
src/tests/core/walker.rs Updates tests to use new OID alias APIs (get_existing_alias, non-reference OID access).
src/tests/core/oids.rs Adds focused tests for aliasing and prefix lookup without reinterning.
src/tests/core/graph_service.rs Switches test repos to shared init_repo_at fixture.
src/tests/app/state/app.rs Adds tests for wait_until_graph_complete success and error modes.
src/tests/app/input/navigation.rs Switches test repos to shared init_repo_at fixture and adds language guard for language selection test.
src/tests/app/input/git.rs Switches test repos to shared init_repo_at fixture.
src/tests/app/draw/settings.rs Adds language guard to settings shortcut localisation rendering test.
src/main.rs Adds --exit-when-graph-complete mode and CLI repo path handling for benchmarking/scripted runs.
src/lib.rs Exposes new git::gix module and test-only git::test_support.
src/helpers/heatmap.rs Replaces map-based heatmap counting with fixed-size arrays + HeatmapCounts, and adds sorted-alias heatmap builder.
src/helpers/branch_visibility.rs Adds byte-slice refname parsing helper for gix-backed reference iteration.
src/git/test_support.rs Introduces centralized test fixtures (repo init, commits, worktrees, submodules, temp paths, language guard).
src/git/gix.rs Adds small gix integration helpers (object cache, commitgraph hint, branch tip iteration, error mapping).
src/core/walker.rs Updates walker call sites to handle OIDs as values (no deref) after Oids API changes.
src/core/oids.rs Implements new gix-backed alias store, conversion helpers, reserve/shrink helpers, and nibble-based prefix matching.
src/core/graph_service.rs Switches heatmap building to sorted aliases and updates lookup paths to use new alias/prefix APIs.
src/app/input/worktrees.rs Updates worktree selection logic to use get_existing_alias instead of direct map access.
src/app/input/navigation.rs Updates parent/child navigation to use value OIDs and get_existing_alias.
src/app/input/modals.rs Replaces SHA search via stringified OIDs with get_alias_by_prefix.
src/app/input/git.rs Updates stash-related OID retrieval to new value-returning Oids API.
src/app/draw/stashes.rs Updates stash rendering to use value OIDs (no deref).
src/app/app.rs Adds bootstrap/shutdown helpers, adds wait_until_graph_complete, and makes sync resilient to graph channel disconnects.
Cargo.toml Adds gitoxide/iddqd dependencies (gix, iddqd, etc.) and supporting crates.
Cargo.lock Locks new dependency graph for gix/iddqd and transitive additions.

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

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