cd /news/developer-tools/example-of-claude-code-git-integrati… · home topics developer-tools article
[ARTICLE · art-113658] src=gist.github.com ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Example of Claude Code Git Integration

A developer shared a bash script that integrates Claude Code with GitHub Issues, enabling automated local processing of issue commands. The script creates a branch, sets up a Node.js environment, and uses the GitHub CLI to comment on issues, demonstrating a practical workflow for AI-assisted development.

read12 min views2 publishedAug 28, 2026

| #!/bin/bash | | | | | | | | set -e | | | | | ISSUE_NUMBER="${ISSUE_NUMBER}" | | ISSUE_TITLE="${ISSUE_TITLE}" | | ISSUE_AUTHOR="${ISSUE_AUTHOR}" | | ISSUE_COMMAND="${ISSUE_COMMAND}" | | REPO_OWNER="${REPO_OWNER}" | | REPO_NAME="${REPO_NAME}" | | GITHUB_TOKEN="${GITHUB_TOKEN}" | | | | | REPO="${REPO_OWNER}/${REPO_NAME}" | | BRANCH_NAME="claude-bot/issue-${ISSUE_NUMBER}" | | | | | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" | | PROJECT_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )" | | | | | LOG_DIR="$PROJECT_ROOT/logs/claude-handler" | | mkdir -p "$LOG_DIR" | | LOG_FILE="$LOG_DIR/handler-local-$(date +%Y%m%d).log" | | | | | log() { | | echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" | | } | | | | | add_issue_comment() { | | local comment="$1" | | log "Adding comment to issue #$ISSUE_NUMBER" | | | | gh issue comment "$ISSUE_NUMBER" \ | | --repo "$REPO" \ | | --body "$comment" | | } | | | | | get_default_branch() { | | gh repo view "$REPO" --json defaultBranchRef --jq '.defaultBranchRef.name' | | } | | | | | setup_node_env() { | | log "Setting up Node.js environment..." | | | | | if [ -s "$HOME/.nvm/nvm.sh" ]; then | | source "$HOME/.nvm/nvm.sh" | | nvm use 22.16.0 >/dev/null 2>&1 || { | | log "Installing Node.js 22.16.0..." | | nvm install 22.16.0 | | nvm use 22.16.0 | | } | | elif [ -s "/usr/local/share/nvm/nvm.sh" ]; then | | source "/usr/local/share/nvm/nvm.sh" | | nvm use 22.16.0 >/dev/null 2>&1 || { | | log "Installing Node.js 22.16.0..." | | nvm install 22.16.0 | | nvm use 22.16.0 | | } | | fi | | | | NODE_VERSION=$(node --version) | | log "Using Node.js: $NODE_VERSION" | | } | | | | log "=== Processing Issue #$ISSUE_NUMBER Locally ===" | | log "Title: $ISSUE_TITLE" | | log "Author: $ISSUE_AUTHOR" | | log "Command: $ISSUE_COMMAND" | | log "Branch will be: $BRANCH_NAME" | | | | | DEFAULT_BRANCH=$(get_default_branch) | | log "Repository default branch: $DEFAULT_BRANCH" | | | | | ACKNOWLEDGMENT="👋 Hello @$ISSUE_AUTHOR! I'm Claude, and I'll help you with this issue. | | | | I'm analyzing your request and will create a branch to work on it locally. Here's what I understand: | | | | Request: $ISSUE_COMMAND | | | | I'll start working on this and provide updates as I progress. Creating branch `$BRANCH_NAME` from `$DEFAULT_BRANCH`..." | | | | add_issue_comment "$ACKNOWLEDGMENT" | | | | | cd "$PROJECT_ROOT" | | | | | log "Cleaning up git state" | | git reset --hard HEAD 2>/dev/null || true | | git clean -fd 2>/dev/null || true | | git checkout "$DEFAULT_BRANCH" 2>/dev/null || true | | | | | log "Configuring Git authentication" | | git config --global user.name "Claude Bot" | | git config --global user.email "claude-bot@anthropic.com" | | | | | git config --global --unset-all credential.helper || true | | | | | if [ -n "$GITHUB_TOKEN" ]; then | | log "Using GITHUB_TOKEN for authentication" | | | git config --global credential.helper "!f() { | | if [ "$1" = "get" ]; then | | echo "username=token" | | echo "password=$GITHUB_TOKEN" | | fi | | }; f" | | | | | CURRENT_REMOTE=$(git config --get remote.origin.url || echo "") | | if [[ "$CURRENT_REMOTE" == "github.com" ]] && [[ "$CURRENT_REMOTE" != "@" ]]; then | | | NEW_REMOTE=$(echo "$CURRENT_REMOTE" | sed "s|https://github.com/|https://token:$GITHUB_TOKEN@github.com/|") | | git remote set-url origin "$NEW_REMOTE" | | log "Updated remote URL for token auth" | | fi | | else | | log "Using gh CLI for authentication" | | git config --global credential.helper "!gh auth git-credential" | | fi | | | | | log "Creating branch: $BRANCH_NAME" | | | | | log "Cleaning up all claude-bot branch references" | | git branch -D $(git branch | grep "claude-bot" | xargs) 2>/dev/null || true | | git branch -d -r $(git branch -r | grep "origin/claude-bot" | xargs) 2>/dev/null || true | | rm -rf ".git/refs/remotes/origin/claude-bot" 2>/dev/null || true | | rm -f ".git/refs/remotes/origin/claude-bot"* 2>/dev/null || true | | find .git -name "*.lock" -delete 2>/dev/null || true | | | | | mkdir -p .git/logs/refs/heads .git/refs/remotes/origin | | chmod -R 755 .git/logs .git/refs 2>/dev/null || true | | chown -R $(whoami):$(whoami) .git/logs .git/refs 2>/dev/null || true | | | | | git checkout HEAD~0 2>/dev/null || true | | | | | log "Fetching updates from origin" | | git fetch origin || { | | log "Error: Could not fetch from origin. Check GitHub authentication." | | add_issue_comment "❌ Error: Could not fetch from GitHub repository. Please check authentication setup." | | exit 1 | | } | | | | | git checkout "$DEFAULT_BRANCH" || { | | log "Error: Could not switch to default branch $DEFAULT_BRANCH" | | add_issue_comment "❌ Error: Could not switch to default branch `$DEFAULT_BRANCH`." | | exit 1 | | } | | | | git checkout -b "$BRANCH_NAME" || { | | log "Error: Could not create branch $BRANCH_NAME" | | add_issue_comment "❌ Error: Could not create branch `$BRANCH_NAME`. Please check for permission issues." | | exit 1 | | } | | | | | EXECUTION_COMMENT="🚀 Starting work on branch `$BRANCH_NAME` | | | | I'm now working on your request locally with Claude Code. I'll implement the changes and run tests before creating a pull request. | | | | Current status: Analyzing request and implementing changes..." | | | | add_issue_comment "$EXECUTION_COMMENT" | | | | | setup_node_env | | | | | CLAUDE_PROMPT_FILE="/tmp/claude_issue_${ISSUE_NUMBER}_prompt.txt" | | cat > "$CLAUDE_PROMPT_FILE" << EOF | | You are working on GitHub issue #$ISSUE_NUMBER: "$ISSUE_TITLE" within this repository. | | | | REQUEST: $ISSUE_COMMAND | | | | I need you to implement this request now. Here's what you should do: | | | |

  1. Read the project structure and understand the codebase | |
  2. Implement the specific request above | |
  3. Follow existing patterns and conventions | |
  4. Create or modify files as needed | |
  5. Do not create placeholder files - implement actual functionality | | | | The current branch is: $BRANCH_NAME | | | | Start by exploring the codebase and then implement the request completely. | | EOF | | | | log "Launching Claude Code with issue prompt..." | | | | | export CLAUDE_PROMPT_FILE="$CLAUDE_PROMPT_FILE" | | export CLAUDE_AUTOMODE="true" | | export CI="true" | | export ANTHROPIC_AUTO_APPROVE="true" | | export CLAUDE_NON_INTERACTIVE="true" | | | | | log "Executing Claude Code in automated mode..." | | CLAUDE_EXIT_CODE=0 | | | | | log "Using Claude Code --print for text generation..." | | timeout 960 claude --print --dangerously-skip-permissions < "$CLAUDE_PROMPT_FILE" > "/tmp/claude_output_${ISSUE_NUMBER}.txt" 2>&1 || CLAUDE_EXIT_CODE=$? | | | | | if [ $CLAUDE_EXIT_CODE -ne 0 ]; then | | log "Text generation failed, trying interactive approach with extended timeout..." | | CLAUDE_EXIT_CODE=0 | | | | | timeout 1920 bash -c " | | { | | cat '$CLAUDE_PROMPT_FILE' | | echo '' | | echo 'Please complete this task and implement the changes needed.' | | echo '' | | | sleep 160 | | echo 'exit' | | } | claude --dangerously-skip-permissions | | " || CLAUDE_EXIT_CODE=$? | | fi | | | | | if [ -s "/tmp/claude_output_${ISSUE_NUMBER}.txt" ]; then | | log "Claude Code --print generated output, creating response file" | | | | | echo "# Claude Code Response for Issue #$ISSUE_NUMBER" > "CLAUDE_RESPONSE_${ISSUE_NUMBER}.md" | | echo "" >> "CLAUDE_RESPONSE_${ISSUE_NUMBER}.md" | | echo "Original Request: $ISSUE_COMMAND" >> "CLAUDE_RESPONSE_${ISSUE_NUMBER}.md" | | echo "" >> "CLAUDE_RESPONSE_${ISSUE_NUMBER}.md" | | echo "Generated Response:" >> "CLAUDE_RESPONSE_${ISSUE_NUMBER}.md" | | echo "" >> "CLAUDE_RESPONSE_${ISSUE_NUMBER}.md" | | cat "/tmp/claude_output_${ISSUE_NUMBER}.txt" >> "CLAUDE_RESPONSE_${ISSUE_NUMBER}.md" | | | | git add "CLAUDE_RESPONSE_${ISSUE_NUMBER}.md" | | | | | rm -f "/tmp/claude_output_${ISSUE_NUMBER}.txt" | | | | | CLAUDE_EXIT_CODE=0 | | | | elif [ $CLAUDE_EXIT_CODE -ne 0 ]; then | | log "Claude Code execution failed with exit code: $CLAUDE_EXIT_CODE" | | | | | if [ $CLAUDE_EXIT_CODE -eq 124 ]; then | | FAILURE_REASON="Claude Code execution timed out" | | elif [ $CLAUDE_EXIT_CODE -eq 1 ]; then | | FAILURE_REASON="Claude Code encountered an error during execution" | | else | | FAILURE_REASON="Claude Code failed with exit code $CLAUDE_EXIT_CODE" | | fi | | | | | echo "# Implementation Status for Issue #$ISSUE_NUMBER" > "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | echo "" >> "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | echo "Original Request: $ISSUE_COMMAND" >> "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | echo "" >> "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | echo "Status: $FAILURE_REASON" >> "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | echo "Timestamp: $(date)" >> "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | echo "Branch: `$BRANCH_NAME`" >> "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | echo "" >> "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | echo "Next Steps:" >> "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | echo "- Check the logs in `$LOG_FILE`" >> "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | echo "- Verify Claude Code is properly installed and configured" >> "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | echo "- Consider manual implementation or re-running with different parameters" >> "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | | | git add "IMPLEMENTATION_ISSUE_${ISSUE_NUMBER}.md" | | | | | add_issue_comment "⚠️ Claude Code Execution Failed | | | | $FAILURE_REASON | | | | I've created a status file on branch `$BRANCH_NAME` with details. Please check the logs or try manual implementation." | | | | | rm -f "/tmp/claude_output_${ISSUE_NUMBER}.txt" | | fi | | | | | rm -f "$CLAUDE_PROMPT_FILE" | | | | | log "Checking for changes..." | | if git diff --quiet && git diff --staged --quiet; then | | log "No changes were made by Claude Code" | | | | FINAL_COMMENT="⚠️ Implementation Incomplete | | | | I created a branch and ran Claude Code, but no changes were generated. The request was: | | | |

$ISSUE_COMMAND | | | | This might mean: | |

  • The request needs more specific details | |
  • Claude Code encountered an issue during execution | |
  • Manual implementation is required | | | | Please check the branch `$BRANCH_NAME` and provide more details if needed, or implement the changes manually." | | | | else | | log "Changes detected, committing and creating PR..." | | | | | git add -A | | | | | git commit -m "Implement #$ISSUE_NUMBER: $ISSUE_TITLE | | | | $ISSUE_COMMAND | | | | 🤖 Implemented locally with Claude Code" || { | | log "Error: Could not commit changes" | | add_issue_comment "❌ Error: Could not commit changes to branch `$BRANCH_NAME`." | | exit 1 | | } | | | | | log "Pushing branch to origin" | | git push origin "$BRANCH_NAME" || { | | log "Error: Could not push branch $BRANCH_NAME" | | add_issue_comment "❌ Error: Could not push branch `$BRANCH_NAME` to GitHub. Please check permissions." | | exit 1 | | } | | | | | log "Creating pull request" | | PR_URL=$(gh pr create \ | | --repo "$REPO" \ | | --title "Implement #$ISSUE_NUMBER: $ISSUE_TITLE" \ | | --body "Fixes #$ISSUE_NUMBER | | | | Original Request: $ISSUE_COMMAND | | | | Implementation: This PR was automatically generated by Claude Code running locally in response to the GitHub issue. | | | | 🤖 Implemented locally with Claude Code" \ | | --base "$DEFAULT_BRANCH" \ | | --head "$BRANCH_NAME" 2>&1) || { | | log "Error creating pull request: $PR_URL" | | add_issue_comment "❌ Error: Could not create pull request. Branch `$BRANCH_NAME` has been pushed with changes." | | exit 1 | | } | | | | | if [ -f "CLAUDE_RESPONSE_${ISSUE_NUMBER}.md" ]; then | | log "Removing Claude response file after successful PR creation" | | git rm "CLAUDE_RESPONSE_${ISSUE_NUMBER}.md" | | git commit -m "Clean up Claude response file | | | | 🤖 Automated cleanup after PR creation" || { | | log "Warning: Could not remove Claude response file" | | } | | | | | git push origin "$BRANCH_NAME" || { | | log "Warning: Could not push cleanup commit" | | } | | fi | | | | FINAL_COMMENT="✅ Implementation Complete! | | | | I've successfully implemented the requested changes using Claude Code and created a pull request: | | | | Pull Request: $PR_URL | | Branch: `$BRANCH_NAME` | | | | The implementation has been completed locally and is ready for review. Please check the PR for details on what was implemented." | | fi | | | | add_issue_comment "$FINAL_COMMENT" | | log "Issue #$ISSUE_NUMBER processing completed successfully" | | | | exit 0 |
── more in #developer-tools 4 stories · sorted by recency
── more on @claude code 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/example-of-claude-co…] indexed:0 read:12min 2026-08-28 ·