Skip to content

Commit 552d94c

Browse files
committed
fix: detect squash-merged branches for SSH workspace deletion
SSH workspaces required force deletion after squash-merging PRs because the check used 'git log --branches --not --remotes' which always shows commits for squash-merged branches (original commits differ from squash commit SHA). Added content-based comparison when unpushed commits are detected: - Fetch latest default branch from origin - Get files changed on branch since merge-base - Compare each file's content between HEAD and origin/$DEFAULT - If all files match, treat as merged (squash-merge case) This allows clean deletion of squash-merged branches without forcing, while still protecting branches with genuinely unmerged work.
1 parent 12cf0f4 commit 552d94c

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

src/node/runtime/SSHRuntime.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,13 +1097,48 @@ export class SSHRuntime implements Runtime {
10971097
fi
10981098
fi
10991099
1100-
# If we have both branch and default, use show-branch for better output
1100+
# Check for squash-merge: if all changed files match origin/$DEFAULT, content is merged
1101+
if [ -n "$DEFAULT" ]; then
1102+
# Fetch latest to ensure we have current remote state
1103+
git fetch origin "$DEFAULT" --quiet 2>/dev/null || true
1104+
1105+
# Get merge-base between current branch and default
1106+
MERGE_BASE=$(git merge-base "origin/$DEFAULT" HEAD 2>/dev/null)
1107+
if [ -n "$MERGE_BASE" ]; then
1108+
# Get files changed on this branch since fork point
1109+
CHANGED_FILES=$(git diff --name-only "$MERGE_BASE" HEAD 2>/dev/null)
1110+
1111+
if [ -n "$CHANGED_FILES" ]; then
1112+
# Check if all changed files match what's in origin/$DEFAULT
1113+
ALL_MERGED=true
1114+
while IFS= read -r f; do
1115+
# Compare file content between HEAD and origin/$DEFAULT
1116+
# If file doesn't exist in one but exists in other, they differ
1117+
if ! git diff --quiet "HEAD:$f" "origin/$DEFAULT:$f" 2>/dev/null; then
1118+
ALL_MERGED=false
1119+
break
1120+
fi
1121+
done <<< "$CHANGED_FILES"
1122+
1123+
if $ALL_MERGED; then
1124+
# All changes are in default branch - safe to delete (squash-merge case)
1125+
exit 0
1126+
fi
1127+
else
1128+
# No changed files means nothing to merge - safe to delete
1129+
exit 0
1130+
fi
1131+
fi
1132+
fi
1133+
1134+
# If we get here, there are real unpushed changes
1135+
# Show helpful output for debugging
11011136
if [ -n "$BRANCH" ] && [ -n "$DEFAULT" ] && git show-branch "$BRANCH" "origin/$DEFAULT" >/dev/null 2>&1; then
11021137
echo "Branch status compared to origin/$DEFAULT:" >&2
11031138
echo "" >&2
11041139
git show-branch "$BRANCH" "origin/$DEFAULT" 2>&1 | head -20 >&2
11051140
echo "" >&2
1106-
echo "Note: If your PR was squash-merged, these commits are already in origin/$DEFAULT and safe to delete." >&2
1141+
echo "Note: Branch has changes not yet in origin/$DEFAULT." >&2
11071142
else
11081143
# Fallback to just showing the commit list
11091144
echo "$unpushed" | head -10 >&2

0 commit comments

Comments
 (0)