From 411b4dec84a13c229dd3a67d20b697d8a22775a3 Mon Sep 17 00:00:00 2001 From: Jan Klattenhoff Date: Mon, 7 Apr 2025 19:22:16 +0200 Subject: [PATCH] feat(pre-receive): enhance new branch validation logic --- hooks/pre-recieve.sh | 48 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/hooks/pre-recieve.sh b/hooks/pre-recieve.sh index bb6f5bc..a976504 100644 --- a/hooks/pre-recieve.sh +++ b/hooks/pre-recieve.sh @@ -41,11 +41,44 @@ while read -r OLD_REV NEW_REV REF_NAME; do continue fi - # Skip if it's a new branch (no old revision) + # Handle new branch pushes differently if [[ "$OLD_REV" = "0000000000000000000000000000000000000000" ]]; then - OLD_REV=$(git rev-list --max-parents=0 "$NEW_REV") + echo -e "${YELLOW}New branch detected: $REF_NAME${NC}" + + # Find the common ancestor with other branches + # This helps us identify only the new commits unique to this branch + COMMON_ANCESTOR="" + + # Get list of all other refs excluding the current one and tags + OTHER_REFS=$(git for-each-ref --format='%(refname)' refs/heads/ | grep -v "$REF_NAME") + + if [ -n "$OTHER_REFS" ]; then + # Find the merge-base with each existing branch and use the most recent one + for REF in $OTHER_REFS; do + BASE=$(git merge-base "$NEW_REV" "$REF" 2>/dev/null || echo "") + if [ -n "$BASE" ]; then + if [ -z "$COMMON_ANCESTOR" ] || [ "$(git rev-list -n 1 --date-order "$BASE" "$COMMON_ANCESTOR" | wc -l)" -eq 1 ]; then + COMMON_ANCESTOR="$BASE" + fi + fi + done + fi + + if [ -n "$COMMON_ANCESTOR" ]; then + echo -e "${BLUE}Only validating commits unique to this branch${NC}" + OLD_REV="$COMMON_ANCESTOR" + else + # Brand new branch with no common ancestor - validate only the last 10 commits + echo -e "${BLUE}New branch with no common history - validating only the latest 10 commits${NC}" + COMMIT_COUNT=$(git rev-list --count "$NEW_REV") + if [ "$COMMIT_COUNT" -gt 10 ]; then + OLD_REV=$(git rev-list -n 1 "$NEW_REV"~10) + fi + fi fi + echo -e "${YELLOW}Checking commits in $REF_NAME${NC}" + # Get branch stats from git (quietly) BRANCH_COMMITS=$(git rev-list --count "$REF_NAME" 2>/dev/null || echo "?") BRANCH_AGE=$(git log -1 --format="%cr" "$REF_NAME" 2>/dev/null || echo "unknown time ago") @@ -53,6 +86,15 @@ while read -r OLD_REV NEW_REV REF_NAME; do # Get all commit hashes between old and new revision COMMITS=$(git rev-list "$OLD_REV".."$NEW_REV") + # Count how many commits we're validating + COMMITS_TO_CHECK=$(echo "$COMMITS" | wc -l) + if [ "$COMMITS_TO_CHECK" -eq 0 ]; then + echo -e "${GREEN}No new commits to validate${NC}" + continue + else + echo -e "${BLUE}Validating $COMMITS_TO_CHECK commit(s)${NC}" + fi + # Process each commit message silently for COMMIT in $COMMITS; do TOTAL_COMMITS=$((TOTAL_COMMITS + 1)) @@ -77,7 +119,7 @@ while read -r OLD_REV NEW_REV REF_NAME; do # Display only the commit statistics box draw_box "COMMIT STATISTICS" echo -e "${BOLD}Branch information:${NC} $BRANCH_COMMITS total commits (created $BRANCH_AGE)" - echo -e "${BOLD}Commits in this push:${NC} $TOTAL_COMMITS" + echo -e "${BOLD}Commits validated:${NC} $TOTAL_COMMITS" echo -e "${GREEN}Valid semantic commits: ${NC} $VALID_COMMITS" echo -e "${BLUE}Merge commits: ${NC} $MERGE_COMMITS" echo -e "${RED}Invalid commits: ${NC} $INVALID_COMMITS"