6 min read • Guide 326 of 877
Automating Branch Management
Manual branch management is error-prone and time-consuming. Automated branch workflows ensure consistent naming, clean up stale branches, and enforce team standards. This guide covers practical automation strategies for branch management.
Branch Automation Types
| Automation | Benefit | Effort |
|---|---|---|
| Naming validation | Consistency | Low |
| Auto-delete merged | Clean repo | Low |
| Stale cleanup | Reduced clutter | Medium |
| Protection rules | Quality gates | Low |
| CI per branch type | Right tests | Medium |
Branch Naming
Enforcing Conventions
BRANCH NAMING AUTOMATION
════════════════════════
NAMING PATTERN:
─────────────────────────────────────
Standard format:
├── type/ticket-description
├── Examples:
│ ├── feature/AUTH-123-login-flow
│ ├── bugfix/BUG-456-null-pointer
│ ├── hotfix/PROD-789-payment-fix
│ └── chore/DEP-001-update-deps
└── Consistent, parseable
VALIDATION OPTIONS:
─────────────────────────────────────
1. Pre-commit hook:
#!/bin/bash
branch=$(git rev-parse --abbrev-ref HEAD)
pattern="^(feature|bugfix|hotfix|chore)\/[A-Z]+-[0-9]+-"
if [[ ! $branch =~ $pattern ]]; then
echo "Invalid branch name: $branch"
exit 1
fi
2. CI check:
- name: Validate branch name
run: |
if [[ ! "$GITHUB_HEAD_REF" =~ ^(feature|bugfix|hotfix)/ ]]; then
echo "Invalid branch name"
exit 1
fi
3. Pre-receive hook (server-side):
├── Blocks invalid branches at push
└── Strongest enforcement
LINK TO TASKS:
─────────────────────────────────────
Extract ticket from branch:
├── Parse branch name
├── Link PR to issue automatically
├── Update task status
├── Close task on merge
└── Full traceability
Auto-Cleanup
Managing Branch Lifecycle
BRANCH CLEANUP AUTOMATION
═════════════════════════
AUTO-DELETE ON MERGE:
─────────────────────────────────────
GitHub setting:
├── Settings → General
├── "Automatically delete head branches"
├── Enable ✓
├── Branch deleted when PR merged
├── No manual cleanup
└── Clean repository
GitLab:
├── Settings → Repository
├── "Enable auto-delete merged branches"
└── Same behavior
STALE BRANCH CLEANUP:
─────────────────────────────────────
Script to find stale branches:
# Find branches older than 30 days
for branch in $(git branch -r --merged | grep -v main); do
last_commit=$(git log -1 --format=%ci "$branch")
days_old=$(( ($(date +%s) - $(date -d "$last_commit" +%s)) / 86400 ))
if [ $days_old -gt 30 ]; then
echo "Stale: $branch ($days_old days)"
fi
done
SCHEDULED CLEANUP:
─────────────────────────────────────
GitHub Action:
name: Branch Cleanup
on:
schedule:
- cron: '0 0 * * 0' # Weekly
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Delete stale branches
run: |
# Delete merged branches older than 14 days
for branch in $(git branch -r --merged origin/main); do
# Skip protected branches
if [[ ! "$branch" =~ (main|develop|release) ]]; then
git push origin --delete "${branch#origin/}"
fi
done
Branch Protection
Automated Quality Gates
BRANCH PROTECTION RULES
═══════════════════════
GITHUB PROTECTION SETTINGS:
─────────────────────────────────────
For main branch:
├── Require pull request before merging ✓
├── Require approvals: 1-2 ✓
├── Dismiss stale reviews ✓
├── Require status checks to pass ✓
│ ├── CI build
│ ├── Tests
│ └── Lint
├── Require branches to be up to date ✓
├── Require signed commits (optional)
├── Restrict pushes ✓
└── No force pushes ✓
RULESETS (NEWER):
─────────────────────────────────────
GitHub Rulesets:
├── Apply to multiple branches
├── Pattern matching (release/*)
├── Bypass permissions
├── More granular control
└── Organization-wide
BENEFITS:
─────────────────────────────────────
├── Consistent quality
├── No accidental pushes to main
├── Reviews enforced
├── Tests must pass
├── Team alignment
└── Automated enforcement
CI Per Branch Type
Conditional Workflows
CONDITIONAL CI PIPELINES
════════════════════════
BRANCH-BASED CI:
─────────────────────────────────────
Different pipelines per branch:
on:
push:
branches:
- main
- 'release/**'
- 'feature/**'
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
# Only on main
deploy-staging:
if: github.ref == 'refs/heads/main'
needs: test
runs-on: ubuntu-latest
steps:
- run: deploy-to-staging
# Only on release branches
deploy-production:
if: startsWith(github.ref, 'refs/heads/release/')
needs: test
runs-on: ubuntu-latest
steps:
- run: deploy-to-prod
FEATURE BRANCH STRATEGY:
─────────────────────────────────────
Feature branches:
├── Run: lint, unit tests
├── Skip: integration tests, deploy
├── Fast feedback
└── Lower resource usage
Main branch:
├── Run: all tests
├── Run: security scan
├── Deploy: staging
└── Full validation
Release branches:
├── Run: all tests + smoke
├── Deploy: production
├── Tag release
└── Full production path
Notifications
Awareness Automation
BRANCH NOTIFICATIONS
════════════════════
LONG-LIVED BRANCH ALERTS:
─────────────────────────────────────
Alert when branch is too old:
- name: Check branch age
run: |
branch="${{ github.head_ref }}"
created=$(gh pr view ${{ github.event.pull_request.number }} \
--json createdAt -q '.createdAt')
days_old=$(( ($(date +%s) - $(date -d "$created" +%s)) / 86400 ))
if [ $days_old -gt 7 ]; then
gh pr comment ${{ github.event.pull_request.number }} \
--body "⚠️ This branch is $days_old days old. Consider merging or splitting."
fi
MERGE CONFLICT DETECTION:
─────────────────────────────────────
Check for conflicts:
├── Automated check against main
├── Alert if conflicts detected
├── PR labels for conflict status
├── Slack notification
└── Early conflict resolution
BRANCH SYNC REMINDERS:
─────────────────────────────────────
├── Notify when behind main
├── Suggest rebase/merge
├── Prevent large drift
└── Keep branches current
GitScrum Integration
Branch-Task Connection
GITSCRUM BRANCH FEATURES
════════════════════════
AUTOMATIC LINKING:
─────────────────────────────────────
Branch naming includes task ID:
├── feature/GS-123-user-auth
├── GitScrum detects GS-123
├── PR linked to task
├── Activity visible on task
└── Full traceability
STATUS UPDATES:
─────────────────────────────────────
├── Branch created → Task "In Progress"
├── PR opened → Task "In Review"
├── PR merged → Task "Done"
├── Automatic status flow
└── No manual updates needed
VISIBILITY:
─────────────────────────────────────
On task card:
├── See active branches
├── See PR status
├── See merge status
├── Development context
└── Complete picture
Best Practices
For Branch Automation
- Enforce naming — Consistent, parseable patterns
- Auto-delete merged — Clean repository
- Protect main — Quality gates
- Link to tasks — Full traceability
- Conditional CI — Right tests for right branches
Anti-Patterns
BRANCH AUTOMATION MISTAKES:
✗ No branch protection on main
✗ Manual cleanup only
✗ Inconsistent naming
✗ Long-lived branches (weeks)
✗ Same CI for all branches
✗ No task linkage
✗ Branches never cleaned up
✗ Force push allowed on main