| name | refresh-repo |
| description | Check PR merge readiness, sync local repo, cleanup stale worktrees; optional cross-repo sweep and stale-branch prune modes |
Git Refresh
Check open PR merge-readiness status, sync the local repository, and cleanup stale worktrees.
State warning: Branch state, remote tracking, and PR status change between
invocations. Re-run all git/gh commands from Step 1.
Steps
1. Identify Open PRs
CRITICAL: Always check for open PRs, regardless of current branch.
gh pr view --json state,number,title 2>/dev/null
gh pr list --author @me --state open --json number,title,headRefName
2. Report Merge-Readiness Status
For each open PR, check and report.
Run the canonical PR-readiness gate from /gh-cli-patterns.
Replace <OWNER>, <REPO>, <PR_NUMBER> per the placeholder legend in that skill.
Merge-ready criteria — all of the following must hold:
| Field | Required | Status |
|---|
state | OPEN | Not ready |
mergeable | MERGEABLE | Not ready |
mergeStateStatus | CLEAN or HAS_HOOKS | Not ready (BEHIND, BLOCKED, DIRTY, UNSTABLE, UNKNOWN, DRAFT) |
isDraft | false | Not ready |
reviewDecision | APPROVED or null | Not ready |
statusCheckRollup.state | SUCCESS | Not ready |
All reviewThreads.isResolved | true | Not ready — unresolved threads |
reviewThreads.pageInfo.hasNextPage | false | Not ready — >100 threads, paginate |
3. Sync Workflow
- Record the current branch and worktree path.
- Fetch origin with stale remote branch pruning, but without tag updates:
git fetch origin --no-tags --prune --force
- Determine the default branch from
origin/HEAD, falling back to main or master.
- Restore the default-branch worktree to the default branch. If a
worktree is checked out to the default branch, keep it on the default
branch. After a feature PR merges, that worktree is sometimes left on the
now-
[gone] feature branch. Detect and fix:
- Resolve the default worktree path from
git worktree list --porcelain,
matching on the branch refs/heads/<default> entry — do not rely on
basename matching of paths, since a feature branch named
feature/<default> would also produce a path basename of <default>.
- If that path exists and
git -C <path> rev-parse --abbrev-ref HEAD does not equal
<default> (this is safer than symbolic-ref --short HEAD, which errors on
detached HEAD during a rebase or commit-checkout):
- If the worktree has uncommitted changes
(
git -C <path> status --porcelain is non-empty), stash them first with
git -C <path> stash push -u -m "refresh-repo: auto-stash before <default> restore"
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.
- Sync the default branch from its dedicated worktree with a fast-forward only merge,
using
git -C <path> so the merge always targets the default worktree regardless
of the current shell directory:
git -C <path> merge --ff-only origin/<default>.
If the default worktree is dirty or divergent, report it and skip instead of resetting.
- Delete local branches already merged into the default branch with
git branch -d.
Never delete main/master/develop/current branches, worktree-checked-out branches, or branches
with open PRs.
- Conclude the operation without switching branches. Because Steps 4 and 5 used
git -C <path> to operate on the default worktree directly, the current shell's
working directory and branch were never changed — each worktree owns its checkout.
Do not use git fetch --tags, git fetch --prune-tags, or git pull --tags during the
normal refresh. Tags are audited separately in Step 4 so local-only non-release tags and
tag rewrites are not deleted by a broad fetch refspec.
4. Tag Audit And Cleanup
Treat origin as authoritative for release tags only.
Use native Git commands to compare local tags to remote tags:
git for-each-ref '--format=%(refname:short)' refs/tags
git show-ref --tags
git ls-remote --tags --refs origin
For local-only tags:
- If the tag name matches the release tag pattern
v[0-9]*, delete it with
git tag -d <tag>.
- If the tag name does not match the release tag pattern, report it and do not delete it.
For tags that exist both locally and on origin but point at different objects, report the
mismatch and do not force-update it automatically. Never delete or rewrite remote tags.
5. Worktree Cleanup
Only remove a worktree if it is confirmed stale.
Stale definition: No open PR, no uncommitted changes, and either:
- The branch has a merged PR (most recently merged by
mergedAt) whose headRefOid matches the local branch HEAD
(gh pr list --state merged --head <branch> --json number,headRefOid,mergedAt)
- Its remote tracking branch was deleted (
[gone] in git branch -vv) and it has no commits
ahead of the default branch (git log origin/<default>..HEAD --oneline is empty)
Branches with open PRs, local-only branches without PRs, and worktrees with uncommitted
changes are NEVER stale.
For each worktree from git worktree list:
- Skip the default branch worktree, the current branch, and bare repo entries
- If the branch has an open PR, skip — it is never stale
- Check if stale using the definition above
- If not stale, skip
- Run
git worktree remove <path> — NEVER use --force
- If Git blocks removal (dirty worktree), report it and skip
- If removed, also delete the branch:
git branch -d <branch>.
If this fails only because a squash-merged branch is not reachable from local default,
use git branch -D <branch> only when the merged PR headRefOid matched the local
branch HEAD before removing the worktree.
Finish with git worktree prune.
6. Summary
Report: PRs assessed as merge-ready (if any), tags deleted or reported, branches cleaned up,
worktrees removed, default-branch worktree restorations (with any stash references created),
current branch, and sync status.
Cross-Repo Operating Modes
Optional modes that change /refresh-repo from single-repo to workspace-wide.
Both modes reuse the stale-worktree definition from Step 5 and the deletion
rules from Step 5.7 — they only add new pre-filters, never weaken existing
safety.
--sweep [<repo-glob>]
Multi-repo cleanup of abandoned local branches. For every default-branch
worktree in your workspace (caller can pass a custom glob if their layout
differs), resolve that repo's own default branch first (per Step 3 above —
main on trunk repos, develop on git-flow repos), then for every local
branch where git log origin/<default>..HEAD is non-empty:
- Content-equivalence check: compute merge base, diff each touched file
against current
origin/<default>. If every touched file is content-equivalent
to (or older than) origin/<default>, delete the branch and its worktree.
Already-on-the-default-branch contributions do not deserve a PR.
- Workaround filter: if the diff (a) modifies 1 of N files sharing a
common shape with no written rationale for the asymmetry, or (b) references
a "sync mechanism" / "auto-update" by name that
grep -r <name> . returns
zero matches for, surface for human review. Do not open a draft.
- Only branches passing both checks become draft PRs.
- Per-repo summary: branches deleted as content-equivalent, branches surfaced
for review, branches PR-ified, branches unchanged.
Origin: the 2026-05-22 sweep opened 8 dead PRs against ansible-splunk
(6 already-on-main duplicates, 2 workaround anti-patterns). Both filters
above would have caught all 8 before any CI ran.
--prune-stale <days> (default 60)
Delete local branches with no open PR and no push activity within <days>.
Expands Step 5's stale definition with a time threshold; still respects every
safety rule (never delete branches with open PRs, uncommitted changes, or
the current checkout).
Per branch: if gh pr list --head <branch> is empty AND
git log -1 --format=%cr <branch> is older than <days>, run
git worktree remove <path> (per Step 5 — never --force) then
git branch -d <branch>.
Use --prune-stale 30 for an aggressive sweep, --prune-stale 90 for
conservative.
Common Mistake to Avoid
DO NOT skip the PR check just because you're on main. The user may have multiple open PRs from different branches.
Always run gh pr list --author @me --state open to find work that needs merging.
Do not use --prune-tags as a shortcut for tag cleanup. Git treats tag pruning as an
explicit refspec prune and can delete local-only tags that are not release artifacts.
Related Skills
- sync-main (git-workflows) — Syncs the default branch and merges into current or all PR branches
- rebase-pr (github-workflows) — Rebase-merge workflow for merging individual PRs
- git-workflow-standards (git-standards) — Worktree structure and branch hygiene conventions
- gh-cli-patterns (github-workflows) — Canonical gh CLI command shapes, placeholder convention, PR-readiness gate, default-branch detection