Skip to content

feat: add pre-push PR size check local hook#2939

Open
swasti29 wants to merge 2 commits into
devfrom
copilot/add-local-pre-push-hook
Open

feat: add pre-push PR size check local hook#2939
swasti29 wants to merge 2 commits into
devfrom
copilot/add-local-pre-push-hook

Conversation

@swasti29
Copy link
Copy Markdown
Contributor

@swasti29 swasti29 commented Apr 17, 2026

Adds a local git pre-push hook that warns developers when a push exceeds 500 changed lines, prompting to confirm or cancel. Fires on every push to any remote branch; bypassable via git push --no-verify.

New files

  • .githooks/pr-size-check.sh — Shared hook logic: resolves base branch, filters excluded file types, counts diff lines, prompts if over limit.
  • .githooks/pre-push — MSAL-specific entry point; sets EXTRA_EXCLUDES for test dirs, IdentityCore submodule, and Samples/.
  • Makefilemake setup target to activate hooks per clone.

Developer setup

make setup  # run once per clone

Add local pre-push hook that mirrors the remote PR Size Check workflow.
Warns when push exceeds 500 LOC (excluding tests, config, and non-source files).
Exclusions match pr-size-check-reusable.yml exactly.

Setup: run 'make setup' to enable the hook.
Bypass: git push --no-verify

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@@ -0,0 +1,91 @@
#!/usr/bin/env bash
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This pull request does not update CHANGELOG.md.

Please consider if this change would be noticeable to a partner or user and either update CHANGELOG.md or resolve this conversation.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds local Git hooks to provide an early, local version of the repository’s PR Size Check before developers push changes, plus a make setup helper to enable the hooks.

Changes:

  • Add a reusable pr-size-check.sh hook script with common exclusion patterns and a line-change threshold.
  • Add a repo-specific pre-push hook that supplies MSAL-specific path exclusions and sources the reusable logic.
  • Add a Makefile target (make setup) to configure core.hooksPath to .githooks.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
Makefile Adds setup target intended to configure core.hooksPath for local hooks.
.githooks/pre-push Defines MSAL-specific exclusions and sources the reusable size-check logic.
.githooks/pr-size-check.sh Implements local line-change counting and exclusion filtering with an interactive warning when over limit.

Comment thread Makefile
Comment on lines +2 to +3
git config core.hooksPath .githooks
@echo "✅ Git hooks configured. Pre-push PR size check is now active."
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

Issue: The Makefile recipe lines under setup are not indented with a tab, so make setup will error with “missing separator”.
Impact: The documented setup step won’t work, so contributors won’t be able to enable the hooks via make setup.
Recommendation: Indent each recipe line with a literal tab (or set .RECIPEPREFIX and use that prefix consistently) so the target executes correctly.

Suggested change
git config core.hooksPath .githooks
@echo "✅ Git hooks configured. Pre-push PR size check is now active."
git config core.hooksPath .githooks
@echo "✅ Git hooks configured. Pre-push PR size check is now active."

Copilot uses AI. Check for mistakes.
Comment thread .githooks/pr-size-check.sh Outdated
fi

# ── Get list of changed files (excluding patterns) ───────────
mapfile -t CHANGED_FILES < <(git diff --name-only "$BASE_BRANCH"...HEAD 2>/dev/null | grep -vE "$GREP_PATTERN")
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

Issue: mapfile -t is used to read changed files, but mapfile is not available in the default macOS /bin/bash (3.2).
Impact: The pre-push hook will fail for many macOS developers unless they’ve installed a newer Bash and it’s first in PATH.
Recommendation: Replace mapfile with a Bash 3.2-compatible loop (e.g., while IFS= read -r ...; do ...; done) or explicitly document/enforce a minimum Bash version and resolve Bash path accordingly.

Suggested change
mapfile -t CHANGED_FILES < <(git diff --name-only "$BASE_BRANCH"...HEAD 2>/dev/null | grep -vE "$GREP_PATTERN")
CHANGED_FILES=()
while IFS= read -r changed_file; do
CHANGED_FILES+=("$changed_file")
done < <(git diff --name-only "$BASE_BRANCH"...HEAD 2>/dev/null | grep -vE "$GREP_PATTERN")

Copilot uses AI. Check for mistakes.
Comment thread .githooks/pr-size-check.sh Outdated
echo " To push anyway: git push --no-verify"
echo " To cancel: Ctrl+C"
echo ""
read -r -p " Push anyway? [y/N]: " response
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

Issue: The confirmation prompt uses read from stdin, but for pre-push hooks stdin is the ref-update list provided by Git (not the terminal). When over the limit, read will hit EOF / consume hook input and default to cancelling without giving the user a chance to answer.
Impact: Large pushes can be incorrectly blocked (or behave unpredictably) even when a user intends to proceed.
Recommendation: Read from the controlling terminal (e.g., read ... < /dev/tty) and add a non-interactive fallback (e.g., if no TTY, print the warning and either allow the push or fail with a clear message).

Suggested change
read -r -p " Push anyway? [y/N]: " response
response=""
if [ -r /dev/tty ]; then
read -r -p " Push anyway? [y/N]: " response < /dev/tty
else
echo "Non-interactive environment detected; cannot prompt for confirmation."
echo "Push cancelled."
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +38
# ── Common exclusions (all repos) ────────────────────────────
COMMON_EXCLUDES=(
"\.pbxproj$"
"\.xcscheme$"
"\.xcsettings$"
"\.xcconfig$"
"\.xctestplan$"
"\.xcworkspace/"
"\.xcodeproj/"
"\.plist$"
"\.entitlements$"
"\.storyboard$"
"\.xib$"
"\.xcassets/"
"\.modulemap$"
"\.xcprivacy$"
"\.strings$"
"\.stringsdict$"
"\.xcstrings$"
"\.ya?ml$"
"\.lock$"
"\.(png|jpg|jpeg|svg|pdf|icns|gif|tiff)$"
"\.md$"
"\.mdx$"
)
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

Issue: The local hook’s COMMON_EXCLUDES doesn’t match the repo’s “single source of truth” workflow exclusions (e.g., it additionally excludes *.strings, *.stringsdict, and *.xcstrings).
Impact: Local warnings won’t mirror the GitHub PR Size Check results, which can lead to false negatives (no local warning but CI fails) or inconsistent expectations.
Recommendation: Align this list exactly with .github/workflows/pr-size-check-reusable.yml common exclusions, or clearly document any intentional differences in the hook header comment.

Copilot uses AI. Check for mistakes.
Comment thread .githooks/pr-size-check.sh Outdated
fi

# ── Get list of changed files (excluding patterns) ───────────
mapfile -t CHANGED_FILES < <(git diff --name-only "$BASE_BRANCH"...HEAD 2>/dev/null | grep -vE "$GREP_PATTERN")
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

Issue: Exclusion matching is case-sensitive (grep -vE), while the GitHub workflow compiles exclusions with the /i flag (case-insensitive).
Impact: The local size check can count files the workflow would exclude (or vice versa) if filenames use different casing (e.g., README.MD).
Recommendation: Make the exclusion filter case-insensitive (e.g., use grep -viE or normalize filenames) to better mirror the workflow behavior.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 17, 2026 03:14
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread .githooks/pr-size-check.sh Outdated
Comment on lines +84 to +87
read -r -p " Push anyway? [y/N]: " response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Push cancelled."
exit 1
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

In a pre-push hook, stdin is used by Git to pass the list of refs being pushed. The prompt read -r -p … response will read from that stdin (not from the user’s terminal), so when over the limit the hook will typically auto-decline and cancel the push.

Impact: pushes over the threshold can be blocked unexpectedly, and the user may never see a usable prompt.

Recommendation: read user input from /dev/tty (and/or only prompt when a TTY is available; otherwise just print a warning and allow the push).

Suggested change
read -r -p " Push anyway? [y/N]: " response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Push cancelled."
exit 1
if [ -r /dev/tty ]; then
printf " Push anyway? [y/N]: " > /dev/tty
read -r response < /dev/tty
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Push cancelled."
exit 1
fi
else
echo "ℹ️ No interactive terminal available; allowing push to continue."

Copilot uses AI. Check for mistakes.
Comment thread .githooks/pr-size-check.sh Outdated
Comment on lines +61 to +90
# ── Get list of changed files (excluding patterns) ───────────
mapfile -t CHANGED_FILES < <(git diff --name-only "$BASE_BRANCH"...HEAD 2>/dev/null | grep -vE "$GREP_PATTERN")

if [ "${#CHANGED_FILES[@]}" -eq 0 ]; then
exit 0
fi

# ── Count lines changed ───────────────────────────────────────
TOTAL_LINES=$(git diff "$BASE_BRANCH"...HEAD -- "${CHANGED_FILES[@]}" 2>/dev/null \
| grep -E "^\+|^-" \
| grep -vE "^\+\+\+|^---" \
| wc -l \
| tr -d ' ')

# ── Warn if over limit ────────────────────────────────────────
if [ "$TOTAL_LINES" -gt "$MAX_LINES" ]; then
echo ""
echo "⚠️ WARNING: Your push contains ~${TOTAL_LINES} line changes (limit: ${MAX_LINES})."
echo " Consider splitting this into smaller PRs."
echo ""
echo " To push anyway: git push --no-verify"
echo " To cancel: Ctrl+C"
echo ""
read -r -p " Push anyway? [y/N]: " response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Push cancelled."
exit 1
fi
fi

Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

The diff comparisons are hard-coded to ...HEAD, but a pre-push hook can push refs that aren’t the currently checked-out HEAD (e.g., git push origin other-branch, multiple refs, tags). This means the size check can run against the wrong commit range.

Impact: false positives/negatives (blocking or allowing pushes incorrectly).

Recommendation: consume the ref list provided on stdin by pre-push and compute the diff for the actual local SHA(s) being pushed (or skip non-branch pushes explicitly).

Suggested change
# ── Get list of changed files (excluding patterns) ───────────
mapfile -t CHANGED_FILES < <(git diff --name-only "$BASE_BRANCH"...HEAD 2>/dev/null | grep -vE "$GREP_PATTERN")
if [ "${#CHANGED_FILES[@]}" -eq 0 ]; then
exit 0
fi
# ── Count lines changed ───────────────────────────────────────
TOTAL_LINES=$(git diff "$BASE_BRANCH"...HEAD -- "${CHANGED_FILES[@]}" 2>/dev/null \
| grep -E "^\+|^-" \
| grep -vE "^\+\+\+|^---" \
| wc -l \
| tr -d ' ')
# ── Warn if over limit ────────────────────────────────────────
if [ "$TOTAL_LINES" -gt "$MAX_LINES" ]; then
echo ""
echo "⚠️ WARNING: Your push contains ~${TOTAL_LINES} line changes (limit: ${MAX_LINES})."
echo " Consider splitting this into smaller PRs."
echo ""
echo " To push anyway: git push --no-verify"
echo " To cancel: Ctrl+C"
echo ""
read -r -p " Push anyway? [y/N]: " response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Push cancelled."
exit 1
fi
fi
# ── Evaluate the actual refs being pushed from pre-push stdin ────────────────
while read -r local_ref local_sha remote_ref remote_sha; do
if [ -z "$local_ref" ] || [ -z "$local_sha" ]; then
continue
fi
# Skip deleted refs and non-branch pushes (for example, tags).
if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then
continue
fi
if [[ "$local_ref" != refs/heads/* ]]; then
continue
fi
# ── Get list of changed files for the ref being pushed (excluding patterns) ─
mapfile -t CHANGED_FILES < <(git diff --name-only "$BASE_BRANCH"..."$local_sha" 2>/dev/null | grep -vE "$GREP_PATTERN")
if [ "${#CHANGED_FILES[@]}" -eq 0 ]; then
continue
fi
# ── Count lines changed for the ref being pushed ────────────────────────────
TOTAL_LINES=$(git diff "$BASE_BRANCH"..."$local_sha" -- "${CHANGED_FILES[@]}" 2>/dev/null \
| grep -E "^[+-]" \
| grep -vE "^\+\+\+|^---" \
| wc -l \
| tr -d ' ')
# ── Warn if over limit ──────────────────────────────────────────────────────
if [ "$TOTAL_LINES" -gt "$MAX_LINES" ]; then
echo ""
echo "⚠️ WARNING: Push for ${local_ref#refs/heads/} contains ~${TOTAL_LINES} line changes (limit: ${MAX_LINES})."
echo " Consider splitting this into smaller PRs."
echo ""
echo " To push anyway: git push --no-verify"
echo " To cancel: Ctrl+C"
echo ""
read -r -p " Push anyway? [y/N]: " response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Push cancelled."
exit 1
fi
fi
done

Copilot uses AI. Check for mistakes.
Comment thread .githooks/pr-size-check.sh Outdated
"\.xcstrings$"
"\.ya?ml$"
"\.lock$"
"\.(png|jpg|jpeg|svg|pdf|icns|gif|tiff)$"
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

The common exclusion patterns here don’t match the updated reusable workflow’s exclusions (e.g., the workflow now excludes a broader set of image formats plus audio/video extensions, and uses slightly different tiff?/jpe?g patterns). This conflicts with the PR goal of mirroring the remote PR Size Check logic.

Impact: local pre-push results can disagree with CI, reducing trust in the early feedback.

Recommendation: update the COMMON_EXCLUDES list to stay in sync with .github/workflows/pr-size-check-reusable.yml (ideally keep a single shared source or add a sync check).

Suggested change
"\.(png|jpg|jpeg|svg|pdf|icns|gif|tiff)$"
"\.(png|apng|avif|bmp|gif|heic|heif|icns|ico|jpe?g|jp2|pdf|svg|tiff?|webp|aac|flac|m4a|mp3|ogg|wav|avi|m4v|mkv|mov|mp4|webm)$"

Copilot uses AI. Check for mistakes.
@swasti29 swasti29 force-pushed the copilot/add-local-pre-push-hook branch from 3b76195 to acefd3f Compare April 17, 2026 03:27
- Add extended image formats (bmp, webp, heic, heif, ico)
- Add audio/video exclusions (mp4, mov, mp3, wav, etc.)
- Add binary/submodule detection (warns on non-excluded binaries)
- Use git diff --numstat for accurate line counting
- Handle non-interactive shells gracefully

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 17, 2026 04:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment on lines +14 to +39
# ── Common exclusions (all repos) ────────────────────────────
# Kept in sync with .github/workflows/pr-size-check-reusable.yml
COMMON_EXCLUDES=(
"\.pbxproj$"
"\.xcscheme$"
"\.xcsettings$"
"\.xcconfig$"
"\.xctestplan$"
"\.xcworkspace/"
"\.xcodeproj/"
"\.plist$"
"\.entitlements$"
"\.storyboard$"
"\.xib$"
"\.xcassets/"
"\.modulemap$"
"\.xcprivacy$"
"\.strings$"
"\.stringsdict$"
"\.xcstrings$"
"\.ya?ml$"
"\.lock$"
"\.(png|jpe?g|gif|bmp|svg|webp|heic|heif|tiff?|ico|pdf|icns)$"
"\.(mp4|mov|m4v|avi|mpe?g|webm|mp3|wav|aiff?|m4a)$"
"\.md$"
"\.mdx$"
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

The comment says COMMON_EXCLUDES is “Kept in sync with .github/workflows/pr-size-check-reusable.yml”, but the patterns don’t currently match (e.g., the workflow excludes only a subset of image extensions and does not list .strings/.stringsdict/.xcstrings, while this hook does; the workflow’s media list differs as well).

Impact: Local pre-push warnings may disagree with CI PR Size Check results, creating confusion and reducing trust in the hook.

Recommendation: Update COMMON_EXCLUDES to exactly mirror the workflow’s COMMON_EXCLUDE list, or generate both from a single source of truth to prevent drift.

Copilot uses AI. Check for mistakes.
Comment on lines +99 to +106
if [ -t 1 ] && [ -r /dev/tty ]; then
read -r -p " Push anyway? [y/N]: " response < /dev/tty
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Push cancelled."
exit 1
fi
else
echo " Non-interactive shell detected; allowing push."
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

Interactive detection uses -t 1 (stdout) but the prompt reads from /dev/tty. In cases where stdout is redirected (but a controlling TTY exists), this will incorrectly treat the shell as non-interactive and allow the push without prompting.

Impact: The “confirm or cancel” behavior becomes unreliable, especially in scripted or wrapped git invocations that still have a TTY.

Recommendation: Gate prompting on the TTY you actually read from (e.g., check -r /dev/tty and/or -t 0 / -t 2, or test -t /dev/tty where supported) rather than -t 1.

Suggested change
if [ -t 1 ] && [ -r /dev/tty ]; then
read -r -p " Push anyway? [y/N]: " response < /dev/tty
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Push cancelled."
exit 1
fi
else
echo " Non-interactive shell detected; allowing push."
if [ -r /dev/tty ] && [ -t 0 ] < /dev/tty; then
read -r -p " Push anyway? [y/N]: " response < /dev/tty
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Push cancelled."
exit 1
fi
else
echo " No interactive terminal available; allowing push."

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +92
MERGE_BASE=$(git merge-base HEAD "$BASE_BRANCH" 2>/dev/null)
if [ -z "$MERGE_BASE" ]; then
echo "ℹ️ PR size check skipped: no common ancestor with ${BASE_BRANCH}."
exit 0
fi

# ── Count lines changed (excluding patterns & binaries) ──────
TOTAL_LINES=0
while IFS=$'\t' read -r added deleted filepath; do
[ -z "$filepath" ] && continue

# Check exclusion first
excluded=false
for pattern in "${ALL_EXCLUDES[@]}"; do
if [[ "$filepath" =~ $pattern ]]; then
excluded=true
break
fi
done
[ "$excluded" = true ] && continue

# Binary/submodule: git diff --numstat reports "-" for these
if [ "$added" = "-" ] || [ "$deleted" = "-" ]; then
echo "⚠️ Binary or submodule change in non-excluded file: $filepath"
continue
fi

TOTAL_LINES=$((TOTAL_LINES + added + deleted))
done < <(git diff --numstat "$MERGE_BASE"...HEAD 2>/dev/null)

# ── Warn if over limit ────────────────────────────────────────
if [ "$TOTAL_LINES" -gt "$MAX_LINES" ]; then
echo ""
echo "⚠️ WARNING: Your push contains ~${TOTAL_LINES} line changes (limit: ${MAX_LINES})."
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

This pre-push logic always computes changes for HEAD (git merge-base HEAD … and git diff …HEAD). However, pre-push can be invoked when pushing refs that are not the currently checked-out branch (or multiple refs), and Git provides the local/remote refs and SHAs on stdin.

Impact: The hook can under/over-report the size of what’s actually being pushed, which defeats the purpose of a pre-push guard.

Recommendation: Parse the pre-push stdin lines and run the diff calculation for each local_sha being pushed (or at least use the SHA of the current ref being pushed) instead of hard-coding HEAD.

Suggested change
MERGE_BASE=$(git merge-base HEAD "$BASE_BRANCH" 2>/dev/null)
if [ -z "$MERGE_BASE" ]; then
echo "ℹ️ PR size check skipped: no common ancestor with ${BASE_BRANCH}."
exit 0
fi
# ── Count lines changed (excluding patterns & binaries) ──────
TOTAL_LINES=0
while IFS=$'\t' read -r added deleted filepath; do
[ -z "$filepath" ] && continue
# Check exclusion first
excluded=false
for pattern in "${ALL_EXCLUDES[@]}"; do
if [[ "$filepath" =~ $pattern ]]; then
excluded=true
break
fi
done
[ "$excluded" = true ] && continue
# Binary/submodule: git diff --numstat reports "-" for these
if [ "$added" = "-" ] || [ "$deleted" = "-" ]; then
echo "⚠️ Binary or submodule change in non-excluded file: $filepath"
continue
fi
TOTAL_LINES=$((TOTAL_LINES + added + deleted))
done < <(git diff --numstat "$MERGE_BASE"...HEAD 2>/dev/null)
# ── Warn if over limit ────────────────────────────────────────
if [ "$TOTAL_LINES" -gt "$MAX_LINES" ]; then
echo ""
echo "⚠️ WARNING: Your push contains ~${TOTAL_LINES} line changes (limit: ${MAX_LINES})."
# ── Read refs being pushed from pre-push stdin ────────────────
PUSH_REFS=()
while IFS=' ' read -r local_ref local_sha remote_ref remote_sha; do
[ -z "$local_ref" ] && continue
PUSH_REFS+=("${local_ref}|${local_sha}|${remote_ref}|${remote_sha}")
done
if [ "${#PUSH_REFS[@]}" -eq 0 ]; then
PUSH_REFS+=("HEAD|$(git rev-parse HEAD 2>/dev/null)||")
fi
# ── Count lines changed (excluding patterns & binaries) per ref ──
TOTAL_LINES=0
MAX_PUSH_LINES=0
MAX_PUSH_REF=""
PROCESSED_REFS=0
for push_ref in "${PUSH_REFS[@]}"; do
IFS='|' read -r local_ref local_sha remote_ref remote_sha <<< "$push_ref"
# Deleted ref; nothing local to diff.
if [[ "$local_sha" =~ ^0+$ ]]; then
continue
fi
MERGE_BASE=$(git merge-base "$local_sha" "$BASE_BRANCH" 2>/dev/null)
if [ -z "$MERGE_BASE" ]; then
echo "ℹ️ PR size check skipped for ${local_ref}: no common ancestor with ${BASE_BRANCH}."
continue
fi
REF_TOTAL_LINES=0
while IFS=$'\t' read -r added deleted filepath; do
[ -z "$filepath" ] && continue
# Check exclusion first
excluded=false
for pattern in "${ALL_EXCLUDES[@]}"; do
if [[ "$filepath" =~ $pattern ]]; then
excluded=true
break
fi
done
[ "$excluded" = true ] && continue
# Binary/submodule: git diff --numstat reports "-" for these
if [ "$added" = "-" ] || [ "$deleted" = "-" ]; then
echo "⚠️ Binary or submodule change in non-excluded file for ${local_ref}: $filepath"
continue
fi
REF_TOTAL_LINES=$((REF_TOTAL_LINES + added + deleted))
done < <(git diff --numstat "$MERGE_BASE"...$local_sha 2>/dev/null)
PROCESSED_REFS=$((PROCESSED_REFS + 1))
if [ "$REF_TOTAL_LINES" -gt "$MAX_PUSH_LINES" ]; then
MAX_PUSH_LINES=$REF_TOTAL_LINES
MAX_PUSH_REF="$local_ref"
fi
done
if [ "$PROCESSED_REFS" -eq 0 ]; then
echo "ℹ️ PR size check skipped: no pushable local refs with a common ancestor to ${BASE_BRANCH}."
exit 0
fi
TOTAL_LINES=$MAX_PUSH_LINES
# ── Warn if over limit ────────────────────────────────────────
if [ "$TOTAL_LINES" -gt "$MAX_LINES" ]; then
echo ""
echo "⚠️ WARNING: Your push includes ${MAX_PUSH_REF} with ~${TOTAL_LINES} line changes (limit: ${MAX_LINES})."

Copilot uses AI. Check for mistakes.
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.

2 participants