Skip to content

Instantly share code, notes, and snippets.

@taheri24
Created December 14, 2025 21:27
Show Gist options
  • Select an option

  • Save taheri24/dde9a26b2b33a8ebbebc7c8d4d1debf9 to your computer and use it in GitHub Desktop.

Select an option

Save taheri24/dde9a26b2b33a8ebbebc7c8d4d1debf9 to your computer and use it in GitHub Desktop.
git-ai: AI-Powered Git Analysis with Claude CLI - Smart Code Reviews, Commit Messages & Security Audits
#!/bin/bash
# git-ai - AI-powered git analysis using claude-cli with custom prompts
# Usage: git-ai <command> [prompt-file] [git-diff-args]
set -euo pipefail
# ═══════════════════════════════════════════════════════════════
# CONFIGURATION
# ═══════════════════════════════════════════════════════════════
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROMPTS_DIR="${PROMPTS_DIR:-$SCRIPT_DIR/prompts}"
DEFAULT_DIFF_CMD="git diff --staged"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# ═══════════════════════════════════════════════════════════════
# HELPER FUNCTIONS
# ═══════════════════════════════════════════════════════════════
error() {
echo -e "${RED}Error: $1${NC}" >&2
exit 1
}
info() {
echo -e "${BLUE}ℹ $1${NC}" >&2
}
success() {
echo -e "${GREEN}✓ $1${NC}" >&2
}
warn() {
echo -e "${YELLOW}⚠ $1${NC}" >&2
}
usage() {
cat << 'EOF'
git-ai - AI-powered git analysis using claude-cli
USAGE:
git-ai <command> [prompt-file] [git-diff-args]
git-ai --prompt <prompt-file> [git-diff-args]
git-ai --help
COMMANDS:
analyze - Analyze code changes for bugs and improvements
review - Review staged changes for quality and security
genmsg - Generate conventional commit message
security - Security audit of changes
patchgroup - Group files by commit message (markdown)
summarize - Summarize recent commits
changelog - Generate changelog from commits
testgaps - Identify missing test cases
refactor - Suggest refactoring opportunities
perf - Performance review
pr-desc - Generate PR description
filehistory - Analyze file history (requires file path)
OPTIONS:
-p, --prompt FILE Use custom prompt file
-d, --diff CMD Custom git diff command (default: git diff --staged)
-o, --output FILE Save output to file
-n, --no-diff Don't append git diff (use prompt only)
-h, --help Show this help
EXAMPLES:
# Use built-in command
git-ai analyze
git-ai review
git-ai genmsg
# Use custom prompt file
git-ai --prompt prompts/custom.txt
git-ai -p my-prompt.txt
# Custom git diff command
git-ai analyze --diff "git diff HEAD~1"
git-ai -p prompts/review.txt -d "git diff main...HEAD"
# Group patch files
git-ai patchgroup
git-ai patchgroup -d "git format-patch -1 HEAD --stdout"
# Save output
git-ai analyze -o analysis.md
# Just use prompt without git diff
git-ai --prompt prompts/question.txt --no-diff
PROMPT FILES:
Prompt files should be plain text files containing the instruction
for Claude. The git diff output will be appended automatically unless
--no-diff is used.
Default prompt location: $PROMPTS_DIR
SETUP:
1. Create prompts directory: mkdir -p prompts
2. Add prompt files (see examples below)
3. Make script executable: chmod +x git-ai
4. Optional: ln -s $(pwd)/git-ai /usr/local/bin/git-ai
EOF
}
check_dependencies() {
command -v claude >/dev/null 2>&1 || error "claude-cli not found. Install from: https://github.com/anthropics/claude-cli"
command -v git >/dev/null 2>&1 || error "git not found"
}
ensure_prompts_dir() {
if [[ ! -d "$PROMPTS_DIR" ]]; then
info "Creating prompts directory: $PROMPTS_DIR"
mkdir -p "$PROMPTS_DIR"
create_default_prompts
fi
}
get_prompt_file() {
local cmd="$1"
echo "$PROMPTS_DIR/${cmd}.txt"
}
# ═══════════════════════════════════════════════════════════════
# CREATE DEFAULT PROMPT FILES
# ═══════════════════════════════════════════════════════════════
create_default_prompts() {
info "Creating default prompt files..."
# analyze.txt
cat > "$PROMPTS_DIR/analyze.txt" << 'EOF'
Analyze these code changes. Identify:
- Potential bugs
- Code quality issues
- Performance concerns
- Security vulnerabilities
- Best practice violations
- Improvement suggestions
Be concise and specific. Focus on actionable feedback.
EOF
# review.txt
cat > "$PROMPTS_DIR/review.txt" << 'EOF'
Review these staged changes for:
1. Code quality and readability
2. Potential bugs and edge cases
3. Security issues
4. Performance implications
5. Test coverage needs
6. Documentation requirements
Provide specific, actionable feedback.
EOF
# genmsg.txt
cat > "$PROMPTS_DIR/genmsg.txt" << 'EOF'
Generate a git commit message following conventional commits format.
Format:
<type>: <subject> (max 50 chars)
<body - what and why, if needed>
Types: feat, fix, docs, style, refactor, test, chore, perf
Output ONLY the commit message. No explanations, no markdown, no extra text.
EOF
# security.txt
cat > "$PROMPTS_DIR/security.txt" << 'EOF'
Perform a security audit. Check for:
- Hardcoded secrets, API keys, passwords
- SQL injection vulnerabilities
- XSS vulnerabilities
- Command injection risks
- Path traversal issues
- Insecure cryptography
- Authentication/authorization flaws
- Exposed sensitive data
- CORS misconfigurations
- Dependency vulnerabilities
List findings with severity (HIGH/MEDIUM/LOW).
EOF
# patchgroup.txt
cat > "$PROMPTS_DIR/patchgroup.txt" << 'EOF'
Parse this git patch and group files by commit message.
Output format (markdown only, no descriptions):
## <Commit Message 1>
- path/to/file1.ext
- path/to/file2.ext
## <Commit Message 2>
- path/to/file3.ext
Rules:
- Commit messages as ## headings
- Files as bullet points (-)
- No explanations or additional text
- One file per line
- Preserve exact file paths
- If no commit message exists, use "## Uncommitted Changes"
EOF
# summarize.txt
cat > "$PROMPTS_DIR/summarize.txt" << 'EOF'
Summarize these commits. Group by:
- Features (new functionality)
- Bug Fixes
- Refactoring
- Documentation
- Other
Be concise. Focus on what was accomplished.
EOF
# changelog.txt
cat > "$PROMPTS_DIR/changelog.txt" << 'EOF'
Generate a CHANGELOG.md entry from these commits.
Format:
## [Version] - Date
### Added
- New features
### Fixed
- Bug fixes
### Changed
- Changes to existing functionality
### Breaking Changes
- Breaking changes (if any)
Use conventional commit messages to categorize.
EOF
# testgaps.txt
cat > "$PROMPTS_DIR/testgaps.txt" << 'EOF'
Analyze these code changes and identify what tests should be added.
List:
1. Unit tests needed
2. Integration tests needed
3. Edge cases to cover
4. Error scenarios to test
5. Missing test coverage
Be specific about what to test and why.
EOF
# refactor.txt
cat > "$PROMPTS_DIR/refactor.txt" << 'EOF'
Suggest refactoring opportunities:
- DRY violations (code duplication)
- Long functions (>50 lines)
- Complex conditionals
- Magic numbers/strings
- Poor naming
- Tight coupling
- Missing abstractions
- Code smells
Provide specific suggestions with examples.
EOF
# perf.txt
cat > "$PROMPTS_DIR/perf.txt" << 'EOF'
Performance review. Identify:
- Inefficient algorithms (O(n²) or worse)
- N+1 query problems
- Unnecessary loops
- Memory leaks
- Heavy computations in loops
- Missing caching opportunities
- Blocking operations
- Database query optimization needs
Suggest specific optimizations.
EOF
# pr-desc.txt
cat > "$PROMPTS_DIR/pr-desc.txt" << 'EOF'
Generate a Pull Request description.
Format:
## What
Brief description of changes
## Why
Motivation and context
## How
Technical approach
## Testing
How to test these changes
## Screenshots (if UI changes)
Mention if screenshots needed
Be clear and concise.
EOF
# filehistory.txt
cat > "$PROMPTS_DIR/filehistory.txt" << 'EOF'
Summarize the evolution of this file:
- Major changes over time
- Why changes were made
- Patterns in modifications
- Key contributors (if visible)
- Current state vs original
Provide a narrative of the file's development.
EOF
success "Created default prompts in $PROMPTS_DIR"
}
# ═══════════════════════════════════════════════════════════════
# MAIN LOGIC
# ═══════════════════════════════════════════════════════════════
main() {
check_dependencies
if [[ $# -eq 0 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
usage
exit 0
fi
ensure_prompts_dir
local command=""
local prompt_file=""
local diff_cmd="$DEFAULT_DIFF_CMD"
local output_file=""
local use_diff=true
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
-p|--prompt)
prompt_file="$2"
shift 2
;;
-d|--diff)
diff_cmd="$2"
shift 2
;;
-o|--output)
output_file="$2"
shift 2
;;
-n|--no-diff)
use_diff=false
shift
;;
-h|--help)
usage
exit 0
;;
analyze|review|genmsg|security|patchgroup|summarize|changelog|testgaps|refactor|perf|pr-desc|filehistory)
command="$1"
shift
;;
*)
error "Unknown option: $1\nUse --help for usage information"
;;
esac
done
# Determine prompt file
if [[ -n "$prompt_file" ]]; then
[[ -f "$prompt_file" ]] || error "Prompt file not found: $prompt_file"
elif [[ -n "$command" ]]; then
prompt_file=$(get_prompt_file "$command")
[[ -f "$prompt_file" ]] || error "Prompt file not found: $prompt_file\nRun with --help to see available commands"
else
error "No command or prompt file specified\nUse --help for usage information"
fi
info "Using prompt: $prompt_file"
info "Diff command: $diff_cmd"
# Read prompt
local prompt
prompt=$(<"$prompt_file")
# Get git diff if needed
local git_output=""
if [[ "$use_diff" == true ]]; then
info "Running: $diff_cmd"
if ! git_output=$(eval "$diff_cmd" 2>&1); then
error "Git command failed: $diff_cmd"
fi
if [[ -z "$git_output" ]]; then
warn "No diff output. Check if you have staged changes or adjust --diff command"
exit 0
fi
fi
# Combine prompt and git output
local full_prompt
if [[ "$use_diff" == true ]]; then
full_prompt=$(cat << EOF
$prompt
---
$git_output
EOF
)
else
full_prompt="$prompt"
fi
# Run claude
info "Running claude-cli..."
local result
if ! result=$(echo "$full_prompt" | claude -p); then
error "claude-cli failed"
fi
# Output
if [[ -n "$output_file" ]]; then
echo "$result" > "$output_file"
success "Output saved to: $output_file"
else
echo "$result"
fi
}
# ═══════════════════════════════════════════════════════════════
# RUN
# ═══════════════════════════════════════════════════════════════
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment