diff --git a/.husky/commit-msg b/.husky/commit-msg index 5466d5eed..b7dc1d1fe 100755 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,6 +1,13 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" +# ANSI colors +RED="\033[0;31m" +YELLOW="\033[0;33m" +CYAN="\033[0;36m" +GREEN="\033[0;32m" +RESET="\033[0m" + commit_msg_file=$1 # Guard: ensure commit message file exists @@ -11,7 +18,7 @@ if [ -z "$commit_msg_file" ] || [ ! -f "$commit_msg_file" ]; then fi if ! grep -q "Signed-off-by:" "$commit_msg_file"; then - echo "Commit message missing Signed-off-by line" - echo "Use: git commit -s ..." + echo "${RED} Commit message missing Signed-off-by line ${RESET}" + echo "${GREEN} Use: git commit -s ... ${RESET}" exit 1 fi diff --git a/.husky/pre-push b/.husky/pre-push index ccf05aa56..09b12c019 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1,5 +1,6 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" +#!/bin/bash + +# . "$(dirname -- "$0")/_/husky.sh" # ANSI colors RED="\033[0;31m" @@ -10,16 +11,66 @@ RESET="\033[0m" echo "🔒 Checking commit signatures..." +# Read stdin into a temp file +TMP_FILE=$(mktemp) +cat > "$TMP_FILE" + +if [ ! -s "$TMP_FILE" ]; then + echo "⚠️ Validations won't apply when current branch and remote branch being pushed to are different." +fi + while read local_ref local_sha remote_ref remote_sha; do # Determine range of commits if [ "$remote_sha" = "0000000000000000000000000000000000000000" ]; then - range="$local_sha" + # Use the branch being pushed (may differ from HEAD) + if echo "$local_ref" | grep -q '^refs/heads/'; then + target_branch=${local_ref#refs/heads/} + else + target_branch=$(git rev-parse --abbrev-ref HEAD) + fi + + # Find closest local base branch by commit distance (exclude the target itself) + base_branch=$( + git for-each-ref --format='%(refname:short)' refs/heads/ \ + | grep -vxF "$target_branch" \ + | while IFS= read -r other_branch; do + merge_base=$(git merge-base "$target_branch" "$other_branch") || continue + [ -n "$merge_base" ] || continue + echo "$(git rev-list --count "${merge_base}..${target_branch}") $other_branch" + done \ + | sort -n \ + | head -n1 \ + | awk '{print $2}' + ) + + if [ -z "$base_branch" ]; then + # Resolve remote default (origin/HEAD) or use $default_branch/main + base_branch=${default_branch:-$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@')} + [ -n "$base_branch" ] || base_branch=main + echo "⚠️ Base branch not found — defaulting to '${base_branch}'" + fi + + # Prefer local base, else remote tracking + if git show-ref --verify --quiet "refs/heads/$base_branch"; then + base_ref="$base_branch" + else + base_ref="origin/$base_branch" + fi + + base_commit=$(git merge-base "$base_ref" "$target_branch" 2>/dev/null || true) + if [ -n "$base_commit" ]; then + range="$base_commit..$local_sha" + else + # Safe minimal fallback: just the tip commit + range="$local_sha" + fi else range="$remote_sha..$local_sha" fi unsigned_commits="" + echo "commit range ${range}" # Loop through each commit in range for commit in $(git rev-list $range); do # Skip merge commits @@ -86,6 +137,8 @@ while read local_ref local_sha remote_ref remote_sha; do exit 1 fi fi -done +done < "$TMP_FILE" + +rm -f "$TMP_FILE" -echo "${GREEN}✅ No unsigned commits found${RESET}" \ No newline at end of file +echo "${GREEN}✅ No unsigned commits found${RESET}"