This change introduces a non-recursive visible-parent resolver for commit graphs, indexes git file statuses for O(1) lookup in the Tauri backend, and reduces unnecessary status fetch / UI updates in the Svelte app.
What changed
Commit-graph parent resolution
Added src/lib/graphParents.ts which exports visibleParentResolver(items, visibleHashes).
HistoryPanel.svelte no longer uses the per-call recursive nearestVisibleGraphParents; it now calls visibleParentResolver once per rendering and uses the returned resolver function to expand parents.
The resolver traverses the DAG iteratively, preserves Git first-parent ordering, deduplicates converging paths, avoids per-path visited set allocations and prevents call-stack overflow for deep chains.
A new JS test script scripts/graph-parents.test.mjs exercises ordering, equivalence to the older traversal, stack-safety with 20000 hidden ancestors, shared-ancestry read-count behavior, and prints a small synthetic benchmark.
Git status lookup optimization (Tauri backend)
Replaced repeated find-style searches with file_status_index(statuses) in src-tauri/src/git.rs. The function builds a HashMap<&str, Option> mapping path and old_path aliases to the first matching status record.
repository_files_with_status now uses status_index.get(...).copied().flatten() when assembling tracked and untracked entries, preserving the original first-record-wins semantics and giving precedence to conflicted staged/unstaged states.
Added a Rust unit test file_status_index_preserves_rename_conflict_and_first_match_semantics to assert rename aliasing, conflict precedence, None entries, and absence behavior.
Background fetch / status handling (UI)
In src/App.svelte the background fetch flow captures the result of fetchRemote(path) into fetchedStatus and uses it directly (when present) instead of calling getStatus(path) unconditionally.
The dashboard/tab update path now short-circuits when the repo row hasn't changed (branch, ahead, behind, changed, lastOpened), avoiding unnecessary repoTabs updates and synchronous status cache serialization.
Background polling chooses a single code path to obtain the nextStatus (fetchRemote when fetchFirst, otherwise getStatus) to avoid duplicated work.
Testing
No test execution results were provided.
Recommended checks for reviewers
Run the new JS tests: node --test scripts/graph-parents.test.mjs (or your project test runner) and ensure they pass.
Run Rust unit tests: cd src-tauri && cargo test to execute file_status_index_preserves_rename_conflict_and_first_match_semantics and related tests.
Exercise the app background fetch behavior: trigger a background fetch for a repo where fetchRemote returns a GitStatus and verify the UI updates once and that the dashboard/tab state is not rewritten when unchanged.
Verify fetchRemote callers elsewhere still expect/return a GitStatus so the new fetchedStatus usage is consistent.
Compatibility / reviewer notes
The git.rs change is internal: it changes how statuses are looked up but preserves the prior semantics (first-match wins and rename aliases). The added test codifies those expectations.
The App.svelte change assumes fetchRemote may return a GitStatus; confirm that the runtime implementation of fetchRemote used in the project returns that type in the background-fetch contexts.
The visibleParentResolver replaces a local recursive helper with a shared iterative resolver. Reviewers should verify the HistoryPanel rendering remains correct (ordering and merged-parents behavior), and may run the included synthetic benchmark printed by the JS test to compare behavior.
If anything in fetchRemote's contract or other callers changed, call that out so we can adjust other call sites accordingly.
This change introduces a non-recursive visible-parent resolver for commit graphs, indexes git file statuses for O(1) lookup in the Tauri backend, and reduces unnecessary status fetch / UI updates in the Svelte app.
What changed
- Commit-graph parent resolution
- Added src/lib/graphParents.ts which exports visibleParentResolver(items, visibleHashes).
- HistoryPanel.svelte no longer uses the per-call recursive nearestVisibleGraphParents; it now calls visibleParentResolver once per rendering and uses the returned resolver function to expand parents.
- The resolver traverses the DAG iteratively, preserves Git first-parent ordering, deduplicates converging paths, avoids per-path visited set allocations and prevents call-stack overflow for deep chains.
- A new JS test script scripts/graph-parents.test.mjs exercises ordering, equivalence to the older traversal, stack-safety with 20000 hidden ancestors, shared-ancestry read-count behavior, and prints a small synthetic benchmark.
- Git status lookup optimization (Tauri backend)
- Replaced repeated find-style searches with file_status_index(statuses) in src-tauri/src/git.rs. The function builds a HashMap<&str, Option<FileStatusKind>> mapping path and old_path aliases to the first matching status record.
- repository_files_with_status now uses status_index.get(...).copied().flatten() when assembling tracked and untracked entries, preserving the original first-record-wins semantics and giving precedence to conflicted staged/unstaged states.
- Added a Rust unit test file_status_index_preserves_rename_conflict_and_first_match_semantics to assert rename aliasing, conflict precedence, None entries, and absence behavior.
- Background fetch / status handling (UI)
- In src/App.svelte the background fetch flow captures the result of fetchRemote(path) into fetchedStatus and uses it directly (when present) instead of calling getStatus(path) unconditionally.
- The dashboard/tab update path now short-circuits when the repo row hasn't changed (branch, ahead, behind, changed, lastOpened), avoiding unnecessary repoTabs updates and synchronous status cache serialization.
- Background polling chooses a single code path to obtain the nextStatus (fetchRemote when fetchFirst, otherwise getStatus) to avoid duplicated work.
Testing
- No test execution results were provided.
Recommended checks for reviewers
- Run the new JS tests: node --test scripts/graph-parents.test.mjs (or your project test runner) and ensure they pass.
- Run Rust unit tests: cd src-tauri && cargo test to execute file_status_index_preserves_rename_conflict_and_first_match_semantics and related tests.
- Exercise the app background fetch behavior: trigger a background fetch for a repo where fetchRemote returns a GitStatus and verify the UI updates once and that the dashboard/tab state is not rewritten when unchanged.
- Verify fetchRemote callers elsewhere still expect/return a GitStatus so the new fetchedStatus usage is consistent.
Compatibility / reviewer notes
- The git.rs change is internal: it changes how statuses are looked up but preserves the prior semantics (first-match wins and rename aliases). The added test codifies those expectations.
- The App.svelte change assumes fetchRemote may return a GitStatus; confirm that the runtime implementation of fetchRemote used in the project returns that type in the background-fetch contexts.
- The visibleParentResolver replaces a local recursive helper with a shared iterative resolver. Reviewers should verify the HistoryPanel rendering remains correct (ordering and merged-parents behavior), and may run the included synthetic benchmark printed by the JS test to compare behavior.
Files of interest (high level)
- Added: src/lib/graphParents.ts, scripts/graph-parents.test.mjs
- Modified: src/lib/components/HistoryPanel.svelte, src/App.svelte, src-tauri/src/git.rs
If anything in fetchRemote's contract or other callers changed, call that out so we can adjust other call sites accordingly.
Christoph
added 1 commit 2026-09-11 20:31:57 +00:00
Introduce an iterative visibleParentResolver for commit-graph rendering,
replacing a recursive traversal. It preserves first-parent ordering,
deduplicates converging paths, and avoids stack overflows; a test suite
validates correctness and performance. Additionally, streamline background
fetch handling in the UI to reuse fetchRemote's returned status and avoid
unnecessary status reads and tab invalidation, and refactor Git status
handling in Rust to build a file_status_index that preserves rename and
first-match semantics while speeding lookups.
- Add visibleParentResolver + comprehensive tests for ancestry handling
- Reuse fetchRemote result to apply status and skip unchanged updates
- Replace status_for_file with file_status_index to improve performance
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
This change introduces a non-recursive visible-parent resolver for commit graphs, indexes git file statuses for O(1) lookup in the Tauri backend, and reduces unnecessary status fetch / UI updates in the Svelte app.
What changed
Commit-graph parent resolution
Git status lookup optimization (Tauri backend)
Background fetch / status handling (UI)
Testing
Recommended checks for reviewers
Compatibility / reviewer notes
Files of interest (high level)
If anything in fetchRemote's contract or other callers changed, call that out so we can adjust other call sites accordingly.