Skip to content

Instantly share code, notes, and snippets.

@moritzsalla
Last active October 24, 2024 10:05
Show Gist options
  • Save moritzsalla/562b6024d9aaee759768df641b125a90 to your computer and use it in GitHub Desktop.
Save moritzsalla/562b6024d9aaee759768df641b125a90 to your computer and use it in GitHub Desktop.
Git branch and pr name generator (format: {task}/{scope}/{name})
# Paste this command somewhere in your .zshrc
# ...rest of file
# Load config file if it exists
[[ -f ~/.zsh/git-branch.zsh ]] && source ~/.zsh/git-branch.zsh
# ...rest of file
# Create this file here: .zsh/git-branch.zsh
# In this example, I've created the .zsh folder, but the file can live anywhere. As long as the .zshrc file points to it.
#!/bin/zsh
###############################################################################
# Git Branch Name Generator V.1.0.0
# See `branch --help` command for usage information
###############################################################################
declare -A BRANCH_TYPES=(
["feature"]="✨ New features and functionality"
["bugfix"]="πŸ› Bug fixes and corrections"
["hotfix"]="🚨 Urgent production fixes"
["design"]="🎨 UI/UX changes and improvements"
["refactor"]="πŸ”„ Code restructuring and optimization"
["test"]="πŸ§ͺ Adding or updating tests"
["chore"]="πŸ”§ Maintenance, refactoring, dependencies"
)
function _git_branch::slugify() {
echo "$1" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | sed 's/[^a-zA-Z0-9-]//g'
}
function _git_branch::to_title_case() {
# Simply replace hyphens with spaces, keeping original case
printf "%s" "$1" | sed 's/-/ /g'
}
function _git_branch::format_branch_types() {
for type in ${(k)BRANCH_TYPES}; do
local emoji=${BRANCH_TYPES[$type]%% *} # Get emoji (first word)
local desc=${BRANCH_TYPES[$type]#* } # Get description (rest of string)
printf " %-16s %s\n" "$emoji $type" "$desc"
done
}
function _git_branch::display_menu() {
echo "\n🌿 Select branch type:"
local i=1
for type in ${(k)BRANCH_TYPES}; do
echo " $i) $type - ${BRANCH_TYPES[$type]}"
((i++))
done
echo
}
function _git_branch::get_branch_type() {
local choice=$1
local i=1
local selected_type=""
for type in ${(k)BRANCH_TYPES}; do
if [[ $i -eq $choice ]]; then
echo $type
return 0
fi
((i++))
done
return 1
}
function _git_branch::show_help() {
cat << EOF
🌿 Git Branch Name Generator
Branch Format: {type}/{scope}/{name}
PR Title Format: type(scope): Name
Commands:
branch Create a new branch interactively
branch --pr Generate PR title from current branch
branch --help Show this help message
Branch Types:
$(_git_branch::format_branch_types)
Format:
Branch: type/scope/name
PR Title: type(scope): Name
Examples:
$ branch
β†’ Creates: feature/home/hero-section
$ branch --pr
β†’ Generates: feature(home): Hero section
EOF
}
function _git_branch::create_new_branch() {
_git_branch::display_menu
read "choice?πŸ“ Enter number (1-${#BRANCH_TYPES}): "
local selected_type=$(_git_branch::get_branch_type $choice)
if [[ -z $selected_type ]]; then
echo "\n❌ Error: Invalid choice"
return 1
fi
read "scope?πŸ“ Enter scope: "
if [[ -z $scope ]]; then
echo "\n❌ Error: Scope cannot be empty"
return 1
fi
read "name?πŸ’‘ Enter name: "
if [[ -z $name ]]; then
echo "\n❌ Error: Name cannot be empty"
return 1
fi
local branch_name="$selected_type/$(_git_branch::slugify $scope)/$(_git_branch::slugify $name)"
if ! git checkout -b "$branch_name"; then
echo "\n❌ Error: Failed to create branch"
return 1
fi
}
function _git_branch::generate_pr_title() {
local current_branch=$(git branch --show-current)
local branch_type=${current_branch%%/*}
local remaining=${current_branch#*/}
local scope=${remaining%%/*}
local name=${remaining#*/}
local title_name=$(_git_branch::to_title_case "$name")
local pr_title="$branch_type($scope): $title_name"
printf "%s" "$pr_title" | pbcopy
echo "\nπŸ“‹ PR title copied to clipboard:"
echo " $pr_title\n"
}
function branch() {
case "$1" in
--help)
_git_branch::show_help
;;
--pr)
_git_branch::generate_pr_title
;;
"")
_git_branch::create_new_branch
;;
*)
echo "Unknown option: $1. Possible options are: --help, --pr."
echo "Run 'branch --help' for usage information"
return 1
;;
esac
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment