Skip to content

Show a worktree as the branch it holds, in one place in the sidebar - #710

Closed
goneng wants to merge 4 commits into
read-the-worktree-porcelain-into-a-modelfrom
name-the-worktree-rows-after-their-branch
Closed

goneng wants to merge 4 commits into
read-the-worktree-porcelain-into-a-modelfrom
name-the-worktree-rows-after-their-branch

Conversation

@goneng

@goneng goneng commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

A worktree is a branch that happens to sit in its own directory, so the
sidebar lists it once, under WORKTREES, named after that branch rather
than after the folder it lives in.

  • Name a worktree row after the branch it holds, keeping the directory
    in the tooltip together with the lock and prune state
  • Keep a branch held in another worktree out of BRANCHES, in both
    directions, since the worktree snapshot only lands after the branch
    list has already been built
  • Carry that branch's rev specifier on the row, so selecting it moves
    the history list and the ref menu builds, as they did for the branch
    row before it moved
  • Fix the worktree snapshot announcing itself before the index derived
    from it, and drop the branch-row plumbing this all makes unreachable

Test plan:

  • 199 unit tests pass, 9 of them in the worktree group suite and 5 new
  • The integration test runs real git worktree add and git worktree lock, then asserts what the sidebar ends up showing
  • Checked by hand on the GitX repo itself: five worktree rows named
    after their branches, a single checkmark on master, and the history
    list following a worktree row on selection

Built on #709 and targets its branch, so only the four commits here are
under review. It carries no closing keyword: slices 3 and 4 of #675,
the worktree lifecycle actions, are still to come.

The lookup kept a branch-to-path mapping and dropped the rest, so a
worktree on a detached HEAD, a bare repository, and every lock or prune
state went unrecorded and could not reach the sidebar.

- Add PBGitWorktree, reading a record's path, HEAD, branch or detached
  state, bare, locked and prunable with their reasons, and whether the
  record is the worktree we have open.
- Frame records on the `worktree` line rather than on HEAD, since a bare
  repository's record carries neither a HEAD nor a branch and would
  otherwise be dropped.
- Unescape a quoted lock reason, whose octal escapes stand for bytes of
  the UTF-8 encoding rather than for characters.
- Split running git away from reading what it printed, so one run feeds
  one parse and the branch-to-path dictionary the drawing path asks for
  is derived from the snapshot rather than parsed again.
A worktree is somewhere work happens, so the group sits with the
branches rather than down among the remotes and the vendored things.

- Add a WORKTREES group listing every worktree git reports, filled at
  -populateList and rebuilt when a later snapshot arrives, the way the
  stashes group already is.
- Mark the worktree this window has open with the checkmark that means
  exactly that elsewhere in the sidebar, and give the row a tooltip
  naming its branch and its lock or prune reason.
- Move the tooltip out of the badge refresh, which reassigned it on
  every window activation and so would have erased whatever the row
  had set for itself.
- Cover the whole chain with a test that runs `git worktree add` and
  `git worktree lock`, the only worktree test reading git's own output
  rather than a fixture that cannot notice git changing.
A worktree is a branch that happens to sit in its own directory, so it
belongs in one place in the sidebar; listing it as both a branch and a
directory stated the same fact twice under two different names.

- Name a worktree row after the branch it holds, keeping the directory
  in the tooltip with the lock and prune state
- Keep a branch held elsewhere out of BRANCHES, in both directions, as
  the worktree snapshot only lands after the branches are built
- Answer with that branch from the row, so the ref menu builds and
  already offers to open the worktree rather than to check it out
- Give every row its name on hover, so a truncated one stays readable,
  and reopen the worktree on a double click as the branch rows did
A branch listed under BRANCHES can no longer be held by another
worktree, so everything that answered for that case had become
unreachable.

- Take the worktree path and the icon override out of the cell builder,
  which now reads its icon off the item like every other row
- Drop the cell's worktreePath property and the tooltip it wrote
- Let a double click on a branch row check it out, which is the only
  thing it can still mean
@goneng
goneng force-pushed the read-the-worktree-porcelain-into-a-model branch from 99a91f8 to 6e8f8da Compare September 21, 2026 17:29
@goneng
goneng force-pushed the name-the-worktree-rows-after-their-branch branch from 9c12663 to 8455e01 Compare September 21, 2026 17:29
@goneng
goneng force-pushed the read-the-worktree-porcelain-into-a-model branch from 6e8f8da to 23c4474 Compare September 21, 2026 18:45
@goneng

goneng commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator Author

Folded into #709, which now carries the whole change as three commits. Keeping them apart would have let #709 merge on its own, and on its own it added a WORKTREES group that duplicated every branch and did nothing on click, right-click or double click.

@goneng goneng closed this Sep 21, 2026
@goneng
goneng deleted the name-the-worktree-rows-after-their-branch branch September 21, 2026 18:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant