Skip to content

docs(switch): say why a branch off a remote base has no upstream - #3913

Open
worktrunk-bot wants to merge 2 commits into
mainfrom
docs/issue-3912-remote-base-upstream
Open

docs(switch): say why a branch off a remote base has no upstream#3913
worktrunk-bot wants to merge 2 commits into
mainfrom
docs/issue-3912-remote-base-upstream

Conversation

@worktrunk-bot

@worktrunk-bot worktrunk-bot commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Problem

wt switch --create <name> --base origin/<branch> leaves the new branch with no upstream — deliberately, since git would otherwise set it to track the base (#713). Nothing in wt switch's help or the site docs says this happens or what to do about it, so the user is left with a branch that a bare git push refuses and no stated way to publish it. #3912 is the third thread to arrive at the same manual git push --set-upstream origin <branch> step.

Solution

One paragraph in the Creating a branch section of wt switch's after_long_help: what the unset is for, and the two ways to publish — the explicit git push --set-upstream, or git's push.autoSetupRemote = true, after which a bare git push from the new worktree publishes the branch and configures its tracking. The paragraph also names the bare --base release form, which resolve_base_ref promotes to origin/release when the name exists on exactly one remote and not locally, landing in the same no-upstream state.

The rationale is scoped to push.default = upstream, which is the configuration the unset actually protects: under git's default simple, a feature branch tracking origin/release refuses the bare push rather than pushing to release. The same overstatement was in the code comment above unset_upstream() in src/commands/worktree/switch.rs, corrected here alongside it.

No behavior change — help text, its three generated mirrors, and one code comment.

Testing

Claims verified against scratch repos with a local bare origin, using target/debug/wt and git 2.55.0:

Verification

Explicit remote base, and the bare remote-only base that resolves to it:

$ wt switch --create feature/2.0.0/baseline --base origin/release/2.0.0 --no-cd
✓ Created branch feature/2.0.0/baseline from origin/release/2.0.0 and worktree @ …
$ wt switch --create feat --base release --no-cd     # `release` exists only on origin
✓ Created branch feat from origin/release and worktree @ /tmp/repro2/work.feat
$ git branch -vv
+ feat 6f3c01c (/tmp/repro2/work.feat) r2            # no upstream
* main 4cbf891 [origin/main] r1

push.default under a branch that tracks origin/release:

$ git config --get push.default          # unset → "simple"
$ git push
fatal: The upstream branch of your current branch does not match
the name of your current branch.  To push to the upstream branch
on the remote, use

    git push origin HEAD:release
$ git -c push.default=upstream push --dry-run
   b119751..b340114  feature -> release

With push.autoSetupRemote = true set, a bare git push from the new worktree:

$ git push
 * [new branch]      feature/2.0.0/autosetup -> feature/2.0.0/autosetup
branch 'feature/2.0.0/autosetup' set up to track 'origin/feature/2.0.0/autosetup'.

cargo test --test integration test_docs_are_in_sync regenerated the three mirrors (site page, skill reference, plugin skills mirror) and passes on a second run; cargo insta test --accept --test integration -- test_help refreshed help_switch_long.


Refs #3912 — automated triage

Creating from a remote base deliberately unsets the tracking git would
otherwise set to the base (#713), so a bare `git push` cannot push the
new work to the base branch. Nothing said so, leaving the branch with no
upstream and no stated way to publish it.

Refs #3912
@worktrunk-bot worktrunk-bot added the automated-fix Automated CI fix label Aug 25, 2026

@worktrunk-bot worktrunk-bot left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The behavior claim is right — switch.rs unsets the upstream whenever --create's base is a remote-tracking ref (the is_remote_tracking_branch(base) arm, citing #713) — and I reproduced the push.autoSetupRemote = true path exactly as written. One inline suggestion on the rationale sentence, which doesn't hold under git's default config.

One thing the paragraph under-describes: resolve_base_ref promotes a bare base to origin/<base> when the name exists on exactly one remote and not locally (the remotes.len() == 1 arm in src/commands/worktree/switch.rs), so --base release against a remote-only release lands in the same no-upstream state as the explicit --base origin/release the paragraph shows. Worth a few words if it fits, though the explicit form is the one #3912 hit.

Repro for the inline suggestion (git 2.55.0, default config)
$ git config --get push.default    # unset → "simple"
$ git worktree add -b feature ../ft origin/release
$ git branch -vv
* feature 48b8215 [origin/release] r1
$ git push
fatal: The upstream branch of your current branch does not match
the name of your current branch.  To push to the upstream branch
on the remote, use

    git push origin HEAD:release

Under push.default = upstream it does what the paragraph says:

$ git -c push.default=upstream push --dry-run
To ../origin.git
   48b8215..5c1fec7  feature -> release

So the unset protects the upstream configuration specifically; under simple both states refuse the bare push, just with different messages.

Comment thread src/cli/mod.rs Outdated
Also covers the bare `--base release` that resolve_base_ref promotes to
`origin/release`, and corrects the same overstatement in the code comment
above unset_upstream().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automated-fix Automated CI fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant