Created git-pr-auto
I built a shell function that sends git diff to Claude to auto-generate Pull Request titles and descriptions. It includes practical features like automatic GitHub account switching and remote branch checking.
Key features:
- Claude automatically generates PR title and body from git diff
- Auto-detects master and main branches
- Checks remote branch existence before proceeding
- Automatic GitHub account switching (personal/work)
- Language switching based on account type
- Confirmation step before creating PR
- Automatically opens PR in browser after creation
Why I Built This
Writing Pull Requests was tedious. I faced several challenges:
PR Creation Takes Too Much Time
- Recalling changes to write a title
- Organizing and describing changes
- Formatting the description
- These tasks took 5-10 minutes every time
Switching Between Multiple Accounts is Annoying
- Using separate GitHub accounts for work and personal projects
- Need to configure git config for each repository
- GitHub CLI authentication needs switching too
- Wrong settings lead to PRs from the wrong account
Inconsistent PR Quality
- Descriptions become sloppy when tired
- Information gets insufficient when rushed
- Sometimes fail to accurately convey changes
git-pr-auto solves these issues. Claude API analyzes the diff and generates appropriate titles and descriptions. Automatic account switching prevents configuration mistakes.
Prerequisites
You need the following setup to use this function.
GitHub CLI
# macOS
brew install gh
# Authentication (personal)
gh auth login
# Authentication (work)
GH_HOST=github.example.com gh auth login
Claude CLI
# For macOS
brew install anthropic/claude/claude
# Authentication
claude auth
Check the official documentation for Claude CLI.
Environment Variables
# Add to .zshrc or .bashrc
# Pattern for personal account repositories (regex)
export GITHUB_PERSONAL_PATTERN="github.com/(your-username|your-org)"
# Work account settings
export GITHUB_WORK_USER="work.user@company.com"
export GITHUB_WORK_HOST="github.example.com"
Implementation
Here's the complete implementation.
git-pr-auto() {
# Auto-configure account
if ! git-auth-setup; then
return 1
fi
# Check GitHub CLI authentication
if ! gh auth status >/dev/null 2>&1; then
echo "Error: GitHub CLI is not authenticated"
if [ -n "$GH_HOST" ]; then
echo "Please run: GH_HOST=$GH_HOST gh auth login"
else
echo "Please run: gh auth login"
fi
echo ""
echo "Current directory: $(pwd)"
echo "Remote URL: $(git remote get-url origin 2>/dev/null)"
return 1
fi
# Get current branch
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
# Detect master or main branch
if git branch -a | grep -q "^\s*master$\|^\s*\*\s*master$\|remotes/origin/master$"; then
BASE_BRANCH=master
elif git branch -a | grep -q "^\s*main$\|^\s*\*\s*main$\|remotes/origin/main$"; then
BASE_BRANCH=main
else
echo "Error: Neither master nor main branch found"
return 1
fi
# Error if current branch is base branch
if [ "$CURRENT_BRANCH" = "$BASE_BRANCH" ]; then
echo "Error: Cannot create PR from $BASE_BRANCH branch"
return 1
fi
# Determine whether to use local or remote branch
if git rev-parse --verify "$BASE_BRANCH" >/dev/null 2>&1; then
COMPARE_BASE="$BASE_BRANCH"
elif git rev-parse --verify "origin/$BASE_BRANCH" >/dev/null 2>&1; then
COMPARE_BASE="origin/$BASE_BRANCH"
else
echo "Error: Cannot find $BASE_BRANCH branch locally or remotely"
return 1
fi
echo "π Checking diff between $CURRENT_BRANCH and $COMPARE_BASE..."
echo "----------------------------------------"
# Get diff
DIFF=$(git diff $COMPARE_BASE..HEAD)
if [ -z "$DIFF" ]; then
echo "Error: No differences found between $CURRENT_BRANCH and $COMPARE_BASE"
return 1
fi
# Show diff summary
echo "Files changed:"
STAT_OUTPUT=$(git diff --stat $COMPARE_BASE..HEAD)
if [ -z "$STAT_OUTPUT" ]; then
echo "Error: No file changes detected"
return 1
fi
echo "$STAT_OUTPUT"
echo "----------------------------------------"
# Check remote branch existence
if ! git ls-remote --exit-code --heads origin "$CURRENT_BRANCH" >/dev/null 2>&1; then
echo ""
echo "β Error: Remote branch 'origin/$CURRENT_BRANCH' does not exist"
echo ""
echo "Please push your branch to remote first:"
echo " git push -u origin $CURRENT_BRANCH"
return 1
fi
# Generate PR content with claude command
echo "π€ Analyzing diff with Claude..."
# Change Body language based on account type
if [ "$GITHUB_ACCOUNT_TYPE" = "personal" ]; then
BODY_LANG="English"
else
BODY_LANG="Japanese"
fi
PR_CONTENT=$(claude -p "Generate a Pull Request title and description from the following git diff.
Please output in the following format only (do not output any other text):
TITLE: [Concise title (English, within 50 characters)]
BODY:
[Description of changes (in ${BODY_LANG} in detail)]
- Change 1
- Change 2
...
Below is the git diff:
$DIFF
")
# Debug: Check Claude output
if [ -z "$PR_CONTENT" ]; then
echo "Error: Claude returned empty response"
return 1
fi
# Extract title and body
PR_TITLE=$(echo "$PR_CONTENT" | grep "^TITLE:" | head -n 1 | sed 's/^TITLE:[[:space:]]*//')
PR_BODY=$(echo "$PR_CONTENT" | sed -n '/^BODY:/,$ p' | tail -n +2)
# Error if title is empty
if [ -z "$PR_TITLE" ]; then
echo "Error: Failed to extract PR title from Claude response"
echo "Claude output:"
echo "$PR_CONTENT"
return 1
fi
echo "----------------------------------------"
echo "π Generated PR Content:"
echo "Title: $PR_TITLE"
echo ""
echo "Body:"
echo "$PR_BODY"
echo "----------------------------------------"
# Create PR
echo ""
read "?Create PR? (y/N): " CONFIRM
if [ "$CONFIRM" = "y" ] || [ "$CONFIRM" = "Y" ]; then
echo "π Creating PR..."
PR_URL=$(gh pr create --base "$BASE_BRANCH" --title "$PR_TITLE" --body "$PR_BODY" 2>&1 | grep -o 'https://github.com/[^[:space:]]*')
if [ -n "$PR_URL" ]; then
echo ""
echo "β
PR created successfully!"
echo "Opening PR in browser..."
open "$PR_URL"
else
echo ""
echo "β
PR created successfully!"
gh pr view --web
fi
else
echo "PR creation cancelled"
fi
}
Key Points
1. Remote Branch Check
Before calling Claude API, it checks if the remote branch exists. This prevents wasting API costs and time.
if ! git ls-remote --exit-code --heads origin "$CURRENT_BRANCH" >/dev/null 2>&1; then
echo "β Error: Remote branch 'origin/$CURRENT_BRANCH' does not exist"
echo "Please push your branch to remote first:"
echo " git push -u origin $CURRENT_BRANCH"
return 1
fi
2. Language Switching Based on Account Type
Generates PR body in English for personal accounts and Japanese for work accounts.
if [ "$GITHUB_ACCOUNT_TYPE" = "personal" ]; then
BODY_LANG="English"
else
BODY_LANG="Japanese"
fi
3. Prompt for Claude
Specifying a clear format for Claude ensures parseable output.
PR_CONTENT=$(claude -p "Generate a Pull Request title and description from the following git diff.
Please output in the following format only (do not output any other text):
TITLE: [Concise title (English, within 50 characters)]
BODY:
[Description of changes (in ${BODY_LANG} in detail)]
- Change 1
- Change 2
...
Below is the git diff:
$DIFF
")
Usage
Basic Usage
# Commit changes on feature branch
git add .
git commit -m "Add new feature"
# Push to remote
git push -u origin feature-branch
# Auto-create PR
git-pr-auto
The execution flow:
- Automatic account configuration
- GitHub CLI authentication check
- Base branch detection
- Diff verification and display
- Remote branch check
- PR content generation with Claude API
- Review generated content
- Confirm PR creation
- Create PR and open in browser
Example Execution
$ git-pr-auto
π Checking diff between feature-branch and main...
----------------------------------------
Files changed:
functions/git.sh | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
----------------------------------------
π€ Analyzing diff with Claude...
----------------------------------------
π Generated PR Content:
Title: Add remote branch check before PR creation
Body:
Added remote branch existence check for more robust PR creation flow.
Changes:
- Check remote branch existence before Claude API call
- Display appropriate error message and push command when branch doesn't exist
- Reduce API cost and time waste
----------------------------------------
Create PR? (y/N): y
π Creating PR...
β
PR created successfully!
Opening PR in browser...
Automatic GitHub Account Switching
This function calls another function called git-auth-setup to automatically configure accounts.
git-auth-setup() {
# Get remote URL
REMOTE_URL=$(git remote get-url origin 2>/dev/null)
if [ -z "$REMOTE_URL" ]; then
echo "Error: Not a git repository or no remote configured"
return 1
fi
# Determine if personal or work account
if echo "$REMOTE_URL" | grep -qE "$GITHUB_PERSONAL_PATTERN"; then
# Personal account settings
export GITHUB_ACCOUNT_TYPE="personal"
unset GH_HOST
git config user.name "Your Name"
git config user.email "personal@example.com"
else
# Work account settings
export GITHUB_ACCOUNT_TYPE="work"
export GH_HOST="$GITHUB_WORK_HOST"
git config user.name "Your Work Name"
git config user.email "$GITHUB_WORK_USER"
fi
}
This mechanism automatically switches to the appropriate account settings based on the repository URL.
Troubleshooting
Claude CLI Not Installed
command not found: claude
Install Claude CLI:
brew install anthropic/claude/claude
claude auth
GitHub CLI Not Authenticated
Error: GitHub CLI is not authenticated
Please run: gh auth login
Authenticate with the displayed command:
# Personal account
gh auth login
# Work account
GH_HOST=github.example.com gh auth login
Remote Branch Doesn't Exist
β Error: Remote branch 'origin/feature-branch' does not exist
Please push your branch to remote first:
git push -u origin feature-branch
Push with the displayed command:
git push -u origin feature-branch
Empty Claude Response
Error: Claude returned empty response
Possible causes:
- Claude API authentication expired β Re-authenticate with
claude auth - Diff is too large β Split commits to make them smaller
- Network issues β Check connection
Can't Extract PR Title
Error: Failed to extract PR title from Claude response
This occurs when Claude's output format differs from expectations. Check the debug output and adjust the prompt if needed.
Further Improvements
While the current implementation is practical, there's room for improvement:
Draft PR Support
gh pr create --draft --base "$BASE_BRANCH" --title "$PR_TITLE" --body "$PR_BODY"
Add an option to create as a draft PR.
Auto-assign Reviewers
gh pr create --base "$BASE_BRANCH" --title "$PR_TITLE" --body "$PR_BODY" \
--reviewer "reviewer1,reviewer2"
Automatically assign team members as reviewers.
Auto-label
gh pr create --base "$BASE_BRANCH" --title "$PR_TITLE" --body "$PR_BODY" \
--label "enhancement,needs-review"
Automatically add labels based on the changes.
Template Support
Read GitHub's PR template and pass it to Claude to generate PRs that follow the template.
Summary
git-pr-auto makes PR creation dramatically easier. It's particularly effective in these scenarios:
- Managing multiple GitHub accounts
- Finding PR descriptions tedious to write
- Spending too much time organizing and summarizing changes
- Wanting to automate the PR creation process
Claude API's accuracy is high, generating content that's usable as-is in most cases. Occasional adjustments are needed, but it's much faster than writing from scratch.
Since using this function, time spent on PR creation has significantly decreased. Give it a try if you face similar challenges.
Top comments (0)