Skip to content

Show branch topology in revision history graph#10

Open
JohnRDOrazio wants to merge 13 commits intomainfrom
feature/branch-topology-graph
Open

Show branch topology in revision history graph#10
JohnRDOrazio wants to merge 13 commits intomainfrom
feature/branch-topology-graph

Conversation

@JohnRDOrazio
Copy link
Member

@JohnRDOrazio JohnRDOrazio commented Mar 10, 2026

Summary

  • Use backend refs map to assign feature branch commits to separate lanes in the git graph, with branch name badges (blue, with GitBranch icon)
  • Fix lane assignment so hints from refs take priority over child continuation, ensuring branching is visible even when a feature branch is ahead of main with no divergence
  • Refresh branch data (commits ahead/behind counts) after every commit operation and when the history panel opens, fixing stale BranchBadge/BranchSelector counts

Test plan

  • Open a project on a feature branch, click History — feature branch commits appear on a separate lane with branch labels; main commits on lane 0 with a "main" badge
  • Make a commit on a feature branch — BranchBadge and BranchSelector immediately show updated "+N" count without needing to reload
  • Open History panel — branch selector refreshes to show current ahead/behind counts
  • Verify npm run type-check and npm run lint pass cleanly

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Per-commit branch badges added to revision history and reflected in the git graph; graph layout now respects the default branch.
    • Revision API now surfaces branch refs so the UI shows up-to-date branch information.
  • Refactor

    • Branch data now refreshes automatically after saves, updates, and deletes for immediate consistency.
  • Tests

    • New unit tests validate branch-aware graph layout and lane assignments.

Closes #8

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds branch-ref propagation through API, graph builder, and UI; Graph vertices gain refs and lane-hinting; BranchContext switches to React Query, exports branchQueryKeys and refreshBranches; Editor page invalidates branch list queries after save/delete/update; Revision UI and GitGraph render per-commit branch badges.

Changes

Cohort / File(s) Summary
Branch context & provider
lib/context/BranchContext.tsx
Switched to React Query: adds exported branchQueryKeys, uses useQuery/useQueryClient, exposes refreshBranches(): Promise<void> (replaces loadBranches), derives branches/defaultBranch from server response, persists currentBranch preference.
Editor wiring / query invalidation
app/projects/[id]/editor/page.tsx
Adds useQueryClient() and invalidates branchQueryKeys.list(projectId) after commit/save/delete/update flows; adds queryClient to callback deps.
Graph builder & types
lib/git-graph/graph-builder.ts, lib/git-graph/types.ts
buildGraphLayout now accepts refs?: Record<string,string[]> and defaultBranch?; GraphVertex gains refs: string[]; added computeBranchHints and lane/color assignment consumes hints.
API types
lib/api/revisions.ts
RevisionHistoryResponse now optionally includes refs?: Record<string,string[]>.
Graph component
components/revision/GitGraph.tsx
GitGraphProps extended with refs? and defaultBranch?; buildGraphLayout call and useMemo depend on refs and defaultBranch.
Revision history UI
components/revision/RevisionHistoryPanel.tsx
Stores response.refs into local state, uses useBranch() for defaultBranch, passes refs/defaultBranch to GitGraph, and renders per-commit branch badges using refs[commit.hash].
Tests
__tests__/lib/git-graph/graph-builder.test.ts
New test suite validating branch-aware lane assignment scenarios for buildGraphLayout (empty, linear, feature tips, stacked branches, multiple features).
Next config & manifest
next.config.ts, manifest_file, package.json
Added output: "standalone" to Next config; minor manifest/package line changes.

Sequence Diagram(s)

sequenceDiagram
    participant Editor as Editor Page
    participant Query as React Query Cache
    participant BranchProv as BranchContext
    participant API as API Layer

    Editor->>API: save / update / delete
    API-->>Editor: operation result
    Editor->>Query: invalidateQueries(branchQueryKeys.list(projectId))
    Query->>BranchProv: triggers refetch (refreshBranches)
    BranchProv->>API: fetch branches
    API-->>BranchProv: branches + defaultBranch
    BranchProv-->>Editor: context updates (branches/defaultBranch)
Loading
sequenceDiagram
    participant UI as RevisionHistoryPanel
    participant API as API Layer
    participant Builder as Graph Builder
    participant Graph as GitGraph Component
    participant Context as BranchContext

    UI->>API: loadHistory() (commits + refs)
    API-->>UI: commits + refs
    UI->>Context: read defaultBranch
    UI->>Builder: buildGraphLayout(commits, refs, defaultBranch)
    Builder->>Builder: computeBranchHints(refs, defaultBranch)
    Builder->>Builder: assignLanesAndColors(vertices, hints)
    Builder-->>UI: GraphLayout (vertices include refs)
    UI->>Graph: render commits with branch badges
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I found little refs tucked in each hash,

Lanes appeared where once the line was plain,
I nudged the cache and watched the graph dash,
Branches returned and colors woke again,
Hoppity hops — the history blooms! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly and concisely summarizes the main change: displaying branch topology in the revision history graph.
Linked Issues check ✅ Passed The PR fully addresses issue #8 by restoring branch topology visualization, updating API responses to include refs, and refreshing branch data after operations.
Out of Scope Changes check ✅ Passed All changes are scoped to displaying branch topology and keeping counts accurate; the Docker standalone output change is a necessary supporting configuration.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/branch-topology-graph
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@JohnRDOrazio
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/revision/RevisionHistoryPanel.tsx`:
- Around line 196-205: The badge strip is wrapping and pushing the text column
out of sync; when rendering refs?.[commit.hash]?.map((ref) => ...) around the
GitBranch badge, make the badge row single-line and truncated by adding no-wrap
and overflow truncation classes to the span (e.g. add whitespace-nowrap,
overflow-hidden, text-ellipsis/truncate and a sensible max-width or max-w-[...]
class) so long branch names don’t wrap; keep the GitBranch icon and ref text but
ensure each badge is constrained (or alternatively constrain the parent
container for all badges) so the row stays fixed-height and aligns with the
graph cell.

In `@lib/context/BranchContext.tsx`:
- Around line 61-70: The BranchProvider currently exposes an imperative
refreshRef (BranchProviderHandle.refreshBranches) and uses loadBranches; replace
this with a React Query-backed query for branches keyed by projectId and remove
refreshRef/refreshBranches from BranchProviderProps/BranchProviderHandle,
switching consumers to the query's data and refetch functions; implement any
write operations as React Query mutations that call
queryClient.invalidateQueries or mutation.onSuccess to refresh the branches
cache, and update callers (the editor and history panel) to either read the
branches from useQuery or call queryClient.refetchQueries/useQueryClient instead
of calling loadBranches or branchRef.current?.refreshBranches().

In `@lib/git-graph/graph-builder.ts`:
- Around line 183-185: The color assignment incorrectly allows the first side
branch to receive color 0 because nextColor is initialized to 0; update the
logic in graph-builder.ts (around the assignedColor/hintedLane handling and the
nextColor initialization) to reserve color 0 for lane 0 — either initialize
nextColor to 1 where it’s declared or ensure the branch that sets assignedColor
for hintedLane !== 0 uses nextColor starting at 1 (and then increments nextColor
afterwards); refer to the variables assignedColor, hintedLane, and nextColor
when making the change.
- Around line 167-171: The forEach callbacks are returning the Set via the
implicit-expression form (triggering useIterableCallbackReturn); change the
callbacks that iterate activeLanes and the other forEach at the later location
to use block bodies and call usedLanes.add(lane); (and the analogous add call)
as statements. Locate the forEach that reads activeLanes and the second forEach
around the code referencing hintedLane and replace the arrow expressions with
block-bodied arrow functions so Set.add(...) is a statement rather than an
implicit return.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 11f84d96-c734-4cba-b909-a989ba5cf677

📥 Commits

Reviewing files that changed from the base of the PR and between d258636 and d3fb68f.

📒 Files selected for processing (7)
  • app/projects/[id]/editor/page.tsx
  • components/revision/GitGraph.tsx
  • components/revision/RevisionHistoryPanel.tsx
  • lib/api/revisions.ts
  • lib/context/BranchContext.tsx
  • lib/git-graph/graph-builder.ts
  • lib/git-graph/types.ts

…nts after commits

Use the refs map from the backend to visually separate branches onto different
lanes in the git graph. Feature branch commits now appear on a separate lane
with branch name badges, while main commits stay on lane 0.

Also fix stale branch data (commits ahead/behind) by refreshing branch info
after every commit operation and when the history panel opens.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@JohnRDOrazio JohnRDOrazio force-pushed the feature/branch-topology-graph branch from d3fb68f to 3bdf914 Compare March 10, 2026 16:43
@JohnRDOrazio JohnRDOrazio changed the base branch from feature/explicit-save-button to main March 10, 2026 16:43
JohnRDOrazio and others added 2 commits March 10, 2026 17:49
Wrap branch ref badges in a non-wrapping container with overflow hidden
to prevent long branch names from breaking row alignment in the git graph.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use block bodies in forEach callbacks to avoid returning Set.add() values
(lint: useIterableCallbackReturn). Initialize nextColor to 1 so the main
lane always gets color 0 and side branches start at color 1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (3)
lib/git-graph/graph-builder.ts (2)

155-156: ⚠️ Potential issue | 🟡 Minor

Keep color 0 exclusive to lane 0.

nextColor still starts at 0, so the first hinted side branch on Line 184 renders with the same color as the main lane. The fallback path on Line 216 has the same problem when it allocates lane 0.

Proposed fix
-  let nextColor = 0;
+  let nextColor = 1;
@@
-          assignedColor = hintedLane === 0 ? 0 : nextColor++;
+          assignedColor = hintedLane === 0 ? 0 : nextColor++;
@@
-      assignedColor = nextColor++;
+      assignedColor = assignedLane === 0 ? 0 : nextColor++;

Also applies to: 183-185, 212-216

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/git-graph/graph-builder.ts` around lines 155 - 156, nextColor is
initialized to 0 so the first allocated side branch can get color 0 (same as
main lane); change the allocation logic to keep color 0 reserved for lane 0 by
initializing nextColor = 1 and update any increment/wrap logic that assigns
lanes (places that do nextColor++ / nextColor = (nextColor + 1) % N or fallback
lane search) to skip 0 (e.g., if nextColor becomes 0, advance to 1) so no
allocation ever returns color 0 for hinted/fallback branches.

167-171: ⚠️ Potential issue | 🟠 Major

Fix the forEach callbacks before linting.

Line 171 and Line 210 still use expression-bodied callbacks, so Biome treats them as returning the Set from usedLanes.add(...) and fails useIterableCallbackReturn.

Proposed fix
-      activeLanes.forEach(({ lane }) => usedLanes.add(lane));
+      activeLanes.forEach(({ lane }) => {
+        usedLanes.add(lane);
+      });
@@
-      activeLanes.forEach(({ lane }) => usedLanes.add(lane));
+      activeLanes.forEach(({ lane }) => {
+        usedLanes.add(lane);
+      });

Also applies to: 209-210

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/git-graph/graph-builder.ts` around lines 167 - 171, The forEach callbacks
that call usedLanes.add(...) are using expression-bodied arrows which return the
Set value and trigger the useIterableCallbackReturn lint; change those to
block-bodied callbacks so they don't return a value. Specifically, update
activeLanes.forEach(({ lane }) => usedLanes.add(lane)) to activeLanes.forEach(({
lane }) => { usedLanes.add(lane); }) and make the analogous change to the other
forEach near the hintedLane logic (the second occurrence that also calls
usedLanes.add) so both callbacks use { ... } and no implicit return.
components/revision/RevisionHistoryPanel.tsx (1)

196-205: ⚠️ Potential issue | 🟡 Minor

Constrain the ref badges to one line.

These rows are fixed to ROW_HEIGHT, so long or multiple refs can still wrap here and push the text column out of sync with the graph. Keep the badge strip single-line/truncated, or raise both the row height and graph cell height together.

Proposed fix
-                          {refs?.[commit.hash]?.map((ref) => (
-                            <span
-                              key={ref}
-                              className="inline-flex items-center gap-1 rounded-full bg-blue-100 px-1.5 py-0.5 text-xs font-medium text-blue-700 dark:bg-blue-900/30 dark:text-blue-300"
-                            >
-                              <GitBranch className="h-2.5 w-2.5" />
-                              {ref}
-                            </span>
-                          ))}
+                          {(refs?.[commit.hash] ?? []).length > 0 && (
+                            <div className="mt-0.5 flex min-w-0 items-center gap-1 overflow-hidden whitespace-nowrap">
+                              {(refs?.[commit.hash] ?? []).map((ref) => (
+                                <span
+                                  key={ref}
+                                  title={ref}
+                                  className="inline-flex max-w-[160px] items-center gap-1 rounded-full bg-blue-100 px-1.5 py-0.5 text-xs font-medium text-blue-700 dark:bg-blue-900/30 dark:text-blue-300"
+                                >
+                                  <GitBranch className="h-2.5 w-2.5 shrink-0" />
+                                  <span className="truncate">{ref}</span>
+                                </span>
+                              ))}
+                            </div>
+                          )}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/revision/RevisionHistoryPanel.tsx` around lines 196 - 205, The ref
badges can wrap and change row height; wrap the map output in a single-line,
non-wrapping container and make each badge non-shrinking so badges are clipped
instead of wrapping: update the block that renders refs?.[commit.hash]?.map(...)
(the span elements using GitBranch and ref) to be inside a wrapper with CSS
classes enforcing overflow-hidden, whitespace-nowrap, and
text-overflow/ellipses; ensure each badge gets a flex-shrink-0 (or equivalent)
so they stay on one line and excess badges are truncated rather than wrapping.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@components/revision/RevisionHistoryPanel.tsx`:
- Around line 196-205: The ref badges can wrap and change row height; wrap the
map output in a single-line, non-wrapping container and make each badge
non-shrinking so badges are clipped instead of wrapping: update the block that
renders refs?.[commit.hash]?.map(...) (the span elements using GitBranch and
ref) to be inside a wrapper with CSS classes enforcing overflow-hidden,
whitespace-nowrap, and text-overflow/ellipses; ensure each badge gets a
flex-shrink-0 (or equivalent) so they stay on one line and excess badges are
truncated rather than wrapping.

In `@lib/git-graph/graph-builder.ts`:
- Around line 155-156: nextColor is initialized to 0 so the first allocated side
branch can get color 0 (same as main lane); change the allocation logic to keep
color 0 reserved for lane 0 by initializing nextColor = 1 and update any
increment/wrap logic that assigns lanes (places that do nextColor++ / nextColor
= (nextColor + 1) % N or fallback lane search) to skip 0 (e.g., if nextColor
becomes 0, advance to 1) so no allocation ever returns color 0 for
hinted/fallback branches.
- Around line 167-171: The forEach callbacks that call usedLanes.add(...) are
using expression-bodied arrows which return the Set value and trigger the
useIterableCallbackReturn lint; change those to block-bodied callbacks so they
don't return a value. Specifically, update activeLanes.forEach(({ lane }) =>
usedLanes.add(lane)) to activeLanes.forEach(({ lane }) => { usedLanes.add(lane);
}) and make the analogous change to the other forEach near the hintedLane logic
(the second occurrence that also calls usedLanes.add) so both callbacks use {
... } and no implicit return.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 91d32c2b-fe7a-4f33-97dd-d456384614b3

📥 Commits

Reviewing files that changed from the base of the PR and between d3fb68f and 3bdf914.

📒 Files selected for processing (7)
  • app/projects/[id]/editor/page.tsx
  • components/revision/GitGraph.tsx
  • components/revision/RevisionHistoryPanel.tsx
  • lib/api/revisions.ts
  • lib/context/BranchContext.tsx
  • lib/git-graph/graph-builder.ts
  • lib/git-graph/types.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/api/revisions.ts
  • lib/context/BranchContext.tsx

When the fallback lane assignment happens to pick lane 0, use color 0
instead of allocating the next color, keeping main-line commits visually
consistent.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/revision/RevisionHistoryPanel.tsx (1)

39-71: 🛠️ Refactor suggestion | 🟠 Major

Move the history/branch loading onto React Query.

This change adds more remote state (refs plus a branch refresh trigger) behind local useState/useEffect, which keeps cache and refetch behavior split across component state and context. Please model the history request as a query and drive refreshes through query invalidation/refetch instead.

As per coding guidelines, "Use React Query (@tanstack/react-query) for server state management".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/revision/RevisionHistoryPanel.tsx` around lines 39 - 71, The
component is managing remote history/refs with local useState and loadHistory;
replace that with a React Query useQuery that calls revisionsApi.getHistory and
returns {commits, refs} keyed by ['revisions', projectId] (remove loadHistory,
setCommits/setRefs, setIsLoading/setError and selected state updates tied to
them), enable the query only when isOpen and projectId are present, and surface
query status/error instead of local flags; keep calling loadBranches() but when
branches refreshes complete (or when defaultBranch changes) trigger the history
refresh by calling useQueryClient().invalidateQueries(['revisions', projectId])
or query.refetch so branch updates drive refetches rather than local effects.
Ensure you reference the existing symbols revisionsApi.getHistory, loadBranches,
loadHistory (remove), commits and refs state (replace), and the query key
['revisions', projectId].
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/git-graph/graph-builder.ts`:
- Around line 130-137: The loop that assigns lane hints (using nextLane, hints,
walk, GraphVertex, vertices, mainLine, and v.id) currently overwrites existing
hints and steals commits from earlier stacked branches; change the walk so it
stops when it encounters a commit that already has a hint instead of rewriting
it (i.e., break the walk if hints.has(walk) is true) — ensure you check hints
before calling hints.set and update the loop condition or add an early-break so
earlier lane assignments are preserved.

---

Outside diff comments:
In `@components/revision/RevisionHistoryPanel.tsx`:
- Around line 39-71: The component is managing remote history/refs with local
useState and loadHistory; replace that with a React Query useQuery that calls
revisionsApi.getHistory and returns {commits, refs} keyed by ['revisions',
projectId] (remove loadHistory, setCommits/setRefs, setIsLoading/setError and
selected state updates tied to them), enable the query only when isOpen and
projectId are present, and surface query status/error instead of local flags;
keep calling loadBranches() but when branches refreshes complete (or when
defaultBranch changes) trigger the history refresh by calling
useQueryClient().invalidateQueries(['revisions', projectId]) or query.refetch so
branch updates drive refetches rather than local effects. Ensure you reference
the existing symbols revisionsApi.getHistory, loadBranches, loadHistory
(remove), commits and refs state (replace), and the query key ['revisions',
projectId].

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eddff8d5-2c95-49a5-96bb-fa643180da3c

📥 Commits

Reviewing files that changed from the base of the PR and between 3bdf914 and 670e9b9.

📒 Files selected for processing (2)
  • components/revision/RevisionHistoryPanel.tsx
  • lib/git-graph/graph-builder.ts

@JohnRDOrazio JohnRDOrazio added this to the v0.3.0 milestone Mar 10, 2026
JohnRDOrazio and others added 7 commits March 11, 2026 13:37
When feature/b branches from feature/a (not main), the second branch
walk would overwrite feature/a's lane hints. Add a guard to break
early if a commit was already claimed by a prior branch walk.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…reshRef

Replace manual useState/useCallback/useEffect branch loading with
useQuery. Remove useImperativeHandle/refreshRef pattern — the editor
page now invalidates the shared query key directly via useQueryClient.
RevisionHistoryPanel no longer needs a manual loadBranches() call.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both are used in callbacks throughout the file but the build
environment's ESLint flags them as unused.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove unnecessary eslint-disable comments (values are used in callbacks)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Dockerfile COPY step expects /app/public to exist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
lib/context/BranchContext.tsx (1)

82-91: Consider including accessToken in the query key for cache correctness.

The query key is ["branches", projectId], but accessToken is passed to the query function. If accessToken changes (e.g., token refresh or user switch) while projectId remains the same, React Query may return stale cached data from the previous token.

This is likely acceptable if:

  1. Token changes always coincide with page refreshes, or
  2. The accessToken is stable for the session lifetime

If token changes can occur without a refresh, consider adding it to the key:

Potential adjustment
 const {
   data: response,
   isLoading,
   error: queryError,
 } = useQuery({
-  queryKey: branchQueryKeys.list(projectId),
+  queryKey: [...branchQueryKeys.list(projectId), accessToken],
   queryFn: () => branchesApi.list(projectId, accessToken),
   enabled: !!projectId,
 });

Note: This would also require updating the invalidation calls in editor/page.tsx to include accessToken.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/context/BranchContext.tsx` around lines 82 - 91, The query key for the
useQuery call using branchQueryKeys.list(projectId) must include accessToken to
avoid returning cached branch data tied to a different token; update the
useQuery invocation (where useQuery is called in BranchContext.tsx and uses
branchesApi.list(projectId, accessToken)) to include accessToken in the queryKey
(e.g., branchQueryKeys.list(projectId, accessToken)), and then update any places
that invalidate or refetch this key (notably the invalidation calls in
editor/page.tsx) so they pass the same accessToken when invalidating.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@lib/context/BranchContext.tsx`:
- Around line 82-91: The query key for the useQuery call using
branchQueryKeys.list(projectId) must include accessToken to avoid returning
cached branch data tied to a different token; update the useQuery invocation
(where useQuery is called in BranchContext.tsx and uses
branchesApi.list(projectId, accessToken)) to include accessToken in the queryKey
(e.g., branchQueryKeys.list(projectId, accessToken)), and then update any places
that invalidate or refetch this key (notably the invalidation calls in
editor/page.tsx) so they pass the same accessToken when invalidating.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 84058ed7-92dc-4a83-a2ca-e8ba095fb4ea

📥 Commits

Reviewing files that changed from the base of the PR and between 670e9b9 and fba8321.

📒 Files selected for processing (6)
  • __tests__/lib/git-graph/graph-builder.test.ts
  • app/projects/[id]/editor/page.tsx
  • components/revision/RevisionHistoryPanel.tsx
  • lib/context/BranchContext.tsx
  • lib/git-graph/graph-builder.ts
  • public/.gitkeep

damienriehl and others added 2 commits March 14, 2026 18:58
The Dockerfile copies from .next/standalone but next.config.ts was
missing output: "standalone", causing Docker builds to fail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update branchQueryKeys.list() to accept and include accessToken parameter
- Include accessToken in useQuery call to prevent returning cached data tied to different tokens
- Update refreshBranches callback to pass accessToken when invalidating
- Update all 5 invalidateQueries calls in editor/page.tsx to pass accessToken

This ensures branch queries are properly scoped by authentication token,
preventing incorrect cache hits when users with different tokens access the same project.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JohnRDOrazio
Copy link
Member Author

Gentle reminder: The commit 'd5f88a9' ("Add standalone output for Docker deployment") appears to be unrelated to the branch topology feature. ✨

For future PRs, consider moving unrelated bugfixes or infrastructure changes to their own dedicated PR or branch. This helps keep:

  • Review focus clear and scoped
  • Git history readable and traceable
  • CI/CD pipelines focused on the feature at hand

Example workflow:

Thanks for the contribution! This guideline just helps us maintain clean, focused PRs. 👍

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.

Git history graph does not show branches since bare repo migration

2 participants