Skip to content

Conversation

@sujitaw
Copy link
Contributor

@sujitaw sujitaw commented Oct 16, 2025

What

  • modified pre-push script to only check commits related to local branch when pushing a local branch to remote for first time .

Summary by CodeRabbit

  • Bug Fixes

    • Warns when a commit message file is missing and exits gracefully
    • Better handling for initial push with improved base-branch detection and safe fallbacks
  • Improvements

    • Commit validation messages are colorized for clearer visibility
    • Validates push input and reports the computed commit range before checks
    • Robust temporary-input handling to avoid spurious failures

@sujitaw sujitaw requested a review from GHkrishna October 16, 2025 06:35
@sujitaw sujitaw self-assigned this Oct 16, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 16, 2025

Walkthrough

The PR updates two Husky hook scripts: .husky/commit-msg adds ANSI color variables, a guard for missing commit message files, and colorized DCO failure output; .husky/pre-push rewrites initial-push handling to compute an appropriate base branch and commit range, emits diagnostics, and preserves unsigned-commit checks.

Changes

Cohort / File(s) Summary
Commit message validation
/.husky/commit-msg
Adds ANSI color variables; prints a warning and exits 0 when commit message file is missing; colorizes Signed-off-by/DCO failure message (red error + green suggested command); preserves failure exit code (1) on check fail.
Push validation and base branch detection
/.husky/pre-push
Switches to bash, reads stdin into a temp file, validates input; for initial pushes (remote_sha = all zeros) computes target branch and searches local branches for closest merge-base to derive a base_commit; sets commit range to base_commit..local_sha (falls back to local_sha), echoes commit range ${range}, and continues unsigned-commit checks using the computed range; preserves non-initial-push behavior.

Sequence Diagram(s)

sequenceDiagram
    participant User as Git User
    participant PrePush as .husky/pre-push
    participant Git as Git
    participant Validator as Unsigned-commit Check

    User->>PrePush: git push
    activate PrePush

    PrePush->>Git: read stdin -> tmp file
    PrePush->>PrePush: parse local_sha, remote_sha, local_ref

    alt initial push (remote_sha = 0000...)
        rect rgb(235,245,255)
        PrePush->>PrePush: determine target_branch (from local_ref or HEAD)
        PrePush->>Git: list local branches
        Git-->>PrePush: branches
        PrePush->>PrePush: compute merge-base distances
        PrePush->>PrePush: pick closest base_branch or fallback (default_branch/origin/HEAD/main)
        PrePush->>Git: compute base_commit (merge-base)
        PrePush->>PrePush: set range = base_commit..local_sha (or local_sha fallback)
        PrePush->>User: echo "commit range ${range}"
        end
    else non-initial push
        PrePush->>PrePush: set range = remote_sha..local_sha (unchanged)
    end

    PrePush->>Validator: run unsigned-commit checks on range
    Validator-->>PrePush: results
    PrePush-->>User: allow or reject push
    deactivate PrePush
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Potential attention points:

  • .husky/pre-push: correctness of branch detection, merge-base/distance computation, and fallback ordering.
  • Safe handling of temporary file and stdin redirection to avoid edge-case hangs.
  • .husky/commit-msg: behavior when commit message file path is missing vs. present; color escape correctness across shells.

Possibly related PRs

Suggested reviewers

  • shitrerohit

Poem

🐰
I hopped through hooks to paint messages bright,
Red for the missing, green for the right,
I sniffed for base branches near and far,
Echoed the range — a guiding star.
Push on, dear devs, with carrot-coded light! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: fixing commit range limitation for git hooks when pushing local branches.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/limit_local_branch_commit_range_for_git_hooks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@GHkrishna
Copy link
Contributor

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Oct 16, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sujitaw sujitaw changed the title fix/limit local branch commit range fro git hooks fix/limit local branch commit range for git hooks Oct 16, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
.husky/commit-msg (2)

4-10: Make color variables portable in POSIX sh

"\033[..." won’t produce colors via echo in POSIX sh. Define colors using printf so variables contain the actual ESC char.

-# ANSI colors
-RED="\033[0;31m"
-YELLOW="\033[0;33m"
-CYAN="\033[0;36m"
-GREEN="\033[0;32m"
-RESET="\033[0m"
+# ANSI colors (portable)
+RED=$(printf '\033[0;31m')
+YELLOW=$(printf '\033[0;33m')
+CYAN=$(printf '\033[0;36m')
+GREEN=$(printf '\033[0;32m')
+RESET=$(printf '\033[0m')

21-22: Use printf for colored output; minor DCO check nit

Ensure color escapes render by using printf %b. Also consider anchoring the DCO check to the start of the line to avoid false positives like “Re-signed-off-by”.

-  echo "${RED} Commit message missing Signed-off-by line ${RESET}"
-  echo "${GREEN} Use: git commit -s ... ${RESET}"
+  printf "%b\n" "${RED}Commit message missing Signed-off-by line${RESET}"
+  printf "%b\n" "${GREEN}Use: git commit -s ...${RESET}"

Optional (outside this hunk):

  • Replace grep -q "Signed-off-by:" with grep -qi '^Signed-off-by:' for stricter matching.
.husky/pre-push (1)

39-39: Gate debug output behind a flag

Reduce noise on normal pushes; print range only when debugging.

-  echo "commit range ${range}"
+  [ -n "$HUSKY_DEBUG" ] && echo "commit range $range"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c712ea6 and 003c4cf.

📒 Files selected for processing (2)
  • .husky/commit-msg (2 hunks)
  • .husky/pre-push (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: GHkrishna
PR: credebl/platform#1469
File: .husky/pre-push:34-35
Timestamp: 2025-09-30T06:35:15.488Z
Learning: In the credebl/platform repository's pre-push hook (.husky/pre-push), when checking commit signatures, user GHkrishna encountered an edge case where pulling squashed commits from other contributors causes signature validation issues because those commits are signed with others' GPG keys. The user prefers a solution that distinguishes local commits from upstream commits to apply signature validation only to the current user's own commits.
🔇 Additional comments (1)
.husky/pre-push (1)

108-108: LGTM

Helpful success message; no issues.

@GHkrishna GHkrishna changed the title fix/limit local branch commit range for git hooks fix: limit local branch commit range for git hooks Oct 16, 2025
@GHkrishna GHkrishna added the bug Something isn't working label Oct 16, 2025
Signed-off-by: sujitaw <[email protected]>
@sonarqubecloud
Copy link

sonarqubecloud bot commented Nov 5, 2025

@sujitaw
Copy link
Contributor Author

sujitaw commented Nov 5, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 5, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
.husky/pre-push (1)

73-73: Consider making diagnostic output optional or removing before production.

The commit range echo is helpful for debugging but may be noisy for regular use. Since this PR is in draft status, this might be intentional for testing.

Consider one of these options before merging:

  1. Remove the line entirely
  2. Make it conditional:
-	echo "commit range ${range}"
+	[ -n "$DEBUG" ] && echo "commit range ${range}"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 003c4cf and 514ff4a.

📒 Files selected for processing (1)
  • .husky/pre-push (3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: GHkrishna
Repo: credebl/platform PR: 1469
File: .husky/pre-push:34-35
Timestamp: 2025-09-30T06:35:15.488Z
Learning: In the credebl/platform repository's pre-push hook (.husky/pre-push), when checking commit signatures, user GHkrishna encountered an edge case where pulling squashed commits from other contributors causes signature validation issues because those commits are signed with others' GPG keys. The user prefers a solution that distinguishes local commits from upstream commits to apply signature validation only to the current user's own commits.
Learnt from: GHkrishna
Repo: credebl/platform PR: 1468
File: .husky/pre-push:47-56
Timestamp: 2025-09-29T12:14:52.484Z
Learning: User GHkrishna prefers allowing automatic rebase in pre-push hooks for signing commits, considering it acceptable since they're rebasing their own local commits before sharing.
📚 Learning: 2025-09-30T06:35:15.488Z
Learnt from: GHkrishna
Repo: credebl/platform PR: 1469
File: .husky/pre-push:34-35
Timestamp: 2025-09-30T06:35:15.488Z
Learning: In the credebl/platform repository's pre-push hook (.husky/pre-push), when checking commit signatures, user GHkrishna encountered an edge case where pulling squashed commits from other contributors causes signature validation issues because those commits are signed with others' GPG keys. The user prefers a solution that distinguishes local commits from upstream commits to apply signature validation only to the current user's own commits.

Applied to files:

  • .husky/pre-push
📚 Learning: 2025-09-29T12:14:52.484Z
Learnt from: GHkrishna
Repo: credebl/platform PR: 1468
File: .husky/pre-push:47-56
Timestamp: 2025-09-29T12:14:52.484Z
Learning: User GHkrishna prefers allowing automatic rebase in pre-push hooks for signing commits, considering it acceptable since they're rebasing their own local commits before sharing.

Applied to files:

  • .husky/pre-push
🔇 Additional comments (3)
.husky/pre-push (3)

1-3: Verify whether commenting out husky.sh sourcing is intentional.

The husky.sh sourcing is commented out, which may affect environment setup or path configuration. If this is for testing purposes, it should be uncommented before merging to production.


25-66: Excellent implementation of the commit range logic!

The initial push range computation has been significantly improved and properly addresses the previous review feedback. The code now:

  • ✅ Uses the ref being pushed rather than HEAD to handle cases where the pushed branch differs from the current checkout
  • ✅ Correctly excludes the target branch with grep -vxF for exact matching
  • ✅ Guards git merge-base operations with || continue and empty checks to prevent failures
  • ✅ Implements a robust multi-level fallback strategy (origin/HEAD → default_branch → main)
  • ✅ Provides a safe minimal fallback (just local_sha) when no common history exists

This implementation properly distinguishes local commits from upstream commits, addressing the learnings about signature validation edge cases.

Based on learnings


140-142: LGTM!

Proper handling of the temporary file with correct input redirection and cleanup. The use of rm -f ensures the script won't fail even if the file doesn't exist.

Comment on lines +18 to +20
if [ ! -s "$TMP_FILE" ]; then
echo "⚠️ Validations won't apply when current branch and remote branch being pushed to are different."
fi
Copy link

@coderabbitai coderabbitai bot Nov 5, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clarify the warning message to accurately reflect the condition.

The warning message states "Validations won't apply when current branch and remote branch being pushed to are different," but it's triggered when stdin is empty, which can occur in various scenarios beyond just differing branches (e.g., nothing to push, certain git operations).

Consider revising to:

-  echo "⚠️ Validations won't apply when current branch and remote branch being pushed to are different."
+  echo "⚠️ No refs to push - skipping commit signature validation."
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [ ! -s "$TMP_FILE" ]; then
echo "⚠️ Validations won't apply when current branch and remote branch being pushed to are different."
fi
if [ ! -s "$TMP_FILE" ]; then
echo "⚠️ No refs to push - skipping commit signature validation."
fi
🤖 Prompt for AI Agents
In .husky/pre-push around lines 18 to 20, the warning text incorrectly ties the
condition to differing branches while the check actually detects an empty stdin
(no ref info), which can happen for reasons like nothing to push or certain git
operations; update the message to accurately state that no ref info was received
(stdin is empty) and therefore pre-push validations may be skipped, and
optionally include brief examples (e.g., nothing to push, special git workflows)
to make the warning clear.

Copy link
Contributor Author

@sujitaw sujitaw Nov 5, 2025

Choose a reason for hiding this comment

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

@coderabbitai when pushing to other remote branches for eg : my current local branch is develop and i perform git push origin main in that scenario too the refs are empty .
is there any other way to address this scenario

Copy link

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Research git pre-push hook documentation and behavior
# Check if there are any environment variables or other ways to detect the scenario

# First, let's check what information is typically available in a pre-push hook
echo "=== Git pre-push hook documentation ==="
git help hooks 2>/dev/null | grep -A 30 "pre-push" | head -40

echo ""
echo "=== Checking git environment variables that might help ==="
# List common git environment variables that might be available
cat << 'EOF'
Common Git environment variables that might be available in pre-push hook:
- GIT_DIR
- GIT_WORK_TREE
- GIT_INDEX_FILE
- GIT_PREFIX
- GIT_REFLOG_ACTION
- GIT_PUSH_OPTION_COUNT
- GIT_PUSH_OPTION_<n>

Note: The pre-push hook receives information via stdin, not command-line arguments.
EOF

echo ""
echo "=== Understanding when stdin is empty ==="
cat << 'EOF'
The pre-push hook receives on stdin (one line per ref being pushed):
<local ref> <local sha1> <remote ref> <remote sha1>

stdin is empty when:
1. Nothing to push (local ref is already up-to-date with remote)
2. Specified ref doesn't exist locally
3. Push is a dry-run or gets rejected before refs are determined

For 'git push origin main' from 'develop' branch:
- If local 'main' exists and differs from 'origin/main': stdin will have data
- If local 'main' doesn't exist: error before hook runs
- If local 'main' is up-to-date with 'origin/main': stdin will be empty (nothing to push)
EOF

Length of output: 1030


🌐 Web query:

git pre-push hook empty stdin scenarios

💡 Result:

Short answer — pre-push hook stdin will be empty when there are no refs/objects being sent, or when something else has already consumed/failed to forward that input.

Common scenarios

  • Nothing to push (git finds no changed refs) — git will not write any lines to the hook’s stdin. [1]
  • Your hook/script (or a helper it calls, e.g. git-lfs) reads stdin before your read-loop, so subsequent reads see EOF. Move the read-loop before anything that consumes stdin. [2]
  • A wrapper/tool running the hook (some hook managers) doesn’t forward git’s stdin into the actual hook process, so the hook sees empty stdin. Check the wrapper’s implementation/config. [3]

What to do

  • Write your hook to handle empty stdin gracefully (e.g., use while read ...; do …; done and treat zero iterations as “nothing to check”). [1]
  • Ensure no commands run before the read-loop that might consume stdin. [2]
  • If using a hook manager/wrapper, verify it forwards stdin or run the hook directly. [3]

Sources
[1] Stack Overflow: “Git-hooks pre-push script does not receive input via STDIN”.
[2] Stack Overflow: “git pre-push hook stdin is empty” (notes about git-lfs and ordering).
[3] GitHub issue / wrapper discussion (lefthook) and Git hooks docs about pre-push input handling.


@sujitaw, great question! Let me explain what's happening in your scenario.

Why stdin is empty

When you run git push origin main from your develop branch:

  • Git compares your local main branch with origin/main
  • If they're identical (nothing new to push), Git doesn't send any ref information to the pre-push hook
  • This results in empty stdin

The pre-push hook only receives stdin with ref information when there are actual commits/refs to push. It doesn't receive the command-line arguments (like which branch you specified), so it can't distinguish between:

  • "Nothing to push because refs are up-to-date"
  • "Pushing a different branch than current HEAD"
  • Other scenarios that result in empty stdin

Current behavior is correct

The current code handles this appropriately:

  1. Detects empty stdin
  2. Shows a warning
  3. Continues without blocking (which is correct - you shouldn't block a no-op push)
  4. Skips validation since there are no commits to validate

Suggested improvement

The only thing we can improve is making the warning message more accurate and informative:

if [ ! -s "$TMP_FILE" ]; then
  echo "⚠️  No refs to push - skipping commit signature validation."
  echo "    (This occurs when local and remote refs are already in sync)"
fi

This message is more accurate because:

  • It correctly states why validation is skipped (no refs to push)
  • It doesn't make assumptions about branch differences
  • It provides context about what "no refs" means

Bottom line: There's no programmatic way in the pre-push hook to detect your specific scenario differently from other empty-stdin cases, but that's okay—the hook should skip validation when there's nothing to push, regardless of the reason. The improved warning message makes this clearer to users.


🧠 Learnings used
Learnt from: GHkrishna
Repo: credebl/platform PR: 1469
File: .husky/pre-push:34-35
Timestamp: 2025-09-30T06:35:15.488Z
Learning: In the credebl/platform repository's pre-push hook (.husky/pre-push), when checking commit signatures, user GHkrishna encountered an edge case where pulling squashed commits from other contributors causes signature validation issues because those commits are signed with others' GPG keys. The user prefers a solution that distinguishes local commits from upstream commits to apply signature validation only to the current user's own commits.

Learnt from: GHkrishna
Repo: credebl/platform PR: 1468
File: .husky/pre-push:47-56
Timestamp: 2025-09-29T12:14:52.484Z
Learning: User GHkrishna prefers allowing automatic rebase in pre-push hooks for signing commits, considering it acceptable since they're rebasing their own local commits before sharing.

@GHkrishna
Copy link
Contributor

@sujitaw, since this PR is in sync with credebl/studio#1257

I think we can merge this PR too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants