#66217

Worktree picker hides local main as a creation base when it differs from origin/main

Opendgmulfopened 3d ago

Reproduction steps

  1. Open a Git repository in Zed with a local main branch and a remote default branch origin/main.
  2. Check out local main and create a commit without pushing it, so local main and origin/main point to different commits.
  3. Open the worktree picker using the title-bar button or the git: worktree action.
  4. Try to create a worktree based on local main, including its unpushed commits.

The picker visibly offers only “Create new worktree based on origin/main”; the active main worktree is listed below it. There is no corresponding creation option based on local main.

Current vs. Expected behavior

Current: The picker hides the current-branch creation target when its branch name matches the remote default branch name. Local main is therefore unavailable as a creation base even when it contains commits absent from origin/main.

Expected: Allow creation from the current local branch when it differs from the remote-tracking default branch. Matching branch names do not imply matching commits. Always offering both targets, or suppressing the local target only when their commit IDs match, would avoid losing this choice.

The documentation says the picker can create a linked worktree from either the current branch or the default branch: https://zed.dev/docs/git#git-worktrees

Relevant implementation

Source inspected at commit 37faef81f74fc1bb08be9939c4cffc8ede6ced2f:

https://github.com/zed-industries/zed/blob/37faef81f74fc1bb08be9939c4cffc8ede6ced2f/crates/git_ui_core/src/worktree_service.rs#L100-L120

worktree_create_targets() compares current_branch_name with default_branch.branch_name and adds CurrentBranch only when those names differ. It does not compare commit IDs. Thus main versus origin/main suppresses the local target regardless of whether their histories differ. This is a source-based diagnosis; no patched build was tested.

Workaround

Create the worktree from the terminal with an explicit local base:

git worktree add -b my-feature ../my-feature main

Zed version and system specs

Zed 1.25.3 (installed application CLI version) OS: macOS 27.2

Logs and settings

No logs or private settings included; the issue concerns the visible picker options and the branch-name comparison above.

Activity

1
yeskunall2d ago

I reproduced this in Zed Nightly 1.27.0 (bundle build 20261028.024048) on macOS 15.8.1 arm64, using a local-only Git origin and clone.

With local main one commit ahead of origin/main, the picker offered only “Create new worktree based on origin/main”. The checked “main worktree” row showed the local commit, but was not a creation target. I expected a local main creation choice so the new worktree could include the unpushed commit.

Reproduction steps

Create a disposable fixture:

root=$(mktemp -d)
git init --bare --initial-branch=main "$root/origin.git"
git clone "$root/origin.git" "$root/repro"
cd "$root/repro"
git -c user.name=Repro -c user.email=repro@example.invalid \
  -c commit.gpgsign=false commit --allow-empty -m base
git push origin main
git remote set-head origin -a
git -c user.name=Repro -c user.email=repro@example.invalid \
  -c commit.gpgsign=false commit --allow-empty -m local-only

Open the clone in Zed and run git: worktree. Dismiss the picker, run git switch -c local-base-control, and reopen it. Then repeat after git switch main.

On local-base-control at the identical commit, both origin/main and local-base-control appeared as creation targets. Switching back to main removed the local creation choice again. origin/main stayed unchanged throughout.

I also verified the workaround git worktree add -b workaround ../workaround main: the new worktree started at the local tip, including the unpushed commit. I did not test a patched build.

Picker comparison

Same local commit in both screenshots. Local paths are redacted.