Last active
February 3, 2026 20:22
-
-
Save dsmrt/19acafe54663e50286fdce87c92b0fd4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Note on examples: | |
| # - Uses null byte (%x00) as delimiter via git log --format=%B%x00 | |
| # - %B outputs the raw commit message body | |
| # - read -d $'\0' reads until null byte, naturally handling multi-line commits | |
| # - Works reliably with any commit message content (including special characters) | |
| # Examples: | |
| # Get change type for commits between v1.0.0 and HEAD | |
| # git log v1.0.0..HEAD --format=%B%x00 | ./determine-semver-from-conventional-commit.sh | |
| # Get change type for commits between two tags | |
| # git log v1.0.0..v2.0.0 --format=%B%x00 | ./determine-semver-from-conventional-commit.sh | |
| # Get change type for last 10 commits | |
| # git log -10 --format=%B%x00 | ./determine-semver-from-conventional-commit.sh | |
| # Function to determine change type for a single commit | |
| get_change_type() { | |
| local COMMIT_MSG="$1" | |
| local FIRST_LINE=$(echo "$COMMIT_MSG" | head -n 1) | |
| local CHANGE_TYPE="patch" | |
| # Check for breaking changes (highest priority) | |
| if [[ "$FIRST_LINE" =~ ^[a-z]+(\([^\)]+\))?\!\:(.*) ]]; then | |
| CHANGE_TYPE="major" | |
| elif echo "$COMMIT_MSG" | grep -qE "^(BREAKING CHANGE:|BREAKING-CHANGE:)"; then | |
| CHANGE_TYPE="major" | |
| elif [[ "$FIRST_LINE" =~ ^feat(\([^\)]+\))?\: ]]; then | |
| CHANGE_TYPE="minor" | |
| fi | |
| echo "$CHANGE_TYPE" | |
| } | |
| # If argument provided, process single commit | |
| if [ -n "$1" ]; then | |
| get_change_type "$1" | |
| exit 0 | |
| fi | |
| # Otherwise, read multiple commits from stdin using null byte delimiter | |
| HIGHEST="patch" | |
| while IFS= read -r -d $'\0' commit; do | |
| # Skip empty commits | |
| [ -z "$commit" ] && continue | |
| TYPE=$(get_change_type "$commit") | |
| # Update highest if needed (major > minor > patch) | |
| if [ "$TYPE" = "major" ]; then | |
| HIGHEST="major" | |
| break # Can't go higher than major | |
| elif [ "$TYPE" = "minor" ] && [ "$HIGHEST" = "patch" ]; then | |
| HIGHEST="minor" | |
| fi | |
| done | |
| echo "$HIGHEST" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment