@@ -0,0 +1,40 @@ +#!/usr/bin/env sh +# +# If you create/switch to a branch without a prefix (no '/'), +# automatically rename it to "feature/". +# +# Allowed prefixes (when '/' is present): +# fix/, feature/, release/, chore/ +# + +set -eu + +IS_BRANCH_CHECKOUT="${3:-0}" +if [ "$IS_BRANCH_CHECKOUT" != "1" ]; then + exit 0 +fi + +BRANCH="$(git symbolic-ref --quiet --short HEAD 2>/dev/null || true)" +if [ -z "$BRANCH" ]; then + exit 0 +fi + +case "$BRANCH" in + fix/*|feature/*|release/*|chore/*) + exit 0 + ;; +esac + +# No prefix -> default to feature/ +if ! printf "%s" "$BRANCH" | grep -q '/'; then + NEW_BRANCH="feature/$BRANCH" + if git show-ref --verify --quiet "refs/heads/$NEW_BRANCH"; then + exit 0 + fi + git branch -m "$BRANCH" "$NEW_BRANCH" 2>/dev/null || true + exit 0 +fi + +# Has a prefix but it's not allowed: cannot reliably fix here (checkout already happened). +exit 0 + @@ -0,0 +1,35 @@ +#!/usr/bin/env sh +# +# Enforce allowed branch prefixes: +# fix/, feature/, release/, chore/ +# +# If branch has no prefix (no '/'), automatically rename to feature/. +# + +set -eu + +BRANCH="$(git symbolic-ref --quiet --short HEAD 2>/dev/null || true)" +if [ -z "$BRANCH" ]; then + exit 0 +fi + +case "$BRANCH" in + fix/*|feature/*|release/*|chore/*) + exit 0 + ;; +esac + +# No slash => default to feature/ +if ! printf "%s" "$BRANCH" | grep -q '/'; then + NEW_BRANCH="feature/$BRANCH" + if ! git show-ref --verify --quiet "refs/heads/$NEW_BRANCH"; then + git branch -m "$BRANCH" "$NEW_BRANCH" + fi + exit 0 +fi + +echo >&2 "Ошибка: недопустимый префикс ветки '$BRANCH'." +echo >&2 "Разрешены только: fix/, feature/, release/, chore/." +echo >&2 "Либо используйте ветку без префикса — она будет автоматически переименована в feature/<имя>." +exit 1 + @@ -0,0 +1,65 @@ +#!/usr/bin/env sh +# +# Auto-prefix commit messages based on branch name: +# fix/..., feature/..., release/..., chore/... +# -> "refs # " +# + +set -eu + +COMMIT_MSG_FILE="${1:-}" +COMMIT_SOURCE="${2:-}" + +if [ -z "$COMMIT_MSG_FILE" ] || [ ! -f "$COMMIT_MSG_FILE" ]; then + exit 0 +fi + +# Skip for merges/squashes/amends/templates (avoid fighting Git-generated messages). +case "$COMMIT_SOURCE" in + merge|squash|commit|template) + exit 0 + ;; +esac + +BRANCH="$(git symbolic-ref --quiet --short HEAD 2>/dev/null || true)" +TASK_NUMBER="" +if printf "%s" "$BRANCH" | grep -Eq '^(fix|feature|release|chore)/[0-9]+'; then + TASK_NUMBER="$(printf "%s" "$BRANCH" | sed -E 's#^(fix|feature|release|chore)/([0-9]+).*#\2#')" +else + exit 0 +fi + +FIRST_LINE="$(LC_ALL=C sed -n '1p' "$COMMIT_MSG_FILE" || true)" + +# Do not touch special commit subjects. +case "$FIRST_LINE" in + "Merge "*|"fixup! "*|"squash! "*|"revert! "*) + exit 0 + ;; +esac + +PREFIX="refs #${TASK_NUMBER} " + +# Already has the right prefix (or already references the number at start) -> no-op. +case "$FIRST_LINE" in + "$PREFIX"*|"refs #${TASK_NUMBER} "*) + exit 0 + ;; +esac + +# If message already starts with some refs prefix, don't double-prefix. +case "$FIRST_LINE" in + "refs #"*|"refs: #"* ) + exit 0 + ;; +esac + +TMP_FILE="${COMMIT_MSG_FILE}.tmp.$$" +{ + printf "%s%s\n" "$PREFIX" "$FIRST_LINE" + LC_ALL=C sed -n '2,$p' "$COMMIT_MSG_FILE" +} > "$TMP_FILE" + +mv "$TMP_FILE" "$COMMIT_MSG_FILE" +exit 0 +