Skip to content

Git Graph highlights new HEAD while showing the previous commit's details #61299

Description

@thegalexc

Reproduction steps

  1. Start Zed and open a Git repository with a clean working tree.
  2. Open Git Graph.
  3. Select the current HEAD commit and confirm that its details and changed files appear in the right pane.
  4. While Git Graph remains open, create a new commit outside Zed that changes a different file.
  5. Return to Git Graph after it refreshes.

This reproduced consistently in a small disposable repository.

Current vs. Expected behavior

Current behavior:

Git Graph refreshes and highlights the new HEAD commit, but the right pane continues showing the previous commit's details and changed files. The highlighted row and details therefore represent different commits.

Pressing Down to select the previous commit and then Up to return to HEAD causes the details pane to synchronize. Selecting the already highlighted HEAD row does not refresh the stale details.

Expected behavior:

The highlighted row and details pane should always represent the same commit. Zed could either:

  • preserve the previously selected commit and its highlight after refreshing, or
  • select the new HEAD and update the details pane to show that commit.

This appears related to, but distinct from, #53594 and #60556. Those concern triggering a graph refresh when refs change. In this case the refresh succeeds, but selection and detail state become inconsistent. The closed #60691 also touched selection preservation during refresh.

Suspected mechanism and possible remediation

I checked crates/git_ui/src/git_graph.rs at adc60ccf12e199b8828bad3abb2591e147034734, the source commit included in this Zed build.

The behavior appears to involve positional selection surviving a graph reload:

  • on_repository_event handles HeadChanged by clearing pending_select_sha and calling invalidate_state.
  • invalidate_state clears graph and search data, but retains selected_entry_idx and the cached commit details.
  • Row highlighting compares the current row index against selected_entry_idx.
  • After a new commit is prepended, the retained index can identify a different commit while the right pane retains the old commit's cached details.
  • select_entry returns early when the selected index has not changed, even if the commit SHA now occupying that index has changed. This explains why navigating away and back refreshes the pane.

One possible fix would be to preserve the selected commit SHA in pending_select_sha, clear the positional selection and detail caches during invalidation, and use the existing SHA remapping path after graph data reloads.

Simpler alternatives would be to clear selection and detail state completely during invalidation, or structurally key selection by commit SHA rather than row index. The same-index early return in select_entry could also compare commit identity before skipping the refresh.

Potential regression tests:

  1. Select HEAD, advance HEAD, reload, and verify the highlighted commit SHA matches the details pane SHA.
  2. Select a non-HEAD commit, prepend a commit, and verify selection follows the original SHA rather than its former index.
  3. After reload, select the highlighted row and verify details are fetched when the SHA occupying that index changed.

Zed version and system specs

Zed: v1.10.2+stable.322.adc60ccf12e199b8828bad3abb2591e147034734 (Zed)
OS: macOS 26.3.1 (a) (Build 25D771280a)
Memory: 36 GiB
Architecture: aarch64

Attach Zed log file

Zed.log

Relevant Zed settings

settings.json

Relevant Keymap

keymap.json

(for AI issues) Model provider details

No response

If you are using WSL on Windows, what flavor of Linux are you using?

None

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:needs triagetriage is not complete: no `area:*` label, or no `priority:*`/`frequency:*` for Bugs/Crashes

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions