Update gp
All checks were successful
Build-Test-Publish / build (linux/amd64) (push) Successful in 6s
Build-Test-Publish / build (linux/arm64) (push) Successful in 12s

This commit is contained in:
j
2026-03-01 21:54:00 +13:00
parent 4c69941722
commit 7b984f5542

85
gp
View File

@@ -49,14 +49,45 @@ EXAMPLES:
EOF EOF
} }
# Function to generate commit message based on changes # Function to generate commit message using Claude AI
generate_commit_message() { generate_commit_message_ai() {
# Stage files first so we can get a proper diff
if [ "$ADD_ALL" = true ]; then
git add -A
fi
local diff
diff=$(git diff --cached)
if [ -z "$diff" ]; then
return 1
fi
local msg
msg=$(echo "$diff" | claude --print \
"Write a short git commit message (max 72 chars subject line) summarising these changes. Output ONLY the message, no quotes or prefixes." \
2>/dev/null) || return 1
# Validate: non-empty, single line, reasonable length
if [ -z "$msg" ]; then
return 1
fi
# Take only the first line
msg=$(echo "$msg" | head -1)
if [ ${#msg} -gt 120 ]; then
return 1
fi
echo "$msg"
}
# Function to generate commit message based on heuristics (fallback)
generate_commit_message_fallback() {
# First check if we have staged changes # First check if we have staged changes
local has_staged_changes=false local has_staged_changes=false
if ! git diff --cached --quiet; then if ! git diff --cached --quiet; then
has_staged_changes=true has_staged_changes=true
fi fi
# Determine which changes to analyze based on staging status and ADD_ALL setting # Determine which changes to analyze based on staging status and ADD_ALL setting
local status_command="" local status_command=""
if [ "$has_staged_changes" = true ]; then if [ "$has_staged_changes" = true ]; then
@@ -64,11 +95,11 @@ generate_commit_message() {
else else
status_command="git diff --name-status" status_command="git diff --name-status"
fi fi
# Get all changes (staged or unstaged depending on context) # Get all changes (staged or unstaged depending on context)
local all_changes local all_changes
all_changes=$($status_command) all_changes=$($status_command)
# If no changes from diff, check for untracked files when add-all is enabled # If no changes from diff, check for untracked files when add-all is enabled
if [ -z "$all_changes" ] && [ "$ADD_ALL" = true ]; then if [ -z "$all_changes" ] && [ "$ADD_ALL" = true ]; then
local untracked_files local untracked_files
@@ -78,27 +109,27 @@ generate_commit_message() {
all_changes=$(echo "$untracked_files" | sed 's/^/A\t/') all_changes=$(echo "$untracked_files" | sed 's/^/A\t/')
fi fi
fi fi
if [ -z "$all_changes" ]; then if [ -z "$all_changes" ]; then
echo "No changes to commit" echo "No changes to commit"
return 1 return 1
fi fi
# Count total files # Count total files
local files_count local files_count
files_count=$(echo "$all_changes" | wc -l) files_count=$(echo "$all_changes" | wc -l)
# Generate smart commit message based on file types and changes # Generate smart commit message based on file types and changes
local has_source_files=false local has_source_files=false
local has_config_files=false local has_config_files=false
local has_docs=false local has_docs=false
local has_tests=false local has_tests=false
local message="" local message=""
# Extract just the filenames for type detection # Extract just the filenames for type detection
while IFS=$'\t' read -r status file; do while IFS=$'\t' read -r status file; do
[ -z "$file" ] && continue [ -z "$file" ] && continue
case "$file" in case "$file" in
*.cpp|*.hpp|*.c|*.h|*.js|*.ts|*.py|*.go|*.rs|*.java) *.cpp|*.hpp|*.c|*.h|*.js|*.ts|*.py|*.go|*.rs|*.java)
has_source_files=true has_source_files=true
@@ -114,7 +145,7 @@ generate_commit_message() {
;; ;;
esac esac
done <<< "$all_changes" done <<< "$all_changes"
# Create descriptive commit message # Create descriptive commit message
if [ "$files_count" -eq 1 ]; then if [ "$files_count" -eq 1 ]; then
local change_line local change_line
@@ -123,7 +154,7 @@ generate_commit_message() {
local single_file local single_file
status=$(echo "$change_line" | cut -f1) status=$(echo "$change_line" | cut -f1)
single_file=$(echo "$change_line" | cut -f2) single_file=$(echo "$change_line" | cut -f2)
case "${status:0:1}" in case "${status:0:1}" in
A) message="Add $single_file" ;; A) message="Add $single_file" ;;
M) message="Update $single_file" ;; M) message="Update $single_file" ;;
@@ -137,9 +168,9 @@ generate_commit_message() {
local modified_count=0 local modified_count=0
local deleted_count=0 local deleted_count=0
local renamed_count=0 local renamed_count=0
# Use the all_changes variable we already have # Use the all_changes variable we already have
# Count different types of changes # Count different types of changes
while IFS=$'\t' read -r status file; do while IFS=$'\t' read -r status file; do
[ -z "$status" ] && continue [ -z "$status" ] && continue
@@ -150,7 +181,7 @@ generate_commit_message() {
R) ((renamed_count++)) ;; R) ((renamed_count++)) ;;
esac esac
done <<< "$all_changes" done <<< "$all_changes"
# Also count untracked files if add-all is enabled # Also count untracked files if add-all is enabled
if [ "$ADD_ALL" = true ]; then if [ "$ADD_ALL" = true ]; then
local untracked_files local untracked_files
@@ -161,14 +192,14 @@ generate_commit_message() {
((added_count += untracked_count)) ((added_count += untracked_count))
fi fi
fi fi
# Generate message based on change types # Generate message based on change types
local change_parts=() local change_parts=()
[ $added_count -gt 0 ] && change_parts+=("add $added_count") [ $added_count -gt 0 ] && change_parts+=("add $added_count")
[ $modified_count -gt 0 ] && change_parts+=("update $modified_count") [ $modified_count -gt 0 ] && change_parts+=("update $modified_count")
[ $deleted_count -gt 0 ] && change_parts+=("remove $deleted_count") [ $deleted_count -gt 0 ] && change_parts+=("remove $deleted_count")
[ $renamed_count -gt 0 ] && change_parts+=("rename $renamed_count") [ $renamed_count -gt 0 ] && change_parts+=("rename $renamed_count")
local change_desc="" local change_desc=""
if [ ${#change_parts[@]} -eq 1 ]; then if [ ${#change_parts[@]} -eq 1 ]; then
change_desc="${change_parts[0]}" change_desc="${change_parts[0]}"
@@ -183,7 +214,7 @@ generate_commit_message() {
done done
change_desc+=" and ${change_parts[last_idx]}" change_desc+=" and ${change_parts[last_idx]}"
fi fi
local prefix="" local prefix=""
if $has_tests; then if $has_tests; then
prefix="test: " prefix="test: "
@@ -194,16 +225,28 @@ generate_commit_message() {
elif $has_source_files; then elif $has_source_files; then
prefix="feat: " prefix="feat: "
fi fi
# Capitalize first letter of change description # Capitalize first letter of change description
change_desc="$(echo "${change_desc:0:1}" | tr '[:lower:]' '[:upper:]')${change_desc:1}" change_desc="$(echo "${change_desc:0:1}" | tr '[:lower:]' '[:upper:]')${change_desc:1}"
message="${prefix}${change_desc} files" message="${prefix}${change_desc} files"
fi fi
echo "$message" echo "$message"
} }
# Function to generate commit message — tries Claude AI first, falls back to heuristics
generate_commit_message() {
if command -v claude &>/dev/null; then
local ai_msg
if ai_msg=$(generate_commit_message_ai); then
echo "$ai_msg"
return 0
fi
fi
generate_commit_message_fallback
}
# Function to check if we're in a git repository and change to repo root # Function to check if we're in a git repository and change to repo root
check_git_repo() { check_git_repo() {
if ! git rev-parse --git-dir >/dev/null 2>&1; then if ! git rev-parse --git-dir >/dev/null 2>&1; then