name: git-multibranch description: Guidance for setting up Git-based multi-branch deployment systems with web servers. This skill applies when configuring Git repositories with post-receive hooks that deploy different branches to different directories, typically served by Nginx or Apache. Use for tasks involving SSH-accessible Git servers, branch-specific deployments, and web server configuration.
Git Multi-Branch Deployment
Overview
This skill provides guidance for configuring Git repositories that automatically deploy content from different branches to different web-accessible directories. The typical setup involves a bare Git repository with post-receive hooks that check out branch contents to specific deployment directories served by a web server.
Core Components
A multi-branch deployment system requires four interconnected components:
- SSH Server - Enables remote Git operations
- Bare Git Repository - Receives pushes and triggers deployment hooks
- Post-Receive Hook - Deploys branch contents to appropriate directories
- Web Server - Serves deployed content from branch-specific directories
Approach Strategy
Phase 1: SSH Configuration
Before configuring Git, ensure SSH access is properly configured:
- Verify SSH service is running and accessible
- Check authentication settings:
PasswordAuthentication,PermitRootLogin, and alsoUsePAM,KbdInteractiveAuthentication - Create the Git user account with appropriate shell access
- Test SSH connectivity before proceeding to Git setup
Critical Check: After any SSH configuration changes, restart the SSH service and verify connectivity with a test login.
Phase 2: Git Repository Setup
Create a bare repository that will receive pushes:
# Create as the git user or with proper ownership
git init --bare /path/to/repo.git
Key considerations:
- The repository must be owned by the Git user
- The repository starts empty - handle first-push scenarios in the hook
- Set appropriate permissions on the repository directory
Phase 3: Deployment Directory Setup
Create and configure deployment directories before writing the hook:
mkdir -p /var/www/main /var/www/dev
chown git:git /var/www/main /var/www/dev
Permission Verification: The post-receive hook runs as the Git user. Verify the Git user has write permissions to all deployment directories before testing.
Phase 4: Post-Receive Hook Implementation
The post-receive hook deploys branch contents on each push. See references/post_receive_hook.md for implementation details and edge case handling.
Key hook requirements:
- Parse branch name from stdin (format:
oldrev newrev refname) - Handle initial push when branches don't exist yet
- Deploy to correct directory based on branch name
- Handle the
refs/heads/prefix in refnames
Phase 5: Web Server Configuration
Configure the web server to serve content from deployment directories. Each branch maps to a specific location path or virtual host.
Verification Strategy
Test from Clean State
Critical: Always test from the exact state that evaluation will use:
- Start with a fresh clone of an empty repository
- Make initial commits locally
- Push to the server
- Verify deployment directories contain expected content
Verification Commands
After each deployment phase, verify:
# Check SSH connectivity
ssh git@localhost 'echo connected'
# Verify repository permissions
ls -la /path/to/repo.git
# Check hook is executable
ls -la /path/to/repo.git/hooks/post-receive
# Verify deployment directory permissions
ls -la /var/www/
# Test web server response
curl -s http://localhost/main/
curl -s http://localhost/dev/
Clean State Testing Protocol
After initial setup testing, reset to clean state before final verification:
- Remove all content from deployment directories
- Delete any test branches in the repository
- Perform a fresh clone and push sequence
- This ensures the setup handles first-push scenarios correctly
Common Pitfalls
SSH Configuration Incomplete
Problem: Changing PasswordAuthentication alone may not enable password auth.
Solution: Check all related settings: UsePAM, KbdInteractiveAuthentication, ChallengeResponseAuthentication. Restart SSH service after changes.
Post-Receive Hook Edge Cases
Problem: Hook fails on first push when target branch doesn't exist.
Solution: The hook must handle both:
- First push to a new branch (branch doesn't exist yet)
- Subsequent pushes to existing branches
See references/post_receive_hook.md for handling strategies.
Testing Pollutes Repository State
Problem: Test commits and pushes leave the repository in a non-empty state, making subsequent tests unrepresentative.
Solution:
- Test from a clean state matching evaluation conditions
- Avoid force-pushing as a workaround - this masks first-push issues
- Reset deployment directories and repository state between test iterations
Git User Permission Issues
Problem: Post-receive hook runs as Git user but cannot write to deployment directories.
Solution:
- Verify ownership:
chown git:git /var/www/main /var/www/dev - Check parent directory permissions
- Test hook execution manually as the Git user
Host Key Verification Overhead
Problem: Using both manual host key addition and StrictHostKeyChecking=no is redundant.
Solution: Choose one approach:
- Add host key to known_hosts once, then rely on it
- OR use
StrictHostKeyChecking=noconsistently (less secure but simpler for local testing)
Deployment Methods
Problem: Unclear which method to use for deploying branch content.
Options:
git checkout -f- Simple, overwrites working treegit archive | tar- Creates clean export, no .git filesgit worktree- Maintains multiple checkouts
Choose based on requirements. Document the rationale for the chosen approach.
Edge Cases to Handle
- First push scenario: When pushing to a branch that doesn't exist on the server yet
- Empty repository: The very first push when no branches exist at all
- Branch deletion: Decide whether to clean up deployment directories when branches are deleted
- Non-existent deployment directories: Handle gracefully if directories don't exist during hook execution
- Concurrent pushes: Consider race conditions if multiple pushes happen simultaneously
Resources
references/
post_receive_hook.md- Detailed post-receive hook implementation with edge case handling