feat(refresh-repo): auto-restore main worktree to main branch#318
feat(refresh-repo): auto-restore main worktree to main branch#318JacobPEvans wants to merge 1 commit into
Conversation
Adds a new step 4 to the refresh-repo Sync Workflow that detects when the default-branch worktree (e.g. <repo>/main/) is checked out to a non-default branch and restores it. After a feature PR merges, the main worktree is often left on the now-[gone] feature branch, violating the convention in ~/git/CLAUDE.md that "main worktree always at <repo>/main/" on the main branch. A workspace sweep observed this drift in 4 repos: docs, dryvist-dotgithub, dryvist-dotgithub-tofu, and tf-splunk-aws. The fix stashes any uncommitted work before checking out the default branch and surfaces the stash ref in the summary so the user can recover. No --force, no reset, no discard.
There was a problem hiding this comment.
Code Review
This pull request updates the refresh-repo skill documentation to include a new step for restoring the default-branch worktree, including logic for stashing uncommitted changes and checking out the default branch. Review feedback suggests several improvements for robustness and policy compliance: using explicit paths instead of basenames to avoid ambiguity, replacing symbolic-ref with rev-parse to handle detached HEAD states, ensuring sync commands target the specific worktree path using git -C, and removing unnecessary branch-switching steps to adhere to worktree management conventions.
| - Resolve the default worktree path from `git worktree list` — the entry whose | ||
| path basename matches the default branch (e.g. `<repo>/main` for `main`). |
There was a problem hiding this comment.
Matching the worktree by basename is ambiguous. For example, a feature branch named feature/main would have a worktree path like ~/git/<repo>/feature/main/, which also has the basename main. Additionally, in a bare-repo setup, the repository root itself might match if the repo is named main. It is safer to resolve the path using the explicit convention: ~/git/<repo>/<default>/.
| - Resolve the default worktree path from `git worktree list` — the entry whose | |
| path basename matches the default branch (e.g. `<repo>/main` for `main`). | |
| - Resolve the default worktree path using the workspace convention: | |
| ~/git/<repo>/<default>/ |
| and surface the stash reference in the summary so the user can recover. | ||
| - `git -C <path> checkout <default>`. | ||
| - Never use `--force`, never discard uncommitted work, never reset. | ||
| 5. Sync the default branch from its existing worktree with a fast-forward only merge: |
There was a problem hiding this comment.
The sync command in the following line must be updated to use the <path> resolved in Step 4. Per the repository's general rules, syncing a branch in a worktree setup should be done by executing commands within its dedicated directory. Without git -C <path>, if the user is currently in a feature worktree, the merge will incorrectly target the feature branch instead of the default branch.
References
- In a git worktree setup where each branch has a dedicated directory, sync a branch by executing git commands from within its worktree directory, rather than using git switch to change branches in the current worktree.
| Never delete main/master/develop/current branches, worktree-checked-out branches, or branches | ||
| with open PRs. | ||
| 6. Switch back to the original branch if it still exists. | ||
| 7. Switch back to the original branch if it still exists. |
There was a problem hiding this comment.
This step suggests switching branches, which is discouraged in a git worktree setup. According to the repository rules, we should execute commands within the dedicated worktree directory instead of using git switch. If Step 4 is implemented by navigating to the correct directory or using git -C, this 'switch back' step should be removed to avoid violating the worktree management policy.
| 7. Switch back to the original branch if it still exists. | |
| 7. Conclude the operation without switching branches, as each worktree has a dedicated directory. |
References
- In a git worktree setup where each branch has a dedicated directory, sync a branch by executing git commands from within its worktree directory, rather than using git switch to change branches in the current worktree.
| often left on the now-`[gone]` feature branch. Detect and fix: | ||
| - Resolve the default worktree path from `git worktree list` — the entry whose | ||
| path basename matches the default branch (e.g. `<repo>/main` for `main`). | ||
| - If that path exists and `git -C <path> symbolic-ref --short HEAD` does not equal |
There was a problem hiding this comment.
Using git symbolic-ref --short HEAD will cause an error if the worktree is in a detached HEAD state (e.g., during a rebase or if a specific commit is checked out). Using git rev-parse --abbrev-ref HEAD is more robust as it returns the branch name or HEAD without failing.
| - If that path exists and `git -C <path> symbolic-ref --short HEAD` does not equal | |
| - If that path exists and git -C <path> rev-parse --abbrev-ref HEAD does not equal |
Summary
Adds a step to the
refresh-repoSync Workflow that detects and fixes acommon workspace drift: the
<repo>/main/worktree left checked out to anow-
[gone]feature branch after that branch's PR merged.This violates the convention in
~/git/CLAUDE.md:A workspace sweep observed this drift in four repos:
docs,dryvist-dotgithub,dryvist-dotgithub-tofu, andtf-splunk-aws.Behavior
In Step 3 (Sync Workflow), immediately after the default-branch is
resolved and before the fast-forward merge:
git worktree list.git -C <path> symbolic-ref --short HEADis not the default branch:git status --porcelainis non-empty), stash them with a recoverable label
(
refresh-repo: auto-stash before <default> restore) and surfacethe stash ref in the summary.
git -C <path> checkout <default>.--force, never reset, never discard uncommitted work.The existing fast-forward merge now runs on the restored default branch
instead of failing or no-op'ing on the wrong head.
Test plan
<repo>/main/onto a[gone]feature branch andrun
/refresh-repo; verify it stashes (if dirty), checks outmain, and fast-forwards./refresh-repoon a repo where<repo>/main/is already onmainand verify no-op behavior (no extra stash, no unnecessarycheckout).
main/worktree on a feature branchand confirm the stash reference is reported.