Add pre-receive.sh
This commit is contained in:
122
pre-receive.sh
Normal file
122
pre-receive.sh
Normal file
@ -0,0 +1,122 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Semantic commit pattern
|
||||
PATTERN='^(feat|fix|docs|style|refactor|test|perf|build|ci|chore|revert)(\([a-zA-Z0-9\._-]+\))?: .{1,}$'
|
||||
|
||||
# Pattern for merge commits from pull requests
|
||||
PR_MERGE_PATTERN='^Merge pull request'
|
||||
|
||||
# Pattern for standard Git merge commits
|
||||
GIT_MERGE_PATTERN='^Merge (branch|remote-tracking branch) .+ into .+$'
|
||||
|
||||
# Set text colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
BLUE='\033[0;34m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Statistics tracking
|
||||
INVALID_COMMITS=0
|
||||
VALID_COMMITS=0
|
||||
MERGE_COMMITS=0
|
||||
TOTAL_COMMITS=0
|
||||
|
||||
# Draw box for statistics
|
||||
draw_box() {
|
||||
local title="$1"
|
||||
local width=60
|
||||
local padding=$(((width - ${#title}) / 2))
|
||||
|
||||
echo -e "${BOLD}┌$(printf '─%.0s' $(seq 1 $width))┐${NC}"
|
||||
echo -e "${BOLD}│$(printf ' %.0s' $(seq 1 $padding))$title$(printf ' %.0s' $(seq 1 $((width - padding - ${#title}))))│${NC}"
|
||||
echo -e "${BOLD}└$(printf '─%.0s' $(seq 1 $width))┘${NC}"
|
||||
}
|
||||
|
||||
# Read stdin (format: <old-value> <new-value> <ref-name>)
|
||||
while read -r OLD_REV NEW_REV REF_NAME; do
|
||||
# Skip if it's a branch deletion
|
||||
if [[ "$NEW_REV" = "0000000000000000000000000000000000000000" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Handle new branch pushes differently
|
||||
if [[ "$OLD_REV" = "0000000000000000000000000000000000000000" ]]; then
|
||||
continue
|
||||
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")
|
||||
|
||||
# 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))
|
||||
COMMIT_MSG=$(git log --format=%B -n 1 "$COMMIT")
|
||||
COMMIT_SUBJECT=$(echo "$COMMIT_MSG" | head -n 1)
|
||||
PARENT_COUNT=$(git rev-list --parents -n 1 "$COMMIT" | awk '{print NF - 1}')
|
||||
|
||||
# Process merge commits or regular commits
|
||||
if [[ $PARENT_COUNT -gt 1 ]] && (echo "$COMMIT_SUBJECT" | grep -E "$PR_MERGE_PATTERN" >/dev/null || echo "$COMMIT_SUBJECT" | grep -E "$GIT_MERGE_PATTERN" >/dev/null); then
|
||||
MERGE_COMMITS=$((MERGE_COMMITS + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Validate commit message silently
|
||||
if ! [[ "$COMMIT_SUBJECT" =~ $PATTERN ]]; then
|
||||
INVALID_COMMITS=$((INVALID_COMMITS + 1))
|
||||
else
|
||||
VALID_COMMITS=$((VALID_COMMITS + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
# 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 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"
|
||||
echo ""
|
||||
|
||||
if [ $TOTAL_COMMITS -gt 0 ]; then
|
||||
VALID_PERCENT=$(((VALID_COMMITS + MERGE_COMMITS) * 100 / TOTAL_COMMITS))
|
||||
echo -e "${BOLD}Semantic compliance:${NC} $VALID_PERCENT%"
|
||||
|
||||
# Print bar
|
||||
printf "["
|
||||
for ((i = 0; i < VALID_PERCENT / 5; i++)); do
|
||||
printf "${GREEN}#${NC}"
|
||||
done
|
||||
for ((i = VALID_PERCENT / 5; i < 20; i++)); do
|
||||
printf "${RED}.${NC}"
|
||||
done
|
||||
printf "] $VALID_PERCENT%%\n"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
# If any commits were invalid, reject the push
|
||||
if [[ $INVALID_COMMITS -gt 0 ]]; then
|
||||
echo -e "${RED}Push rejected: $INVALID_COMMITS commit(s) have invalid messages.${NC}"
|
||||
echo -e "${YELLOW}Please rewrite your commit messages to follow the semantic commit format:${NC}"
|
||||
echo "type(scope): message"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
Reference in New Issue
Block a user