Skip to content

[07/08] update draw/status surfaces for migrated graph and metadata caches#101

Open
mjc wants to merge 63 commits into
asinglebit:mainfrom
mjc:mjc/gitoxide-spike-07-draw-status
Open

[07/08] update draw/status surfaces for migrated graph and metadata caches#101
mjc wants to merge 63 commits into
asinglebit:mainfrom
mjc:mjc/gitoxide-spike-07-draw-status

Conversation

@mjc

@mjc mjc commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Stacked on mjc/gitoxide-spike-06-app-integration.

Why this PR exists:

  • Earlier stack layers moved graph walking, query/action plumbing, and app state onto the new migrated data flow.
  • This PR updates the rendering side so graph, status, statusbar, and related draw surfaces consume those migrated app/cache shapes efficiently.
  • The main goal is to preserve the displayed UI while changing where draw code gets its data:
    • cached graph windows
    • graph projection cache
    • app-held worktree/head metadata
    • split uncommitted summary/detail state
    • path/lazy-repo app integration from the previous layer

What changed:

  • Refactors graph drawing around explicit graph-window preparation and rendering.
  • Changes draw_graph to accept Option<&git2::Repository> so the graph can still render cached/loading/empty states without forcing every path to have an eager repo handle.
  • Uses GraphProjectionCache and GraphProjectionKey to avoid rebuilding message projection when the graph version, visible range, selected row, label toggles, uncommitted-row mode, and status counts have not changed.
  • Splits graph rendering into smaller helpers for:
    • visible-window calculation
    • unborn/empty graph rendering
    • cached projection lookup
    • graph row widget construction
    • scrollbar rendering
    • search highlighting
  • Refactors status-pane rendering around reusable row builders:
    • loading rows
    • empty rows
    • conflict rows
    • staged/unstaged file rows
    • selected-commit diff rows
  • Adds explicit status-pane state handling for uncommitted summary vs uncommitted detail loading.
  • Prevents unstaged detail rendering from pretending it is loaded before detail status has arrived.
  • Rewrites statusbar rendering so it no longer needs to query a live repo during draw.
  • Statusbar head/branch/detached state now comes from cached current worktree/head metadata.
  • Statusbar branch/tag/stash/reflog counts now prefer cached graph pane windows when available.
  • Reworks submodule stack display as spans instead of one preformatted label string.
  • Keeps action-mode and zen-mode indicators in the statusbar, but builds them through helper iterators.
  • Updates app draw dispatch so draw_statusbar no longer takes a repo argument.
  • Updates inspector reflog rendering for the current cached reflog timestamp shape.
  • Updates settings/graph/status/statusbar/title draw surfaces and tests for the migrated metadata shapes.
  • Updates helper behavior:
    • symbol-theme loading no longer rewrites the symbol config just because it parsed successfully.
    • wrap_words avoids cloning when width is zero.
    • title rendering avoids an unnecessary file-name clone.

Algorithm difference:

  • Graph drawing now separates “prepare visible window” from “render cached/projected rows.”
  • Projection cache invalidation is explicit through GraphProjectionKey.
  • Status rendering now builds a pane model first, then renders the pane from that model.
  • Status empty/loading/selectable state is computed from BuiltStatusRows instead of scattered booleans.
  • Statusbar rendering now uses app/cache state rather than issuing repo queries during draw.
  • Display intent should remain equivalent:
    • same graph rows
    • same selected-row behavior
    • same search highlighting
    • same status icons/colors
    • same statusbar counts and mode indicators
    • same empty/loading states

Performance story:

  • Improvements are in draw-path recomputation.
  • Graph message projection can be reused when the graph projection key has not changed.
  • Statusbar avoids repo lookups during draw.
  • Status panes reuse shared row-building paths instead of rebuilding the same logic in multiple branches.

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
07-draw-status 1.618s 97.21x 1.36s 0.08s 89%

CPU: 5950x Linux/ZFS

Ref Total vs main User System CPU
07-draw-status 1.632s 60.81x 1.34s 0.18s 93%

Memory: 5950x Linux/ZFS

Ref Peak heap Peak RSS
07-draw-status 419.89M 916.59M
Top 10 heaptrack allocation sites for `07-draw-status`
  1. 29430 calls, 1.61M peak - <>::finish_grow
  2. 17060 calls, 0B peak - gix_ref::raw::convert::<>::from
  3. 17060 calls, 878.18K peak - guitar::core::walker::Walker::new
  4. 12342 calls, 0B peak - <>::push_back_tracked_path_component
  5. 10240 calls, 154.43M peak - alloc::raw_vec::RawVecInner<>::finish_grow
  6. 9776 calls, 7.47K peak - gix_config::parse::event::<>::to_owned
  7. 2816 calls, 519B peak - gix_config::file::util::<>::push_section_internal
  8. 1308 calls, 0B peak - gix_index::extension::tree::decode::one_recursive
  9. 902 calls, 99B peak - facet_core::impls::alloc::string::<>::SHAPE::{{constant}}::VTABLE::parse
  10. 778 calls, 0B peak - facet_reflect::partial::partial_api::lists::<>::begin_list_item

mjc added 30 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.
(cherry picked from commit 4b30648)
(cherry picked from commit 427dce7)
(cherry picked from commit 9854674)
(cherry picked from commit 6ce842f)
(cherry picked from commit dac26d1)
(cherry picked from commit 77e669a)
(cherry picked from commit 1484548)
mjc added 27 commits July 1, 2026 13:26
(cherry picked from commit e5bd31d)
(cherry picked from commit f956dcc)
(cherry picked from commit 4461f87)
(cherry picked from commit 4ccd4cc)
(cherry picked from commit 28598c0)
(cherry picked from commit 3ddc288)
(cherry picked from commit dc4e23c)
Skip commit diff refresh for the uncommitted pseudo-row when the first
GraphWindow is applied, and add a regression test that reproduces the
spike-06 TUI crash.
(cherry picked from commit c244fc5)
(cherry picked from commit 054ee9d)
(cherry picked from commit a9c3557)
(cherry picked from commit 30c9363)
(cherry picked from commit b99b0e9)
(cherry picked from commit 7b0b990)
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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

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