2025-08-04 10:14:33 -07:00
#!/bin/bash
# Setup script for Claude Commit on any machine
# This script installs the claude-commit tool globally
set -e
# Colors for output
RED = '\033[0;31m'
GREEN = '\033[0;32m'
YELLOW = '\033[1;33m'
BLUE = '\033[0;34m'
NC = '\033[0m' # No Color
echo -e " ${ BLUE } ================================== ${ NC } "
echo -e " ${ BLUE } Claude Commit Setup Script ${ NC } "
echo -e " ${ BLUE } ================================== ${ NC } "
echo ""
# Create ~/.local/bin if it doesn't exist
echo -e " ${ YELLOW } Creating ~/.local/bin directory... ${ NC } "
mkdir -p ~/.local/bin
# Create the claude-commit script
echo -e " ${ YELLOW } Installing claude-commit script... ${ NC } "
cat > ~/.local/bin/claude-commit << 'EOF'
#!/bin/bash
# Claude Commit Message Generator - Global Version
# Automatically generates Conventional Commit messages using git diff
# Colors for output
RED = '\033[0;31m'
GREEN = '\033[0;32m'
YELLOW = '\033[1;33m'
NC = '\033[0m' # No Color
# Check if we're in a git repository
if ! git rev-parse --is-inside-work-tree >/dev/null 2>& 1; then
echo -e " ${ RED } Not in a git repository ${ NC } "
exit 1
fi
# Check if there are changes to commit
if [ [ -z $( git status -s) ] ] ; then
echo -e " ${ RED } No changes to commit ${ NC } "
exit 1
fi
# Get the diff of staged changes (or all changes if nothing staged)
if [ [ -n $( git diff --cached --name-only) ] ] ; then
DIFF = $( git diff --cached)
FILES = $( git diff --cached --name-only)
echo -e " ${ GREEN } Analyzing staged changes... ${ NC } "
else
DIFF = $( git diff)
FILES = $( git diff --name-only)
echo -e " ${ YELLOW } No staged changes. Analyzing all modified files... ${ NC } "
echo -e " ${ YELLOW } Run 'git add' first to stage specific changes ${ NC } "
fi
# Get project name from git remote or directory name
PROJECT_NAME = $( basename " $( git rev-parse --show-toplevel) " )
REMOTE_URL = $( git config --get remote.origin.url 2>/dev/null)
if [ [ -n " $REMOTE_URL " ] ] ; then
PROJECT_NAME = $( basename -s .git " $REMOTE_URL " )
fi
# Create a prompt for Claude
PROMPT = " Based on the following git diff from the ' $PROJECT_NAME ' project, generate a Conventional Commit message.
REQUIREMENTS:
1. Use Conventional Commit format: <type>( <scope>) : <description>
2. Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore
3. Keep first line under 72 characters
4. Use imperative mood ( e.g., 'add' not 'added' )
5. Include a detailed body explaining the purpose and impact
6. Note any breaking changes with 'BREAKING CHANGE:' prefix
7. Reference any issue numbers if apparent from the code
FILES CHANGED:
$FILES
GIT DIFF ( showing first 500 lines) :
$( echo " $DIFF " | head -n 500)
Generate ONLY the commit message, no explanations or markdown formatting."
# Call Claude API (using claude CLI)
echo -e " ${ GREEN } Generating commit message with Claude... ${ NC } "
# Save the prompt to a temporary file to avoid shell escaping issues
TEMP_PROMPT = $( mktemp)
echo " $PROMPT " > " $TEMP_PROMPT "
# Generate the commit message
COMMIT_MSG = $( claude code --no-markdown < " $TEMP_PROMPT " 2>/dev/null)
# Clean up temp file
rm " $TEMP_PROMPT "
# Check if message was generated
if [ [ -z " $COMMIT_MSG " ] ] ; then
echo -e " ${ RED } Failed to generate commit message ${ NC } "
echo "Falling back to standard git commit..."
git commit
exit 1
fi
# Display the generated message
2025-08-04 10:28:01 -07:00
echo ""
2025-08-04 10:14:33 -07:00
echo -e " ${ GREEN } Generated commit message: ${ NC } "
2025-08-04 10:28:01 -07:00
echo "========================================"
2025-08-04 10:14:33 -07:00
echo " $COMMIT_MSG "
2025-08-04 10:28:01 -07:00
echo "========================================"
echo ""
2025-08-04 10:14:33 -07:00
2025-08-04 10:28:01 -07:00
# ALWAYS require explicit review
echo -e " ${ YELLOW } ⚠️ REVIEW REQUIRED ${ NC } "
echo -e " ${ YELLOW } Please review the commit message above carefully. ${ NC } "
echo ""
echo -e " ${ YELLOW } What would you like to do? ${ NC } "
echo " ${ GREEN } 1) ${ NC } Use this message AS-IS "
echo " ${ GREEN } 2) ${ NC } EDIT this message first "
echo " ${ GREEN } 3) ${ NC } Generate a NEW message "
echo " ${ RED } 4) ${ NC } CANCEL (no commit) "
echo ""
read -p "Your choice [1-4]: " choice
2025-08-04 10:14:33 -07:00
case $choice in
1)
2025-08-04 10:28:01 -07:00
# Final confirmation before committing
echo -e " ${ YELLOW } Ready to commit with the message above. ${ NC } "
read -p "Confirm commit? [y/N]: " confirm
if [ [ " $confirm " = ~ ^[ Yy] $ ] ] ; then
# Stage all changes if nothing is staged
if [ [ -z $( git diff --cached --name-only) ] ] ; then
git add -A
fi
# Commit with the generated message
git commit -m " $COMMIT_MSG "
echo -e " ${ GREEN } ✓ Committed successfully ${ NC } "
echo -e " ${ YELLOW } 📝 Note: Changes are committed locally only ${ NC } "
echo -e " ${ YELLOW } Run 'git push' manually when ready to push ${ NC } "
else
echo -e " ${ YELLOW } Commit cancelled ${ NC } "
exit 0
2025-08-04 10:14:33 -07:00
fi
; ;
2)
# Save message to temp file and open in editor
TEMP_MSG = $( mktemp)
echo " $COMMIT_MSG " > " $TEMP_MSG "
2025-08-04 10:28:01 -07:00
echo -e " ${ YELLOW } Opening editor to modify the message... ${ NC } "
2025-08-04 10:14:33 -07:00
${ EDITOR :- vim } " $TEMP_MSG "
2025-08-04 10:28:01 -07:00
# Show the edited message
echo ""
echo -e " ${ GREEN } Edited commit message: ${ NC } "
echo "========================================"
cat " $TEMP_MSG "
echo "========================================"
echo ""
read -p "Commit with this edited message? [y/N]: " confirm
2025-08-04 10:14:33 -07:00
2025-08-04 10:28:01 -07:00
if [ [ " $confirm " = ~ ^[ Yy] $ ] ] ; then
# Stage all changes if nothing is staged
if [ [ -z $( git diff --cached --name-only) ] ] ; then
git add -A
fi
# Commit with edited message
git commit -F " $TEMP_MSG "
rm " $TEMP_MSG "
echo -e " ${ GREEN } ✓ Committed with edited message ${ NC } "
echo -e " ${ YELLOW } 📝 Note: Changes are committed locally only ${ NC } "
echo -e " ${ YELLOW } Run 'git push' manually when ready to push ${ NC } "
else
rm " $TEMP_MSG "
echo -e " ${ YELLOW } Commit cancelled ${ NC } "
exit 0
fi
2025-08-04 10:14:33 -07:00
; ;
3)
2025-08-04 10:28:01 -07:00
echo -e " ${ YELLOW } Regenerating commit message... ${ NC } "
# Re-run the script
exec " $0 " " $@ "
; ;
4)
echo -e " ${ RED } ✗ Commit cancelled by user ${ NC } "
2025-08-04 10:14:33 -07:00
exit 0
; ;
*)
echo -e " ${ RED } Invalid choice. Commit cancelled ${ NC } "
exit 1
; ;
esac
EOF
# Make the script executable
chmod +x ~/.local/bin/claude-commit
echo -e " ${ GREEN } ✓ claude-commit script installed ${ NC } "
2025-08-04 10:28:01 -07:00
# Create configuration file if it doesn't exist
if [ [ ! -f ~/.claude-commit.conf ] ] ; then
echo -e " ${ YELLOW } Creating configuration file... ${ NC } "
cat > ~/.claude-commit.conf << 'CONF_EOF'
# Claude Commit Configuration
# Safety settings to ensure review and prevent accidental pushes
# ALWAYS require explicit confirmation before committing
REQUIRE_CONFIRMATION = true
# NEVER auto-push after commit
AUTO_PUSH = false
# Default editor for message editing (vim, nano, code, etc.)
# Leave empty to use system default ($EDITOR)
PREFERRED_EDITOR =
# Show diff in commit message review (helps catch issues)
SHOW_DIFF_PREVIEW = false
# Maximum diff size to include in Claude prompt (lines)
MAX_DIFF_LINES = 500
# Require double confirmation for commits with breaking changes
DOUBLE_CONFIRM_BREAKING = true
CONF_EOF
echo -e " ${ GREEN } ✓ Configuration file created at ~/.claude-commit.conf ${ NC } "
else
echo -e " ${ GREEN } ✓ Configuration file already exists ${ NC } "
fi
2025-08-04 10:14:33 -07:00
# Set up git aliases
echo -e " ${ YELLOW } Setting up git aliases... ${ NC } "
git config --global alias.cc '!~/.local/bin/claude-commit'
git config --global alias.smart-commit '!~/.local/bin/claude-commit'
echo -e " ${ GREEN } ✓ Git aliases configured ${ NC } "
# Add ~/.local/bin to PATH if not already there
if [ [ " : $PATH : " != *" : $HOME /.local/bin: " * ] ] ; then
echo -e " ${ YELLOW } Adding ~/.local/bin to PATH... ${ NC } "
# Detect shell and update appropriate config file
if [ [ -n " $ZSH_VERSION " ] ] ; then
SHELL_CONFIG = " $HOME /.zshrc "
elif [ [ -n " $BASH_VERSION " ] ] ; then
SHELL_CONFIG = " $HOME /.bashrc "
else
SHELL_CONFIG = " $HOME /.profile "
fi
echo '' >> " $SHELL_CONFIG "
echo '# Added by claude-commit setup' >> " $SHELL_CONFIG "
echo 'export PATH="$HOME/.local/bin:$PATH"' >> " $SHELL_CONFIG "
echo -e " ${ GREEN } ✓ Added to $SHELL_CONFIG ${ NC } "
echo -e " ${ YELLOW } Please run: source $SHELL_CONFIG ${ NC } "
else
echo -e " ${ GREEN } ✓ ~/.local/bin already in PATH ${ NC } "
fi
echo ""
echo -e " ${ GREEN } ================================== ${ NC } "
echo -e " ${ GREEN } Installation Complete! ${ NC } "
echo -e " ${ GREEN } ================================== ${ NC } "
echo ""
echo -e " ${ BLUE } Usage: ${ NC } "
echo -e " ${ YELLOW } git cc ${ NC } - Generate and commit with Claude "
echo -e " ${ YELLOW } git smart-commit ${ NC } - Alternative alias "
echo ""
echo -e " ${ BLUE } This works in any git repository! ${ NC } "