Skip to content

Enhance: [Worktrees] no sidebar section, and no way to add or remove one #675

Closed

Description

@goneng

Split out of #629, which delivered its first three slices and is otherwise done. This is the "later" bullet from that issue, kept separate because the other three were fixes for an app that actively misled you, while this is a feature.

What is missing

There is no WORKTREES section in the sidebar next to SUBMODULES, and no way to add, remove, lock or prune a worktree from the app.

What already exists to build on

The actual gap

+worktreePathsFromPorcelain:excludingWorktreeAtPath: keeps only what marking branches needed, a branch to path mapping, and only for worktrees other than this one. Everything else in the porcelain output is dropped on the floor:

  • HEAD, and worktrees with no branch line at all. A detached worktree would simply not appear in the section, since nothing records it.
  • bare, so the main bare repository cannot be distinguished.
  • locked and its reason, which a remove action has to respect.
  • prunable and its reason, which is the whole basis of a prune action.
  • This repository's own worktree, deliberately excluded, which a list should show and mark as current.

So the first piece of work is reading the porcelain into a model rather than into a lookup table. The current parser is right for what it does and should probably stay as the cheap path for the label drawing, which runs far more often than a sidebar reload.

Suggested slices

  1. parse the full porcelain into a worktree model: path, HEAD, branch or detached, bare, locked with reason, prunable with reason, and which one is ours
  2. a WORKTREES group in the sidebar listing them, marking the current one and showing locked or prunable state
  3. git worktree prune, and lock/unlock
  4. git worktree add, and git worktree remove refusing or warning where git would
  5. git worktree repair for a worktree whose folder was moved: offer it on a worktree whose folder is missing, pointing git at where the folder went (git 2.29, as Tower does)

The first two stand on their own and are worth having without the rest.

Slices 1 and 2 landed in #709. Slices 3 and 4 have swapped places: prune and lock/unlock come first, because they bring the git version check and the worktree row menu that remove then builds on. Slice 5 was added later, after looking at how other clients treat a worktree whose folder is gone.

Activity

  1. self-assigned this
    on Sep 18, 2026
  2. goneng commented on Sep 23, 2026

    @goneng
    CollaboratorAuthor

    Git version requirements for the remaining slices

    GitX accepts any git from 1.6.0 (MIN_GIT_VERSION), but the worktree commands arrived much later. Checked against builtin/worktree.c at each git tag:

    Feature First git version
    worktree add, prune 2.5
    worktree list --porcelain (read since #709) 2.7
    lock / unlock, with --reason 2.10
    remove, move 2.17
    locked / prunable lines in the porcelain 2.31
    list -z 2.36

    Nothing crashes on an older git: a failing command comes back as an error, and before 2.7 the WORKTREES group is simply empty. From 2.7 to 2.30 the porcelain carries no lock or prune state, so every worktree reads as unlocked and not prunable. Apple's git on macOS 13 and later (our deployment target) should be 2.37 or newer, which covers the whole table; the exposure is an older git picked up from PATH or set in the preferences.

    The plan:

    • Gate each action on the git version in one place in PBGitBinary, named per feature, and cache the version (+version runs git --version on every call today).
    • When git is too old, show the item disabled with a tooltip naming the version it needs and the one found, as the disabled Remove item from Show every worktree in the sidebar as the branch it holds #709 already does.
    • Build the Prune confirmation from git worktree prune --dry-run --verbose (2.5+), so what it lists does not depend on the porcelain.
    • No fallback for remove before 2.17: the only substitute is deleting the folder and pruning, which skips git's check for uncommitted work.
    • No reading of worktrees/<id>/locked to recover lock state before 2.31; the extra code is not worth it when the system git reports it.
    • Keep reading plain --porcelain, not -z.
    • Test the gate as a pure function of a version string, so the 2.16/2.17 and 2.30/2.31 boundaries are covered without installing old gits.
    • Leave MIN_GIT_VERSION alone, since raising it would change the requirement for every GitX user.

    The gate lands with slice 3 (prune and lock/unlock), the first slice that needs it.

  3. changed the title [-]Worktrees: no sidebar section, and no way to add or remove one[/-] [+]Enhance: [Worktrees] no sidebar section, and no way to add or remove one[/+] on Sep 24, 2026
  4. goneng commented on Sep 29, 2026

    @goneng
    CollaboratorAuthor

    All five slices have landed:

    Not covered: repairing after the main repository's own folder moves (git worktree repair with no path). That can get its own issue if it is wanted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions