From f27a8233bc8217ea8470579e077b57e5bbc49c65 Mon Sep 17 00:00:00 2001 From: plebeius Date: Tue, 10 Mar 2026 16:23:09 +0800 Subject: [PATCH] fix(ai-workflow): delete merged local task branches --- .codex/hooks/sync-git-branches.sh | 40 +++++++++++++++++++-- .codex/skills/review-and-merge-pr/SKILL.md | 3 +- .cursor/hooks/sync-git-branches.sh | 40 +++++++++++++++++++-- .cursor/skills/review-and-merge-pr/SKILL.md | 3 +- 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/.codex/hooks/sync-git-branches.sh b/.codex/hooks/sync-git-branches.sh index 09ec8fc3..e7bb7e5d 100755 --- a/.codex/hooks/sync-git-branches.sh +++ b/.codex/hooks/sync-git-branches.sh @@ -38,6 +38,31 @@ branch_is_integrated() { return 0 } +branch_has_live_upstream() { + local upstream="$1" + [ -n "$upstream" ] && git show-ref --verify --quiet "refs/remotes/$upstream" +} + +merged_pr_number_for_branch() { + local branch="$1" + local pr_number="" + + if ! command -v gh >/dev/null 2>&1; then + return 0 + fi + + case "$branch" in + pr/*) + pr_number="${branch#pr/}" + gh pr view "$pr_number" --repo bitsocialnet/5chan --json mergedAt --jq 'select(.mergedAt != null) | .mergedAt' >/dev/null 2>&1 || return 0 + echo "$pr_number" + return 0 + ;; + esac + + gh pr list --repo bitsocialnet/5chan --state merged --head "$branch" --json number --jq '.[0].number // empty' 2>/dev/null || true +} + echo "Syncing git refs and temporary branches..." echo "" @@ -54,17 +79,28 @@ git fetch --prune origin 2>&1 || true echo "" while IFS='|' read -r branch upstream; do + local_pr_number="" + [ -z "$branch" ] && continue [ "$branch" = "$current_branch" ] && continue [ "$branch" = "$default_branch" ] && continue branch_looks_temporary "$branch" || continue - branch_is_integrated "$branch" || continue + local_pr_number="$(merged_pr_number_for_branch "$branch")" - if [ -n "$upstream" ] && git show-ref --verify --quiet "refs/remotes/$upstream"; then + if branch_has_live_upstream "$upstream"; then continue fi + if ! branch_is_integrated "$branch" && [ -z "$local_pr_number" ]; then + continue + fi + + if [ -n "$local_pr_number" ]; then + echo "=== merged PR #$local_pr_number allows deleting $branch ===" + echo "" + fi + echo "=== git branch -D $branch ===" git branch -D "$branch" 2>&1 || true echo "" diff --git a/.codex/skills/review-and-merge-pr/SKILL.md b/.codex/skills/review-and-merge-pr/SKILL.md index dc879372..73d07283 100644 --- a/.codex/skills/review-and-merge-pr/SKILL.md +++ b/.codex/skills/review-and-merge-pr/SKILL.md @@ -152,6 +152,7 @@ After the PR is merged: git switch master git pull --ff-only git branch -D 2>/dev/null || true +git branch -D "pr/" 2>/dev/null || true ``` If the PR branch lived in a dedicated worktree, remove that worktree after leaving it: @@ -171,4 +172,4 @@ Tell the user: - whether the PR was merged - whether the linked issue was confirmed closed - whether the linked project item was confirmed `Done` -- whether the branch and any worktree were cleaned up +- whether the feature branch, local `pr/` alias, and any worktree were cleaned up diff --git a/.cursor/hooks/sync-git-branches.sh b/.cursor/hooks/sync-git-branches.sh index 09ec8fc3..e7bb7e5d 100755 --- a/.cursor/hooks/sync-git-branches.sh +++ b/.cursor/hooks/sync-git-branches.sh @@ -38,6 +38,31 @@ branch_is_integrated() { return 0 } +branch_has_live_upstream() { + local upstream="$1" + [ -n "$upstream" ] && git show-ref --verify --quiet "refs/remotes/$upstream" +} + +merged_pr_number_for_branch() { + local branch="$1" + local pr_number="" + + if ! command -v gh >/dev/null 2>&1; then + return 0 + fi + + case "$branch" in + pr/*) + pr_number="${branch#pr/}" + gh pr view "$pr_number" --repo bitsocialnet/5chan --json mergedAt --jq 'select(.mergedAt != null) | .mergedAt' >/dev/null 2>&1 || return 0 + echo "$pr_number" + return 0 + ;; + esac + + gh pr list --repo bitsocialnet/5chan --state merged --head "$branch" --json number --jq '.[0].number // empty' 2>/dev/null || true +} + echo "Syncing git refs and temporary branches..." echo "" @@ -54,17 +79,28 @@ git fetch --prune origin 2>&1 || true echo "" while IFS='|' read -r branch upstream; do + local_pr_number="" + [ -z "$branch" ] && continue [ "$branch" = "$current_branch" ] && continue [ "$branch" = "$default_branch" ] && continue branch_looks_temporary "$branch" || continue - branch_is_integrated "$branch" || continue + local_pr_number="$(merged_pr_number_for_branch "$branch")" - if [ -n "$upstream" ] && git show-ref --verify --quiet "refs/remotes/$upstream"; then + if branch_has_live_upstream "$upstream"; then continue fi + if ! branch_is_integrated "$branch" && [ -z "$local_pr_number" ]; then + continue + fi + + if [ -n "$local_pr_number" ]; then + echo "=== merged PR #$local_pr_number allows deleting $branch ===" + echo "" + fi + echo "=== git branch -D $branch ===" git branch -D "$branch" 2>&1 || true echo "" diff --git a/.cursor/skills/review-and-merge-pr/SKILL.md b/.cursor/skills/review-and-merge-pr/SKILL.md index dc879372..73d07283 100644 --- a/.cursor/skills/review-and-merge-pr/SKILL.md +++ b/.cursor/skills/review-and-merge-pr/SKILL.md @@ -152,6 +152,7 @@ After the PR is merged: git switch master git pull --ff-only git branch -D 2>/dev/null || true +git branch -D "pr/" 2>/dev/null || true ``` If the PR branch lived in a dedicated worktree, remove that worktree after leaving it: @@ -171,4 +172,4 @@ Tell the user: - whether the PR was merged - whether the linked issue was confirmed closed - whether the linked project item was confirmed `Done` -- whether the branch and any worktree were cleaned up +- whether the feature branch, local `pr/` alias, and any worktree were cleaned up