Skip to content

Instantly share code, notes, and snippets.

@stefanocudini
Last active July 2, 2026 13:45
Show Gist options
  • Select an option

  • Save stefanocudini/d9486f1db7cbba01112346de3f2d6017 to your computer and use it in GitHub Desktop.

Select an option

Save stefanocudini/d9486f1db7cbba01112346de3f2d6017 to your computer and use it in GitHub Desktop.
given a GitHub issue number prints "fix-<number>-<title-slug>"
#!/usr/bin/env bash
#
# git-slug — given a GitHub issue URL, prints "fix-<number>-<title-slug>"
#
# Usage: ./git-slug [-q] <github-issue-url | issue-number>
# -q quiet: print only the slug, without the git command
# if the parameter is just a number, the default base URL (MapStore2) is used
#
# Usage with pipe, create new branch immediatly
# git-slug 1123 | sh
#
set -euo pipefail
DEFAULT_BASE_URL="https://github.com/geosolutions-it/MapStore2/issues/"
usage() {
echo "Uso: $(basename "$0") [-q] <url-issue-github | numero-issue>" >&2
echo "Es.: $(basename "$0") https://github.com/owner/repo/issues/123" >&2
echo " $(basename "$0") 123 # usa ${DEFAULT_BASE_URL}123" >&2
echo " -q stampa solo lo slug, senza il comando git" >&2
exit 1
}
command -v curl >/dev/null || { echo "Errore: curl non trovato" >&2; exit 1; }
quiet=0
if [ "${1:-}" = "-q" ] || [ "${1:-}" = "--quiet" ]; then
quiet=1
shift
fi
[ $# -eq 1 ] || usage
url="$1"
# Number only → issue of the default repo
if [[ "$url" =~ ^[0-9]+$ ]]; then
url="${DEFAULT_BASE_URL}${url}"
fi
if [[ "$url" =~ ^https?://github\.com/[^/]+/[^/]+/issues/([0-9]+) ]]; then
num="${BASH_REMATCH[1]}"
else
echo "Errore: URL issue GitHub non valido: $url" >&2
usage
fi
html=$(curl -fsSL "$url") \
|| { echo "Errore: impossibile scaricare la pagina della issue" >&2; exit 1; }
# Prefer og:title (always populated) over <title>, which is sometimes generic ("Issue · GitHub")
html_title=$(printf '%s' "$html" | grep -oP '<meta[^>]*property="og:title"[^>]*content="\K[^"]*' | head -1)
[ -n "$html_title" ] || html_title=$(printf '%s' "$html" | grep -oP '(?<=<title>).*?(?=</title>)' | head -1)
[ -n "$html_title" ] || { echo "Errore: titolo non trovato nella pagina" >&2; exit 1; }
# The title has format: "TITLE · Issue #123 · owner/repo[ · GitHub]" → strip the suffix
title=$(printf '%s' "$html_title" | sed -E 's/ · [A-Za-z ]+ #[0-9]+ · .*$//')
# Slugification: HTML entities dropped, accents → ASCII, lowercase, non-alphanumerics → "-"
slug=$(printf '%s' "$title" \
| sed -E 's/&[a-zA-Z]+;|&#[0-9]+;/ /g' \
| iconv -f utf-8 -t ascii//TRANSLIT \
| tr '[:upper:]' '[:lower:]' \
| sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//')
[ -n "$slug" ] || { echo "Errore: slug vuoto dopo la pulizia del titolo" >&2; exit 1; }
branch="fix-${num}-${slug}"
if [ "$quiet" -eq 1 ]; then
echo "$branch"
else
echo "git checkout -b $branch"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment