Skip to content

Commit 4c3ba66

Browse files
fix(find_git_conflicts): actually label conflicting PRs and stop skipping past 500 (#15182)
* fix(find_git_conflicts): actually label conflicting PRs and stop skipping past 500 * @priya-sundaram-dev #15181 * [x] Fix a script * Workaround for mapfile Co-authored-by: priya-sundaram-dev <oc-409d01@agentmail.to> * Update scripts/find_git_conflicts.sh Co-authored-by: priya-sundaram-dev <oc-409d01@agentmail.to> * Update scripts/find_git_conflicts.sh Co-authored-by: priya-sundaram-dev <oc-409d01@agentmail.to> --------- Co-authored-by: priya-sundaram-dev <oc-409d01@agentmail.to>
1 parent e5cca54 commit 4c3ba66

1 file changed

Lines changed: 72 additions & 9 deletions

File tree

scripts/find_git_conflicts.sh

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,79 @@
11
#!/bin/bash
2+
#
3+
# Find every open pull request that has git merge conflicts with the base
4+
# branch and label it "git merge conflict".
5+
#
6+
# Why this is not a one-liner: GitHub computes PR mergeability *asynchronously*,
7+
# so `gh pr list --json mergeable` frequently reports UNKNOWN for PRs it has not
8+
# recomputed yet. Viewing a PR individually nudges GitHub to compute the value,
9+
# so we re-query only the UNKNOWN PRs a few times before giving up. We also
10+
# avoid `--limit 500`, which silently skips any PR past the 500th (this repo has
11+
# well over 500 open PRs).
12+
#
13+
# Usage:
14+
# scripts/find_git_conflicts.sh # label conflicting PRs
15+
# DRY_RUN=1 scripts/find_git_conflicts.sh # list only, add no labels
16+
#
17+
# Environment overrides: REPO, LABEL, SLEEP (seconds between UNKNOWN retries).
218

3-
# Replace with your repository (format: owner/repo)
4-
REPO="TheAlgorithms/Python"
19+
set -euo pipefail
20+
21+
REPO="${REPO:-TheAlgorithms/Python}"
22+
LABEL="${LABEL:-git merge conflict}"
23+
DRY_RUN="${DRY_RUN:-0}"
24+
SLEEP="${SLEEP:-2}"
525

6-
# Fetch open pull requests with conflicts into a variable
726
echo "Checking for pull requests with conflicts in $REPO..."
827

9-
prs=$(gh pr list --repo "$REPO" --state open --json number,title,mergeable --jq '.[] | select(.mergeable == "CONFLICTING") | {number, title}' --limit 500)
28+
# Make sure the label exists (idempotent; ignore "already exists").
29+
if [[ "$DRY_RUN" != "1" ]]; then
30+
gh label create "$LABEL" --repo "$REPO" \
31+
--color "d93f0b" \
32+
--description "This pull request has git merge conflicts with the base branch" \
33+
2>/dev/null || true
34+
fi
35+
36+
# First pass: one bulk call. Fast, but mergeable is often UNKNOWN.
37+
# First pass: one bulk call. Fast, but mergeable is often UNKNOWN.
38+
rows=()
39+
while IFS= read -r row; do
40+
rows+=("$row")
41+
done < <(
42+
gh pr list --repo "$REPO" --state open --limit 5000 \
43+
--json number,mergeable --jq '.[] | "\(.number)\t\(.mergeable)"'
44+
)
45+
echo "Found ${#rows[@]} open pull requests to inspect."
46+
47+
conflicting=()
48+
unknown=()
49+
for row in "${rows[@]}"; do
50+
number="${row%%$'\t'*}"
51+
mergeable="${row##*$'\t'}"
52+
case "$mergeable" in
53+
CONFLICTING) conflicting+=("$number") ;;
54+
UNKNOWN) unknown+=("$number") ;;
55+
esac
56+
done
1057

11-
# Process each conflicting PR
12-
echo "$prs" | jq -c '.[]' | while read -r pr; do
13-
PR_NUMBER=$(echo "$pr" | jq -r '.number')
14-
PR_TITLE=$(echo "$pr" | jq -r '.title')
15-
echo "PR #$PR_NUMBER - $PR_TITLE has conflicts."
58+
# Second pass: re-query only the UNKNOWN PRs until GitHub finishes computing.
59+
for pr in ${unknown[@]+"${unknown[@]}"}; do
60+
mergeable="UNKNOWN"
61+
for _ in 1 2 3; do
62+
mergeable=$(gh pr view "$pr" --repo "$REPO" --json mergeable --jq '.mergeable')
63+
[[ "$mergeable" != "UNKNOWN" ]] && break
64+
sleep "$SLEEP"
65+
done
66+
[[ "$mergeable" == "CONFLICTING" ]] && conflicting+=("$pr")
1667
done
68+
69+
# Label the conflicting PRs.
70+
for pr in ${conflicting[@]+"${conflicting[@]}"}; do
71+
echo "PR #$pr has conflicts."
72+
if [[ "$DRY_RUN" != "1" ]]; then
73+
gh pr edit "$pr" --repo "$REPO" --add-label "$LABEL"
74+
fi
75+
done
76+
77+
# Machine-readable summary (mirrors the close_pull_requests_with_*.sh scripts).
78+
printf 'CONFLICTING_COUNT=%d CONFLICTING_PRS=%s\n' \
79+
"${#conflicting[@]}" "$(IFS=,; echo "${conflicting[*]}")"

0 commit comments

Comments
 (0)