Skip to content

fix(scripts/cloneWorkTree.fsx): add branch to fetch refspec before git fetch --all#296

Open
nodefect wants to merge 3 commits into
tarsgate:masterfrom
nodefect:clone-worktree-fix-bis
Open

fix(scripts/cloneWorkTree.fsx): add branch to fetch refspec before git fetch --all#296
nodefect wants to merge 3 commits into
tarsgate:masterfrom
nodefect:clone-worktree-fix-bis

Conversation

@nodefect

@nodefect nodefect commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Fixes #292

Problem

When cloneWorkTree.fsx is run on an existing clone to add a worktree for a branch that exists remotely but hasn't been fetched yet, git fetch --all would not pull the branch because the bare clone's fetch refspec only includes the default branch. As a result, git worktree add would create a worktree pointing to a local ref that was absent or outdated, effectively checking out the default branch (main) instead of the requested remote branch.

Fix

Before git fetch --all, run git remote set-branches --add <remote> <branchName> on all remotes to ensure the branch is included in the fetch refspec. This ensures the remote branch is actually fetched, so git worktree add <folder> <branch> correctly checks out the intended branch.

Refactoring

Removed the separate remoteBranchExists variable and consolidated branch checking into a single branchExists binding:

  • For existing clones: check all configured remotes via git ls-remote
  • For new clones: check the provided URL via git ls-remote

This eliminates the split between isUrl/isExistingClone logic for branch checks and ensures there's only one conceptual invocation of git ls-remote.

Updates

Addressed the TODO regarding headBranch for FolderName arguments: when the first argument is a local folder path rather than a URL, the script now queries the current default branch via git symbolic-ref --short HEAD and includes it in the fetch refspec alongside the requested branch. If the query fails (e.g., detached HEAD), it gracefully falls back to fetching only the target branch.

@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@knocte knocte force-pushed the clone-worktree-fix-bis branch from cdd219d to 01496fb Compare June 12, 2026 08:50
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@knocte knocte force-pushed the clone-worktree-fix-bis branch 2 times, most recently from 87cd1c6 to 40c4a62 Compare June 12, 2026 10:41
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@knocte knocte force-pushed the clone-worktree-fix-bis branch from 06b20ad to beb6ec9 Compare June 12, 2026 11:31
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@nodefect nodefect force-pushed the clone-worktree-fix-bis branch 3 times, most recently from 5c05f68 to 52912a2 Compare June 12, 2026 16:41
@knocte knocte force-pushed the clone-worktree-fix-bis branch 3 times, most recently from 93a5f2a to 73f9c39 Compare June 12, 2026 18:25
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@tarsgate tarsgate deleted a comment from nodefect Jun 12, 2026
@knocte knocte force-pushed the clone-worktree-fix-bis branch 3 times, most recently from bd0d748 to 911dfde Compare June 12, 2026 23:06
@knocte knocte force-pushed the clone-worktree-fix-bis branch 11 times, most recently from a5d9150 to 68011fc Compare June 14, 2026 13:59
@tarsgate tarsgate deleted a comment from nodefect Jun 14, 2026
@tarsgate tarsgate deleted a comment from nodefect Jun 14, 2026
@knocte

knocte commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

/pi please review this PR

@nodefect

nodefect commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

Overall this is a solid and much-needed fix for #292. The core change — running git remote set-branches --add before git fetch --all — correctly addresses the root cause where git fetch --all silently fails to pull branches outside the default refspec.

However, I have a few concerns with the refactoring that introduce functional regressions.


🐛 Bug: headBranch parsing breaks for default branches with /

The git ls-remote --symref parsing logic:

.Split('/')
.Last()
.Split('\t')
.First()

is broken when the remote's default branch contains slashes (e.g. release/1.0, hotfix/fix-123). For refs/heads/release/1.0, this extracts 1.0 instead of release/1.0, which then gets passed to:

"clone --single-branch --branch %s --bare %s .bare"

causing the clone to fail because 1.0 is not a valid branch name.

Suggestion: Replace the split-chain with something that strips the known prefix ref: refs/heads/ and then splits on tab, or simply drop --branch %s from the clone command entirely. git clone --single-branch --bare <url> already fetches the remote's default branch correctly, so headBranch may not be needed for the clone step.


⚠️ Regression: Script no longer cds into the worktree

The original script ended with:

Directory.SetCurrentDirectory branchFolderName

This line is gone in the refactored version. If callers (CI steps, other scripts, or users) depend on the script leaving them in the newly-created worktree directory, this is a breaking change. If this removal is intentional, it should be called out explicitly in the PR description; otherwise it should be restored.


📝 Unintended behavior change for new clones

Previously, when cloning a URL and the requested branch existed remotely, the bare clone was created with --branch <requestedBranch>, meaning the bare repo's single fetched branch was the one the user actually asked for.

Now, the bare repo is always cloned with --branch <headBranch> (the remote's default branch). The requested branch is only fetched later via set-branches + fetch --all. This means:

  • More data is fetched (default branch + requested branch vs. just requested branch).
  • The bare repo's HEAD points to the default branch, not the requested one.

This may be fine (and arguably more robust), but it changes the script's contract and should be documented if intentional.


💡 Minor note

  • The TODO: The // TODO: add headBranch even if ArgType is not URL? comment should either be resolved or turned into a follow-up issue rather than left in the script.

Bottom line: The set-branches fix is correct. Please address the headBranch parsing bug (either fix or remove the parsing) and clarify whether the missing cd and the clone behavior change are intentional.


View action run | Model: ppq/autoclaw | Time: 3m 42s | Tokens: 75.9K | Cost: $0.03 | Pi SDK v0.78.1 | Action v2.19.2

@knocte knocte force-pushed the clone-worktree-fix-bis branch 2 times, most recently from c7552b1 to 43308b0 Compare June 14, 2026 14:50
@knocte knocte closed this Jun 14, 2026
@knocte knocte force-pushed the clone-worktree-fix-bis branch from 43308b0 to 58be90e Compare June 14, 2026 14:56
@knocte knocte reopened this Jun 14, 2026
@knocte

knocte commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

/pi ok please address the "// TODO: add headBranch even if ArgType is not URL?", as it was suggested in the PR review

Remember that you can pull nodefect's branch (on nodefect's fork) and push commits on top of it (the TOKEN you have available is the one that corresponds to this nodefect github account).

@nodefect

Copy link
Copy Markdown
Contributor Author

Done. Pushed a commit to the PR branch that resolves the TODO:

  • Removed the // TODO: add headBranch even if ArgType is not URL? comment.
  • Added logic to query the default branch via git symbolic-ref --short HEAD when the first argument is a local folder path (FolderName). If the command succeeds, headBranch is included in the fetch refspec alongside the requested branch; if it fails (e.g. detached HEAD), the script gracefully falls back to fetching only the target branch.

This makes the set-branches behavior consistent between URL and folder-path inputs.


View action run | Model: ppq/autoclaw | Time: 5m 20s | Tokens: 305.5K | Cost: $0.11 | Pi SDK v0.78.1 | Action v2.19.2

GitHub Actions and others added 3 commits June 14, 2026 17:15
Use git remote set-brances --add (fetch branch) for the target
branch and head branch (main/master) in all remotes that contain
them; and stop using `git rev-parse` because we prefer to use
remote info rather than local (and potentially outdated) info.

Also refactored: it turns out that the invocation of
'git symbolic-ref' was dead code (maybe since the introduction
of 'git worktree add -b' usage).

Fixes tarsgate#292
If a branch is in many remotes at the same time, prefix it with
the remote name (and prefer non forks when choosing the remote
name), otherwise the 'git worktree add' command could fail with:

```
git worktree add wip-npmAudit wip/npmAudit
fatal: invalid reference: wip/npmAudit
Git worktree add failed.
```
Fetch head branch in fetch refspec also for FolderName args.
@knocte knocte force-pushed the clone-worktree-fix-bis branch 2 times, most recently from 37e9c2b to 731822e Compare June 14, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(cloneWorkTree.fsx): if branch exists, it's not pulled properly

2 participants