Back to list
laurigates

git-branch-pr-workflow

by laurigates

Claude Code plugins for development workflows

2🍴 0📅 Jan 24, 2026

SKILL.md


model: haiku created: 2025-12-16 modified: 2026-01-24 reviewed: 2025-12-16 name: git-branch-pr-workflow description: | Branch management, pull request workflows, and GitHub integration. Main-branch development pattern (push main to remote feature branches), modern Git commands (switch, restore), branch naming conventions, linear history, and GitHub MCP tools. Use when user mentions creating branches, opening PRs, git switch, git restore, feature branches, pull requests, or GitHub PR workflows. allowed-tools: Bash, Read, mcp__github__create_pull_request, mcp__github__list_pull_requests, mcp__github__update_pull_request

Git Branch PR Workflow

Expert guidance for branch management, pull request workflows, and GitHub integration using modern Git commands and linear history practices.

Core Expertise

  • Main-Branch Development: Work on main locally, push to remote feature branches for PRs
  • Modern Git Commands: Use git switch and git restore instead of checkout
  • Branch Naming: Structured conventions (feat/, fix/, chore/, hotfix/)
  • Linear History: Rebase-first workflow, squash merging, clean history
  • GitHub MCP Integration: Use mcp__github__* tools instead of gh CLI

Main-Branch Development (Preferred)

Develop directly on main, push to remote feature branches for PRs. This eliminates local branch management overhead.

Basic Workflow

# All work happens on main
git switch main
git pull origin main

# Make changes, commit on main
git add file.ts
git commit -m "feat(auth): add OAuth2 support"

# Push to remote feature branch (creates PR target)
git push origin main:feat/auth-oauth2

# Create PR using GitHub MCP (head: feat/auth-oauth2, base: main)

Multi-PR Workflow (Sequential Commits)

When you have commits for multiple PRs on main, push specific commit ranges to different remote branches:

# Commits on main:
# abc1234 feat(auth): add OAuth2 support       <- PR #1
# def5678 feat(auth): add token refresh        <- PR #1
# ghi9012 fix(api): handle timeout edge case   <- PR #2

# Push first 2 commits to auth feature branch
git push origin abc1234^..def5678:feat/auth-oauth2

# Push remaining commit to fix branch
git push origin ghi9012^..ghi9012:fix/api-timeout

# Alternative: push from a specific commit to HEAD
git push origin def5678..HEAD:fix/api-timeout

Commit range patterns:

  • git push origin <start>^..<end>:<remote-branch> - Push commit range (inclusive)
  • git push origin <commit>..<commit>:<remote-branch> - Push range (exclusive start)
  • git push origin <commit>..HEAD:<remote-branch> - Push from commit to current HEAD
  • git push origin main:<remote-branch> - Push entire main to remote branch

Benefits

  • No local branch juggling - Always on main
  • Always on latest main - No branch drift
  • Clean local state - No stale branches to clean up
  • Remote branches are ephemeral - Deleted after PR merge
  • Simpler mental model - One local branch, many remote targets

Modern Git Commands (2025)

Switch vs Checkout

Modern Git uses specialized commands instead of multi-purpose git checkout:

# Branch switching - NEW WAY (Git 2.23+)
git switch feature-branch          # vs git checkout feature-branch
git switch -c new-feature          # vs git checkout -b new-feature
git switch -                       # vs git checkout -

# Creating branches with tracking
git switch -c feature --track origin/feature
git switch -C force-recreate-branch

Restore vs Reset/Checkout

File restoration is now handled by git restore:

# Unstaging files - NEW WAY
git restore --staged file.txt      # vs git reset HEAD file.txt
git restore --staged .             # vs git reset HEAD .

# Discarding changes - NEW WAY
git restore file.txt               # vs git checkout -- file.txt
git restore .                      # vs git checkout -- .

# Restore from specific commit
git restore --source=HEAD~2 file.txt    # vs git checkout HEAD~2 -- file.txt
git restore --source=main --staged .    # vs git reset main .

Command Migration Guide

Legacy CommandModern AlternativePurpose
git checkout branchgit switch branchSwitch branches
git checkout -b newgit switch -c newCreate & switch
git checkout -- filegit restore fileDiscard changes
git reset HEAD filegit restore --staged fileUnstage file
git checkout HEAD~1 -- filegit restore --source=HEAD~1 fileRestore from commit

Branch Naming Conventions

Structured Branch Names

# Feature development
git switch -c feat/payment-integration
git switch -c feat/user-dashboard
git switch -c feat/api-v2

# Bug fixes
git switch -c fix/login-validation
git switch -c fix/memory-leak-auth
git switch -c fix/broken-tests

# Maintenance and refactoring
git switch -c chore/update-dependencies
git switch -c chore/cleanup-tests
git switch -c refactor/auth-service

# Hotfixes (for production)
git switch -c hotfix/security-patch
git switch -c hotfix/critical-bug-fix

Branch Naming Format

{type}/{description}-{YYYYMMDD} (date optional but recommended for clarity)

Types:

  • feat/ - New features
  • fix/ - Bug fixes
  • chore/ - Maintenance, dependencies, linter fixes
  • docs/ - Documentation changes
  • refactor/ - Code restructuring
  • hotfix/ - Emergency production fixes

Linear History Workflow

Trunk-Based Development

Preferred: Main-branch development (see above) - no local feature branches needed.

Alternative: Local feature branches for complex multi-day work:

# Feature branch lifecycle (max 2 days)
git switch main
git pull origin main
git switch -c feat/user-auth

# Daily rebase to stay current
git switch main && git pull
git switch feat/user-auth
git rebase main

# Interactive cleanup before PR
git rebase -i main
# Squash, fixup, reword commits for clean history

# Push and create PR
git push -u origin feat/user-auth

Use local branches only when:

  • Multi-day complex features requiring isolation
  • Experimental work that might be abandoned
  • Need to switch contexts frequently between unrelated work

Squash Merge Strategy

Maintain linear main branch history:

# Manual squash merge
git switch main
git merge --squash feat/user-auth
git commit -m "feat: add user authentication system

- Implement JWT token validation
- Add login/logout endpoints
- Create user session management

Closes #123"

Interactive Rebase Workflow

Clean up commits before sharing:

# Rebase last 3 commits
git rebase -i HEAD~3

# Common rebase commands:
# pick   = use commit as-is
# squash = combine with previous commit
# fixup  = squash without editing message
# reword = change commit message
# drop   = remove commit entirely

# Example rebase todo list:
pick a1b2c3d feat: add login form
fixup d4e5f6g fix typo in login form
squash g7h8i9j add form validation
reword j1k2l3m implement JWT tokens

Advanced Rebase Patterns

Reapply Cherry-Picks (--reapply-cherry-picks)

Problem: After merging trunk into your feature branch multiple times (via git merge main), you want to rebase onto fresh trunk. Default rebase behavior may create conflicts or duplicate commits.

Solution: --reapply-cherry-picks detects commits that were already applied via merge and drops the merge commits, keeping only your original changes.

# Scenario: You merged main into your branch a few times
git log --oneline
# abc123 Merge branch 'main' into feat/auth
# def456 feat: add login endpoint
# ghi789 Merge branch 'main' into feat/auth
# jkl012 feat: add user validation

# Rebase onto fresh main, dropping merge commits
git fetch origin
git rebase --reapply-cherry-picks origin/main

# Result: Clean linear history with just your feature commits
# jkl012 feat: add user validation
# def456 feat: add login endpoint

When to use:

  • After merging trunk into your branch to resolve conflicts
  • Converting a merge-heavy branch to linear history
  • Before creating a PR to clean up integration merges

Update Refs (--update-refs)

Problem: With stacked PRs (PR chains), rebasing one branch requires manually rebasing all dependent branches. Moving commits between branches in the stack is painful.

Solution: --update-refs automatically updates all branches in the chain when you rebase. Combined with interactive rebase, you can reorganize commits across your entire PR stack in one operation.

# Scenario: Stacked PRs
# main <- feat/auth-base <- feat/auth-oauth <- feat/auth-refresh

# Rebase the entire stack onto updated main
git switch feat/auth-refresh
git rebase --update-refs main

# All three branches (auth-base, auth-oauth, auth-refresh) are updated
# No manual rebasing of each branch needed

# Interactive rebase to move commits between branches
git rebase -i --update-refs main

# In the editor, move commit lines around to reorganize the stack:
# pick abc123 feat: add auth base      # Will update feat/auth-base
# pick def456 feat: add OAuth support  # Will update feat/auth-oauth
# pick ghi789 feat: add token refresh  # Will update feat/auth-refresh

Stacked PR workflow with update-refs:

# Create PR stack
git switch main
git pull origin main

# First PR: Base authentication
git switch -c feat/auth-base
# ... make commits ...
git push -u origin feat/auth-base

# Second PR: OAuth (depends on first)
git switch -c feat/auth-oauth
# ... make commits ...
git push -u origin feat/auth-oauth

# Third PR: Token refresh (depends on second)
git switch -c feat/auth-refresh
# ... make commits ...
git push -u origin feat/auth-refresh

# Main updated - rebase entire stack
git fetch origin
git switch feat/auth-refresh
git rebase --update-refs origin/main

# All branches rebased in one command
git push --force-with-lease origin feat/auth-base
git push --force-with-lease origin feat/auth-oauth
git push --force-with-lease origin feat/auth-refresh

When to use:

  • Managing stacked PRs (PR chains with dependencies)
  • Reorganizing commits across multiple branches
  • Keeping branch hierarchies in sync during rebase

Explicit Base Control (--onto)

Problem: Git's automatic base detection can be ambiguous or incorrect. You want precise control over where commits are rebased.

Solution: --onto explicitly specifies the new base, bypassing Git's base detection heuristics.

# Syntax: git rebase --onto <newbase> <upstream> <branch>
# Translates to: Take commits from <upstream>..<branch> and put them onto <newbase>

# Common pattern: Rebase last N commits onto a specific branch
git rebase --onto origin/develop HEAD~5
# Takes your last 5 commits and puts them on top of origin/develop
# Equivalent to: git rebase --onto origin/develop HEAD~5 HEAD

# Example: Move feature commits from old base to new base
# Scenario: You branched from develop, but should have branched from main
git switch feat/payment
git rebase --onto main develop feat/payment
# Takes commits from develop..feat/payment and moves them onto main

# Example: Rebase specific commit range
# Move commits from abc123 to def456 onto main
git rebase --onto main abc123^ def456
# The ^ includes abc123 in the range

# Example: Extract commits to new branch
# You have commits on feat/auth that should be on separate branch
git switch -c feat/auth-ui feat/auth  # Create new branch
git rebase --onto main feat/auth~3 feat/auth-ui
# Takes last 3 commits from feat/auth and puts them on main

Common --onto patterns:

PatternCommandUse Case
Last N commits on trunkgit rebase --onto origin/main HEAD~NRebase recent work onto updated trunk
Change branch basegit rebase --onto <new-base> <old-base>Fix branch created from wrong base
Extract commit rangegit rebase --onto <target> <start>^ <end>Move specific commits to new location
Interactive with ontogit rebase -i --onto <base> HEAD~NClean up and rebase last N commits

When to use:

  • When you don't trust Git's automatic base detection
  • Rebasing a specific number of recent commits (HEAD~N pattern)
  • Changing the base of a branch after it was created
  • Extracting a subset of commits to a new location

Combining Advanced Flags

These flags work together for powerful workflows:

# Rebase stacked PRs with cherry-pick detection
git rebase --reapply-cherry-picks --update-refs origin/main

# Interactive rebase with explicit base and branch updates
git rebase -i --onto origin/main HEAD~10 --update-refs

# Clean up merged history and update dependent branches
git rebase --reapply-cherry-picks --update-refs --onto origin/develop origin/main

GitHub MCP Integration

Use GitHub MCP tools for all GitHub operations:

# Get repository information
mcp__github__get_me()  # Get authenticated user info

# List and create PRs
mcp__github__list_pull_requests(owner="owner", repo="repo")
mcp__github__create_pull_request(
  owner="owner",
  repo="repo",
  title="feat: add authentication",
  head="feat/auth",
  base="main",
  body="## Summary\n- JWT authentication\n- OAuth support\n\nCloses #123"
)

# Update PRs
mcp__github__update_pull_request(
  owner="owner",
  repo="repo",
  pullNumber=42,
  title="Updated title",
  state="open"
)

# List and create issues
mcp__github__list_issues(owner="owner", repo="repo")

Best Practices

Daily Integration Workflow

# Start of day: sync with main
git switch main
git pull origin main
git switch feat/current-work
git rebase main

# End of day: push progress
git add . && git commit -m "wip: daily progress checkpoint"
git push origin feat/current-work

# Before PR: clean up history
git rebase -i main
git push --force-with-lease origin feat/current-work

Conflict Resolution with Rebase

# When rebase conflicts occur
git rebase main
# Fix conflicts in editor
git add resolved-file.txt
git rebase --continue

# If rebase gets messy, abort and merge instead
git rebase --abort
git merge main

Safe Force Pushing

# Always use --force-with-lease to prevent overwriting others' work
git push --force-with-lease origin feat/branch-name

# Never force push to main/shared branches
# Use this alias for safety:
git config alias.pushf 'push --force-with-lease'

Main Branch Protection

Configure branch rules for linear history via GitHub MCP:

# Require linear history (disable merge commits)
# Configure via GitHub settings or MCP tools
# - Require pull request reviews
# - Require status checks to pass
# - Enforce linear history (squash merge only)

Before creating a PR, gather all context in one command:

# Gather PR context (defaults to main as base)
bash "${CLAUDE_PLUGIN_ROOT}/skills/git-branch-pr-workflow/scripts/pr-context.sh"

# Specify different base branch
bash "${CLAUDE_PLUGIN_ROOT}/skills/git-branch-pr-workflow/scripts/pr-context.sh" develop

The script outputs: branch info, remote status, commit range and types, diff stats, issue references found in commits, existing PR detection, and CI check results. Use this output to compose the PR title and body. See scripts/pr-context.sh for details.

Pull Request Workflow

PR Title Format

Use conventional commit format in PR titles:

  • feat: add user authentication
  • fix: resolve login validation bug
  • docs: update API documentation
  • chore: update dependencies

PR Body Template

## Summary
Brief description of changes

## Changes
- Bullet points of key changes
- Link related work

## Testing
How changes were tested

## Issue References
<!-- Use GitHub autolink format - ALWAYS include relevant issues -->
Closes #123
<!-- Or use: Fixes #N, Resolves #N, Refs #N -->

Issue Reference Guidelines:

  • Use Closes #N / Fixes #N / Resolves #N to auto-close issues on merge
  • Use Refs #N / Related to #N for context without auto-closing
  • Cross-repo: Fixes owner/repo#N
  • Multiple: Fixes #1, fixes #2, fixes #3 (repeat keyword)

PR Creation Best Practices

  • One focus per PR - Single logical change
  • Small PRs - Easier to review (< 400 lines preferred)
  • ALWAYS link issues - Use GitHub autolink format for traceability:
    • Closing keywords: Closes #123, Fixes #456, Resolves #789
    • Reference without closing: Refs #234, Related to #567
    • Cross-repository: Fixes owner/repo#123
    • Multiple issues: Fixes #1, fixes #2 (repeat keyword for each)
  • Add labels - Use GitHub labels for categorization
  • Request reviewers - Tag specific reviewers when needed

Troubleshooting

Branch Diverged from Remote

# Pull with rebase to maintain linear history
git pull --rebase origin feat/branch-name

# Or reset if local changes can be discarded
git fetch origin
git reset --hard origin/feat/branch-name

Committed to Main (Expected Workflow)

With main-branch development, committing to main is the expected workflow:

# Commits are already on main - just push to remote feature branch
git push origin main:feat/new-feature

# Create PR using GitHub MCP (head: feat/new-feature, base: main)

# After PR is merged, local main is behind - sync it:
git pull origin main  # Fast-forward merge handles this cleanly

Why this works:

  • Commits exist on both local main and remote feature branch
  • When PR merges to remote main, your local main is behind by same commits
  • git pull recognizes the commits and fast-forwards cleanly
  • No history rewriting, no data loss, no merge conflicts

Rebase Conflicts Are Too Complex

# Abort rebase and use merge instead
git rebase --abort
git merge main

Safe Operations

Recognizing Normal States

These states are expected during development - proceed confidently:

StateMeaningAction
Unstaged changes after pre-commitFormatters modified filesStage with git add -u and continue
Modified files after running formattersExpected auto-fix behaviorStage before committing
Pre-commit exit code 1Files were modifiedStage modifications, re-run pre-commit
Branch behind remoteRemote has newer commitsPull or rebase as appropriate

Confirmation-Required Commands

Request user confirmation before running destructive commands:

# These require explicit user approval:
git branch -d/-D       # "Delete local branch X?"
git push origin --delete  # "Delete remote branch X?"
git reset --hard       # "Discard uncommitted changes?"
git clean -fd          # "Remove untracked files?"

When State is Unclear

When encountering unexpected state:

  1. Run diagnostic commands (git status, git log --oneline -5)
  2. Report findings clearly
  3. Present options and wait for guidance

Recovery Workflows

Pre-commit Modifies Files

This is normal formatter/linter behavior:

# 1. Check what changed
git status

# 2. Stage modified files
git add -u

# 3. Continue with commit
git commit -m "feat(feature): description"

Push Rejected (Non-Fast-Forward)

Remote has newer commits:

# Option 1: Rebase local changes on top (preferred for linear history)
git pull --rebase origin <branch>

# Option 2: Merge remote changes
git pull origin <branch>

# Option 3: Overwrite remote (your branch only, use cautiously)
git push --force-with-lease

Commit Fails

  1. Read the error message
  2. Common causes:
    • Pre-commit hooks failed → Fix issues and retry
    • No staged changes → Stage files first
    • Empty commit message → Provide message
  3. Fix the underlying issue and retry

Score

Total Score

50/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon