feat(git-graph): revamp history browsing and rendering - #288
Conversation
|
| Commit | Scanned at | New | Resolved | Net |
|---|---|---|---|---|
bd06827 |
2026-07-31 10:13 UTC | 0 | 0 | 0 |
bd06827 |
2026-07-31 10:12 UTC | — | — | — |
1355625 |
2026-07-31 10:53 UTC | — | — | — |
feebdcb < |
2026-07-31 11:27 UTC | 0 | 0 | 0 |
Last scanned: feebdcb · 2026-07-31 11:27 UTC
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bd0682744a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| setWorkingTreeFiles( | ||
| result.items.map((item) => ({ | ||
| path: item.path, | ||
| status: resolveWorkingTreeStatus(item), |
There was a problem hiding this comment.
Preserve exact paths for working-tree diffs
When a changed path contains spaces or non-ASCII characters, git status --porcelain returns a quoted/escaped display path, and this mapping stores that representation as the filesystem path. Clicking the entry later passes the quoted value to loadWorkingTreeDiff and openFileFromTree, so a file such as file name.txt opens an empty diff or cannot be opened. Parse a NUL-delimited status response into exact paths, including separate old/new paths for renames, before creating these file changes.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in feebdcb.
Root cause was the shared status parser, so the fix landed there rather than in this hook. parseSourceControlStatusLines now parses git status --porcelain=v1 -z (NUL-delimited, paths verbatim) first and falls back to newline output only when needed, un-escaping octal/quoted forms via unquoteGitPath. path is therefore an exact filesystem path, and renames keep a separate oldPath.
Every producer and consumer was aligned: -z added in electron/host-service/scm-runtime.ts and server/dev-server.ts, and renames are recombined into the old -> new pathspec pair through formatSourceControlDiffPath before crossing IPC, so stage/unstage/discard/diff all keep both pathspecs.
Covered by new tests in tests/source-control-status.test.ts (NUL, newline fallback, non-ASCII, trailing space) and tests/source-control-diff.test.ts (rename recombination).
| if (!nextSelection) { | ||
| if (currentSelection) { | ||
| detailsRequestRef.current += 1; | ||
| } | ||
| setDetails(null); | ||
| setWorkingTreeFiles([]); |
There was a problem hiding this comment.
Reload preserved working-tree details
When the working-tree row is selected, hiding and reopening the Git Graph restores that selection from graphCache, but workingTreeFiles is initialized empty and the initial reload only fetches files when the user explicitly selects the row again. The same branch leaves the file list stale after Refresh while preserving the selection, so the details panel can show no files or outdated files despite the refreshed summary. Reload or cache the working-tree file list whenever this selection survives reconciliation.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in feebdcb.
Extracted refreshWorkingTreeFiles and added a pure helper, resolveGitGraphReloadEffects, that decides the post-reconciliation effects: whenever a working-tree selection survives a reload or remount, the file list is refetched instead of staying at its empty initial value. selectWorkingTree reuses the same helper path, so the details panel and the refreshed summary no longer diverge after Refresh or after hiding and reopening the graph.
Covered by new tests in tests/git-graph-selection.test.ts.
| ? result.availableRefs | ||
| : current.availableRefs, | ||
| }; | ||
| cacheCurrent(next, selection); |
There was a problem hiding this comment.
Cache the live selection after pagination
When a load-more request starts and the user selects a commit before it completes, this callback writes the selection captured when pagination began back into graphCache. The visible selection remains correct until the graph surface unmounts, but reopening it restores the stale cached selection and unexpectedly closes or changes the details panel. Cache selectionRef.current (or otherwise read the live selection) when the page resolves.
AGENTS.md reference: AGENTS.md:L151-L151
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in feebdcb.
The load-more completion callback now caches selectionRef.current instead of the selection value captured when pagination began, so a commit selected mid-request is what gets written into graphCache. Reopening the surface no longer restores a stale selection.
Address Codex review on #288: - Parse `git status --porcelain -z` (and unquote newline output) into exact filesystem paths with separate rename sources, so entries with spaces or non-ASCII names open real diffs instead of empty ones. - Refetch the working-tree file list whenever that selection survives a reload or remount, keeping the details panel in sync after Refresh. - Cache the live selection (`selectionRef.current`) when a pagination page resolves, so reopening the graph no longer restores a stale one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Summary
M/L/Cedge serialization while preserving smooth lane transitions and layered branch strokesLICENSEandNOTICEWhy
Git Graph needed a denser history-browsing workflow and stronger renderer-to-host contracts. A provenance audit also found that later Git Graph releases use a restrictive license. The graph implementation is now independently authored, including the edge path geometry, and adds no runtime geometry dependency or edge-specific third-party notice requirement.
Verification
bun run test:ci— reliability gates, 319 isolated test files, typecheck, web build, and desktop build passedbun run test:e2e -- tests/e2e/git-graph-entry.e2e.ts— 2 Chromium tests passedgit diff --check