Skip to content

feat(refresh-repo): auto-restore main worktree to main branch#318

Open
JacobPEvans wants to merge 1 commit into
mainfrom
fix/worktree-main-convention-enforce
Open

feat(refresh-repo): auto-restore main worktree to main branch#318
JacobPEvans wants to merge 1 commit into
mainfrom
fix/worktree-main-convention-enforce

Conversation

@JacobPEvans
Copy link
Copy Markdown
Owner

Summary

Adds a step to the refresh-repo Sync Workflow that detects and fixes a
common workspace drift: the <repo>/main/ worktree left checked out to a
now-[gone] feature branch after that branch's PR merged.

This violates the convention in ~/git/CLAUDE.md:

Main worktree always at ~/git/<repo>/main/ on the main branch.

A workspace sweep observed this drift in four repos: docs,
dryvist-dotgithub, dryvist-dotgithub-tofu, and tf-splunk-aws.

Behavior

In Step 3 (Sync Workflow), immediately after the default-branch is
resolved and before the fast-forward merge:

  • Resolve the default-branch worktree path from git worktree list.
  • If git -C <path> symbolic-ref --short HEAD is not the default branch:
    • If the worktree has uncommitted changes (git status --porcelain
      is non-empty), stash them with a recoverable label
      (refresh-repo: auto-stash before <default> restore) and surface
      the stash ref in the summary.
    • git -C <path> checkout <default>.
  • Never --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

  • Manually drop <repo>/main/ onto a [gone] feature branch and
    run /refresh-repo; verify it stashes (if dirty), checks out
    main, and fast-forwards.
  • Run /refresh-repo on a repo where <repo>/main/ is already on
    main and verify no-op behavior (no extra stash, no unnecessary
    checkout).
  • Run on a repo with a dirty main/ worktree on a feature branch
    and confirm the stash reference is reported.

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.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

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.

Comment on lines +60 to +61
- Resolve the default worktree path from `git worktree list` — the entry whose
path basename matches the default branch (e.g. `<repo>/main` for `main`).
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

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>/.

Suggested change
- 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:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

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
  1. 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.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

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.

Suggested change
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
  1. 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
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

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.

Suggested change
- 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

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.

1 participant