Files
dots/home/shells/zsh/scripts/git-changes.sh
2025-12-05 01:19:05 +01:00

124 lines
3.1 KiB
Bash

#!/usr/bin/env bash
TARGET_BRANCH=${2:-$(git rev-parse --abbrev-ref HEAD)}
if [ -n "$1" ]; then
BASE_BRANCH="$1"
else
if [ "$TARGET_BRANCH" != "dev" ] && git show-ref --verify --quiet refs/heads/dev; then
BASE_BRANCH="dev"
elif git show-ref --verify --quiet refs/heads/main; then
BASE_BRANCH="main"
elif git show-ref --verify --quiet refs/heads/master; then
BASE_BRANCH="master"
else
echo "Warning: Neither 'dev', 'main' nor 'master' found. Defaulting to 'main'." >&2
BASE_BRANCH="main"
fi
fi
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "Error: Not a git repository." >&2
exit 1
fi
if ! git show-ref --verify --quiet refs/heads/"$BASE_BRANCH"; then
echo "Error: Base branch '$BASE_BRANCH' does not exist." >&2
fi
REMOTE_URL=$(git config --get remote.origin.url)
REPO_URL=""
if [[ "$REMOTE_URL" == git@* ]]; then
REPO_URL=$(echo "$REMOTE_URL" | sed -E 's/git@([^:]+):/https:\/\/\1\//')
fi
REPO_URL=${REPO_URL%.git}
get_commit_link() {
local hash=$1
if [ -n "$REPO_URL" ]; then
echo "($REPO_URL/commit/$hash)"
else
echo "($hash)"
fi
}
feats=""
fixes=""
refactors=""
perfs=""
styles=""
tests=""
builds=""
ops=""
docs=""
chores=""
merges=""
others=""
while IFS="|" read -r hash subject; do
link=$(get_commit_link "$hash")
if [[ "$subject" =~ ^([a-z]+)(\([a-z0-9\ -]+\))?!?:[[:space:]]*(.*)$ ]]; then
type="${BASH_REMATCH[1]}"
clean_msg="${BASH_REMATCH[3]}"
line=" - [\`${hash:0:7}\`]${link}: ${clean_msg}"
case "$type" in
feat) feats="${feats}\n${line}" ;;
fix) fixes="${fixes}\n${line}" ;;
refactor) refactors="${refactors}\n${line}" ;;
perf) perfs="${perfs}\n${line}" ;;
style) styles="${styles}\n${line}" ;;
test) tests="${tests}\n${line}" ;;
build) builds="${builds}\n${line}" ;;
ops) ops="${ops}\n${line}" ;;
docs) docs="${docs}\n${line}" ;;
chore) chores="${chores}\n${line}" ;;
merge) merges="${merges}\n${line}" ;;
*) others="${others}\n${line} (Type: $type)" ;;
esac
else
line=" - [\`${hash:0:7}\`]${link}: ${subject}"
others="${others}\n${line}"
fi
done < <(git log --no-merges --pretty=tformat:"%H|%s" "$BASE_BRANCH..$TARGET_BRANCH")
if [ -n "$feats" ]; then
echo -e "\n- **New Features:**$feats"
fi
if [ -n "$fixes" ]; then
echo -e "\n- **Bug Fixes:**$fixes"
fi
if [ -n "$refactors" ]; then
echo -e "\n- **Code Refactoring:**$refactors"
fi
if [ -n "$perfs" ]; then
echo -e "\n- **Performance Improvements:**$perfs"
fi
if [ -n "$styles" ]; then
echo -e "\n- **Code Style:**$styles"
fi
if [ -n "$tests" ]; then
echo -e "\n- **Tests:**$tests"
fi
if [ -n "$builds" ]; then
echo -e "\n- **Build System/Dependencies:**$builds"
fi
if [ -n "$ops" ]; then
echo -e "\n- **Operations/Infrastructure:**$ops"
fi
if [ -n "$docs" ]; then
echo -e "\n- **Documentation:**$docs"
fi
if [ -n "$chores" ]; then
echo -e "\n- **Chores/Maintenance:**$chores"
fi
if [ -n "$merges" ]; then
echo -e "\n- **Merges:**$merges"
fi
if [ -n "$others" ]; then
echo -e "\n- **Other Commits:**$others"
fi
echo -e "\n> Automatically generated by [git-changes](https://github.com/demenik/dots/tree/main/home/shells/zsh/scripts/git-changes.sh)"