
Git Workflow
- 98 installs
- 14 repo stars
- Updated March 2, 2026
- oakoss/agent-skills
Helps with automation & workflows tasks during AI-assisted development.
About
git-workflow is a Claude Code skill for automation & workflows. It helps solo builders move faster with AI-assisted coding.
- git-workflow
- Automation & Workflows
- AI-coding skill
Git Workflow by the numbers
- 98 all-time installs (skills.sh)
- +5 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #822 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/oakoss/agent-skills --skill git-workflowAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 98 |
|---|---|
| repo stars | ★ 14 |
| Last updated | March 2, 2026 |
| Repository | oakoss/agent-skills ↗ |
What it does
Helps with automation & workflows tasks during AI-assisted development.
Files
Git Workflow
Covers branching strategies, conventional commits, CI/CD automation, repository hygiene, and git internals. GitHub CLI usage is handled by a separate github-cli skill; this skill focuses on git workflow patterns and CI/CD configuration.
Quick Reference
| Area | Key Practice |
|---|---|
| Branching | Trunk-based development with short-lived feature branches |
| Commits | Conventional commits with imperative mood |
| History | Linear history via rebase; squash noisy commits |
| PRs | Small, stacked changes; no mega PRs |
| Main branch | Always deployable; broken main is an emergency |
| CI/CD | Modular GitHub Actions with reusable workflows |
| Merging | Green CI + review required before merge |
| Versioning | Semantic Release or Changesets (never manual) |
| Branches | Max 48 hours lifespan; auto-prune stale/merged |
| Secrets | OIDC Connect in pipelines; never hardcode tokens |
| Signing | Sign commits with SSH or GPG keys for verified authorship |
Branch Naming
| Type | Use For | Example |
|---|---|---|
| feat | New features | feat/add-user-auth |
| fix | Bug fixes | fix/login-redirect |
| chore | Maintenance | chore/update-deps |
| docs | Documentation | docs/api-reference |
| refactor | Code restructuring | refactor/auth-module |
Conventional Commit Types
| Type | Purpose | Version Bump |
|---|---|---|
feat | New features | Minor |
fix | Bug fixes | Patch |
docs | Documentation only | None |
style | Formatting, no logic changes | None |
refactor | Neither fix nor feature | None |
perf | Performance improvements | Patch |
test | Adding or correcting tests | None |
build | Build system or external dependencies | None |
ci | CI configuration changes | None |
chore | Tooling, maintenance, non-src changes | None |
revert | Revert a previous commit | Varies |
Append ! after type/scope for breaking changes (major version bump).
Pre-Merge Checks
All PRs require before merge:
- Lint
- Type check
- Tests
- Security scan
- Review approval (human or automated)
Auto-merge is acceptable for low-risk PRs when pipeline succeeds.
Troubleshooting
| Issue | Resolution |
|---|---|
| Merge conflicts on long-running branch | Rebase onto main frequently; break remaining work into new branch if over 48 hours |
| Broken main branch | Treat as emergency; revert offending commit, then fix forward on a branch |
| Lost commits or data recovery | Use git reflog and object inspection (git cat-file, git fsck) |
| CI pipeline failures | Check reusable workflow versions; verify OIDC permissions |
| Stacked PR conflicts after rebase | Restack entire chain from base; Graphite handles automatically with gt restack |
| Large file accidentally committed | Use git filter-repo to remove from history (not git filter-branch) |
Common Mistakes
| Mistake | Correct Pattern |
|---|---|
| Keeping feature branches alive longer than 48 hours | Merge or rebase daily; break large work into stacked PRs |
| Committing directly to main without branch protection | Enable branch protection rules requiring CI and review |
| Using merge commits that clutter history | Rebase and squash to maintain linear history |
| Hardcoding tokens in GitHub Actions workflows | Use OIDC Connect for authentication in CI/CD pipelines |
| Creating monolithic CI workflows in a single file | Split into reusable workflows and composite actions |
Fix bug as commit message | fix(scope): correct bug description (conventional) |
feat: Added feature (past tense) | feat: add feature (imperative mood, lowercase) |
Using git filter-branch for history rewriting | Use git filter-repo (faster, safer, officially recommended) |
| Pushing to main directly | Create feature branch first |
| Unsigned commits in shared repositories | Configure commit signing with SSH or GPG keys |
Delegation
- Audit repository branch hygiene and stale branches: Use
Exploreagent to list and classify branch age and merge status - Set up CI/CD pipelines with reusable workflows: Use
Taskagent to create modular GitHub Actions configurations - Design branching strategy for a new project: Use
Planagent to evaluate trunk-based vs Git Flow based on team needs
References
- branching-strategies.md -- Git Flow, GitHub Flow, GitLab Flow, One-Flow comparison and selection criteria
- trunk-based-development.md -- Core principles, workflow steps, feature flags, and anti-patterns
- stacked-changes.md -- Stacked PRs concept, manual stacking, Graphite automation, best practices
- conventional-commits.md -- Commit format, types, scopes, breaking changes, and full workflow
- github-actions.md -- Reusable workflows, matrix testing, deployment environments, security
- git-internals.md -- Object model, SHA hashing, index, references, packfiles, garbage collection
- automation-scripts.md -- Branch pruning, semantic release, security scanning, stacked PR helpers
- issue-templates.md -- Bug report, feature request, task, and minimal issue templates
- advanced-operations.md -- Commit signing, interactive rebase, worktrees, bisect, reflog recovery, and --force-with-lease
Advanced Git Operations
Commit Signing
Signing commits proves authorship. SSH keys are preferred: simpler to set up, no extra tooling, and already used for push authentication.
SSH Signing (Preferred)
# Configure git to use SSH for signing
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
# Sign all commits automatically
git config --global commit.gpgsign true
# Verify a signed commit
git verify-commit HEADGitHub requires an allowed-signers file for SSH signature verification:
# Create allowed signers file
echo 'your@email.com namespaces="git" ssh-ed25519 AAAA...' > ~/.ssh/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signersGPG Signing (Legacy)
# List available GPG keys
gpg --list-secret-keys --keyid-format=long
# Configure git to use a specific key
git config --global user.signingkey <KEY_ID>
git config --global commit.gpgsign true
# Export public key to add to GitHub
gpg --armor --export <KEY_ID>Repository-Level Enforcement
# Require signed commits in a pre-receive hook (server-side)
# Or enforce via GitHub branch protection: "Require signed commits"---
Interactive Rebase
Rewrites commit history. Only use on commits that have NOT been pushed to a shared branch.
Basic Usage
# Rebase last N commits interactively
git rebase -i HEAD~3
# Rebase all commits since branching from main
git rebase -i origin/mainCommands in the Rebase Editor
| Command | Effect |
|---|---|
pick | Keep commit as-is |
reword | Keep commit, edit its message |
squash | Meld into previous commit, combine messages |
fixup | Meld into previous commit, discard this message |
drop | Remove commit entirely |
edit | Pause to amend the commit (files or message) |
Common Patterns
Squash work-in-progress commits before merging:
git rebase -i origin/main
# Change 'pick' to 'squash' on all commits after the firstReorder commits (change the order of lines in the editor):
git rebase -i HEAD~4
# Move lines up or down to reorder commitsSplit a commit:
git rebase -i HEAD~2
# Mark the target commit as 'edit'
# When paused:
git reset HEAD^ # unstage the commit
git add file-a.ts
git commit -m 'feat: add component'
git add file-b.ts
git commit -m 'test: add component tests'
git rebase --continueAbort and Recover
# Abort mid-rebase and return to original state
git rebase --abort
# If something went wrong after completing, restore with reflog
git reflog
git reset --hard HEAD@{<n>}---
Worktrees
Work on multiple branches simultaneously without stashing or switching. Each worktree is a separate working directory sharing the same repository.
Basic Usage
# Add a worktree on an existing branch
git worktree add ../hotfix-123 fix/hotfix-123
# Add a worktree and create a new branch
git worktree add -b feat/new-feature ../feat-new-feature main
# List all worktrees
git worktree list
# Remove a worktree (after work is done)
git worktree remove ../hotfix-123Typical Workflow
# Start a long-running feature on main worktree
# Urgent fix arrives — add a second worktree without disturbing current work
git worktree add -b fix/critical-bug ../bug-fix origin/main
cd ../bug-fix
# Fix the bug, commit, push, open PR
git push -u origin fix/critical-bug
# Return to main worktree — original work is untouched
cd ../my-project
# Clean up after PR merges
git worktree remove ../bug-fix
git branch -d fix/critical-bugConstraints
- A branch can only be checked out in one worktree at a time
git stashis per-worktree, not shared- Worktrees share the same
.gitdirectory (hooks, config)
---
Bisect
Binary-search through commit history to find which commit introduced a bug.
Manual Bisect
# Start bisect session
git bisect start
# Mark current commit as bad (has the bug)
git bisect bad
# Mark a known-good commit (before the bug existed)
git bisect good v1.2.0
# Git checks out the midpoint — test it, then mark:
git bisect good # this commit is fine
git bisect bad # this commit has the bug
# Repeat until git reports the first bad commit
# Then end the session
git bisect resetAutomated Bisect
Provide a script that exits 0 for good and non-zero for bad:
git bisect start
git bisect bad HEAD
git bisect good v1.2.0
# Run automated bisect with a test script
git bisect run pnpm test -- --testPathPattern='auth.test.ts'
# Or with a custom script
git bisect run ./scripts/check-regression.sh
git bisect resetBisect Log
# View the bisect decisions made so far
git bisect log
# Replay a saved bisect session
git bisect log > bisect.log
git bisect replay bisect.log---
Reflog
The reflog records every position HEAD and branch tips have been at, including rebases, resets, and amends. Objects remain recoverable until garbage collection runs (default: 90 days for reachable, 30 days for unreachable).
Viewing the Reflog
# Show HEAD reflog
git reflog
# Show reflog for a specific branch
git reflog show feat/my-feature
# Show all reflogs
git reflog --all
# Show with timestamps
git reflog --format='%C(auto)%h %gd %gs (%cr)'Recovery Patterns
Recover commits lost after a hard reset:
git reflog
# Find the SHA before the reset (e.g. HEAD@{2})
git reset --hard HEAD@{2}Recover a deleted branch:
git reflog
# Find the tip SHA of the deleted branch
git checkout -b recovered-branch <sha>Recover a dropped stash:
git fsck --unreachable | grep commit
# Inspect candidates
git show <sha>
# Restore
git stash apply <sha>---
--force-with-lease vs --force
Never use --force on shared branches. It silently overwrites commits pushed by teammates.
# WRONG — overwrites any remote changes blindly
git push --force origin feat/my-feature
# CORRECT — fails if remote has commits not in your local ref
git push --force-with-lease origin feat/my-feature--force-with-lease checks that the remote ref matches your last known state. If a teammate pushed since your last fetch, the push is rejected and you must integrate their changes first.
When Force-Push Is Acceptable
- Your own feature branch (not yet reviewed or merged)
- After interactive rebase to clean up history before PR review
- Never on
main,master, or any shared/protected branch
# Safe pattern: rebase then force-push with lease
git fetch origin
git rebase origin/main
git push --force-with-lease origin feat/my-featureAutomation Scripts
Branch Pruning
Remove merged branches and clean up local caches:
# Prune remote tracking branches
git fetch --prune
# Delete local branches that have been merged to main
git branch --merged main | grep -v "main" | xargs -n 1 git branch -d
# Delete branches merged to current branch
git branch --merged | grep -v "\*" | xargs -n 1 git branch -dStale Branch Cleanup
Find and clean branches older than a threshold:
# List branches sorted by last commit date
git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(refname:short)'
# Find branches with no activity in 30+ days
git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:relative) %(refname:short)' | grep -E "(month|year)"Semantic Release
Automate versioning and changelog generation based on conventional commits:
# Run semantic release (reads commit history, bumps version, publishes)
pnpm dlx semantic-release
# Dry run to preview next version
pnpm dlx semantic-release --dry-runAlternative with Changesets:
# Initialize changesets
pnpm dlx @changesets/cli init
# Add a changeset
pnpm changeset
# Version packages based on changesets
pnpm changeset version
# Publish
pnpm changeset publishSecurity Scanning
Scan for secrets before pushing:
# Scan current directory for leaked secrets
pnpm dlx gitleaks detect --source . --verbose
# Scan git history for secrets
pnpm dlx gitleaks detect --source . --verbose --log-opts="--all"Stacked PR Helpers
# Graphite: Restack all dependent branches
gt restack
# Manual: Rebase a branch onto a new base
git rebase --onto new-base old-base branch-to-moveRepository Maintenance
# Full repository cleanup
git gc --aggressive --prune=now
# Verify repository integrity
git fsck --full
# Show repository size statistics
git count-objects -v -HBranching Strategies
Git Flow
Best for regulated industries, physical hardware, or scheduled releases.
main: Production-ready codedevelop: Integration branch for featuresfeature/*: Long-lived branches for new capabilitiesrelease/*: Preparation for a new production releasehotfix/*: Urgent production fixes
main ──────────────────────────────── production
│ ▲
└── develop ── feature/* ──────────────┘
│ ▲
└── release/* ────────────────────┘
│ ▲
└── hotfix/* ─────────────────────┘GitHub Flow
Best for high-growth SaaS and modern web apps.
- Everything happens on short-lived branches off
main - PRs are used for review and CI validation
- Once merged, the code is deployed immediately
main ──────────────────────────────── always deployable
│ ▲
└── feature-branch ┘ (short-lived, merged via PR)GitLab Flow (Environment-Based)
Best for projects with multiple deployment stages (staging, pre-prod, production).
- Use long-lived branches corresponding to environments
- Code flows through branches via merge requests
main → staging → pre-production → productionOne-Flow (Simplified Git Flow)
Best for teams that need Git Flow's structure but find it too complex.
- Removes the
developbranch - Features and hotfixes all branch off and merge back into
main
Selection Criteria
| Strategy | Speed | Complexity | Reliability | Best For |
|---|---|---|---|---|
| Trunk-Based | Ultra High | Low | High (requires tests) | Small-mid teams, SaaS, CI/CD |
| GitHub Flow | High | Low | High | Web apps, startups |
| Git Flow | Low | High | Very High | Regulated, scheduled releases |
| GitLab Flow | Medium | Medium | High | Multi-environment deployments |
| One-Flow | Medium | Medium | High | Structured but simpler teams |
| Stacked PRs | Ultra High | Moderate | High | Large features, expert teams |
Decision Guide
1. Default: Trunk-based development with feature flags 2. Multiple environments: GitLab Flow 3. Scheduled releases: Git Flow or One-Flow 4. Large features: Stacked PRs on top of trunk-based
Conventional Commits
Format
type(scope): subject
body (optional)
footer (optional)Types
| Type | Description |
|---|---|
feat | New features |
fix | Bug fixes |
docs | Documentation changes |
style | Code style (formatting, no logic changes) |
refactor | Code changes (neither fix nor feature) |
perf | Performance improvements |
test | Adding or correcting tests |
build | Build system or external dependencies |
ci | CI configuration changes |
chore | Tooling, maintenance, non-src changes |
revert | Revert a previous commit |
The spec only mandates feat and fix. The other types are community conventions adopted from the Angular convention and widely used by commitlint.
Scopes
Scopes vary by project. Common patterns:
| Category | Scopes |
|---|---|
| Apps | web, api, mobile |
| Packages | auth, config, database, ui |
| Tooling | deps, ci, build |
Custom scopes are allowed. Scope is optional.
Rules
- Subject: imperative mood, no period, lowercase
- Header max length: 200 characters
- Body: optional, wrap at 72 characters
Examples
# Feature
git commit -m "feat(auth): add password reset flow"
# Bug fix
git commit -m "fix(ui): correct button alignment on mobile"
# Chore
git commit -m "chore(deps): update react to v19"
# With scope
git commit -m "refactor(database): simplify user queries"
# Without scope
git commit -m "docs: update README installation steps"
# Breaking change
git commit -m "feat(api)!: change authentication endpoint response format"Full Workflow
# 1. Create branch from main
git checkout main
git pull
git checkout -b feat/my-feature
# 2. Make changes and commit
git add src/
git commit -m "feat(scope): add feature description"
# 3. Push to remote
git push -u origin feat/my-feature
# 4. Create PR
gh pr create --title "feat(scope): add feature description" --body "..."
# 5. After review, merge
gh pr merge --squashSemantic Versioning Integration
Conventional commits enable automated versioning:
| Commit Type | Version Bump |
|---|---|
fix | Patch (0.0.x) |
feat | Minor (0.x.0) |
feat! / BREAKING CHANGE | Major (x.0.0) |
Tools like Semantic Release and Changesets parse commit messages to determine the next version automatically.
Git Internals
Understanding how Git stores data enables effective debugging and recovery.
The Content-Addressable Store
Git is a persistent map of SHA hash keys to objects:
- Blobs: File contents (just the data, no filename)
- Trees: Directory structures (pointing to blobs and other trees)
- Commits: Snapshots of the tree with metadata (author, message, parent)
# Inspect any object
git cat-file -p <hash>
# Show object type
git cat-file -t <hash>
# Show the tree of a commit
git cat-file -p HEAD^{tree}Object Identification
Git uses SHA-1 hashing by default for collision resistance and content verification. Every object (blob, tree, commit, tag) gets a unique hash. SHA-256 support is available via git init --object-format=sha256 and is expected to become the default in Git 3.0.
# Hash a file to see what Git would name it
git hash-object path/to/file
# Verify repository integrity
git fsck --fullThe Index (Staging Area)
The index is a binary file (.git/index) that prepares the next commit. It serves as the bridge between the working directory and the repository.
# See exactly what is in the index
git ls-files --stage
# Compare working directory to index
git diff
# Compare index to last commit
git diff --cachedReferences and Symbolic Refs
- Heads: Local branches (
refs/heads/) - Remotes: Remote tracking branches (
refs/remotes/) - Tags: Version markers (
refs/tags/) - HEAD: Symbolic ref pointing to the current branch or commit
# Show where HEAD points
git symbolic-ref HEAD
# Show all refs
git show-ref
# Show the reflog (history of HEAD changes)
git reflogData Recovery
# Find lost commits via reflog
git reflog --all
# Find dangling objects (unreachable commits, blobs)
git fsck --unreachable
# Recover a lost commit
git cherry-pick <hash-from-reflog>
# Recover a deleted branch
git checkout -b recovered-branch <hash-from-reflog>Packfiles and Garbage Collection
Git compresses objects into packfiles to save space:
# Run cleanup and optimization
git gc
# Remove unreachable objects
git prune
# Show pack statistics
git count-objects -v
# Verify pack integrity
git verify-pack -v .git/objects/pack/*.idxRepository Size Management
# Find large objects in history
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sort -k3 -n -r | head -20
# Remove a file from all history using git-filter-repo (recommended)
# Install: pip install git-filter-repo
git filter-repo --invert-paths --path path/to/large-file
# Legacy approach (deprecated, slow, unsafe — avoid)
# git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch path/to/large-file' HEADGitHub Actions
Reusable Workflows
Avoid duplication by creating modular workflow templates:
# .github/workflows/standard-ci.yml
name: Standard CI
on:
workflow_call:
inputs:
node-version:
required: true
type: string
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: ${{ inputs.node-version }}
- run: pnpm install && pnpm run lint && pnpm testCalling a reusable workflow:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
ci:
uses: ./.github/workflows/standard-ci.yml
with:
node-version: '22'Dynamic Matrix Testing
Test across multiple environments and configurations simultaneously:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
node: [22, 24]
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node }}
- run: pnpm install && pnpm testDeployment Environments and Gates
Use environments to manage secrets and required approvals:
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging
steps:
- run: pnpm deploy:staging
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- run: pnpm deploy:productionEnvironment configuration:
- Staging: Automatic deploy on
mainmerge - Production: Requires reviewer approval and successful smoke tests
Composite Actions
Bundle multiple steps into a reusable action:
# .github/actions/setup-project/action.yml
name: Setup Project
description: Install dependencies and setup environment
runs:
using: composite
steps:
- uses: actions/setup-node@v6
with:
node-version: '22'
- uses: pnpm/action-setup@v4
- run: pnpm install --frozen-lockfile
shell: bashSecurity Best Practices
- Least Privilege: Use
permissionsblock to limit whatGITHUB_TOKENcan do - Secret Masking: Ensure logs never contain sensitive data
- OIDC Connect: Authenticate with AWS/GCP/Azure without long-lived secrets
- Pin action versions: Use SHA hashes instead of tags for third-party actions
permissions:
contents: read
pull-requests: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6 # pin to SHA in productionAI-Assisted Automation
- Automated code review: Trigger LLM audits on every PR
- Auto-remediation: If CI fails due to lint errors, commit the fix automatically
- PR summarization: Generate changelog entries from commit messages
Issue Templates
Copy and customize these templates for issue bodies.
Bug Report Template
## Description
[Clear description of the bug]
## Steps to Reproduce
1. [First step]
2. [Second step]
3. [And so on...]
## Expected Behavior
[What should happen]
## Actual Behavior
[What actually happens]
## Environment
- Browser: [e.g., Chrome 120]
- OS: [e.g., macOS 15.0]
- Version: [e.g., v1.2.3]
## Screenshots/Logs
[If applicable]
## Additional Context
[Any other relevant information]Feature Request Template
## Summary
[One-line description of the feature]
## Motivation
[Why is this feature needed? What problem does it solve?]
## Proposed Solution
[How should this feature work?]
## Acceptance Criteria
- [ ] [Criterion 1]
- [ ] [Criterion 2]
- [ ] [Criterion 3]
## Alternatives Considered
[Other approaches considered and why they were not chosen]
## Additional Context
[Mockups, examples, or related issues]Task Template
## Objective
[What needs to be accomplished]
## Details
[Detailed description of the work]
## Checklist
- [ ] [Subtask 1]
- [ ] [Subtask 2]
- [ ] [Subtask 3]
## Dependencies
[Any blockers or related work]
## Notes
[Additional context or considerations]Minimal Template
For simple issues:
## Description
[What and why]
## Tasks
- [ ] [Task 1]
- [ ] [Task 2]Stacked Changes
Break large features into a series of small, dependent pull requests. Reviewers only see 100-200 lines at a time, making reviews faster and more thorough.
The Concept
Instead of one giant PR:
Feature A (1,000 lines) -> One giant PR (slow review, high risk)Use stacked PRs:
Part 1: Database Schema (100 lines) -> PR #1
Part 2: API Client (150 lines) -> PR #2 (depends on #1)
Part 3: UI Component (200 lines) -> PR #3 (depends on #2)Manual Stacking with Git CLI
# Create the first part
git checkout main
git checkout -b part-1
# ... make changes, commit, push ...
git push -u origin part-1
# Create the second part on top of part-1
git checkout -b part-2 # branches from part-1
# ... make changes, commit, push ...
git push -u origin part-2
# When part-1 changes, rebase part-2
git checkout part-2
git rebase part-1
# For deeper stacks, use --onto
git rebase --onto new-base old-base branch-to-rebaseAutomated Stacking with Graphite
Graphite automates the rebase/restack process:
# Create a new branch with a commit in the stack
gt create -am "feat: add database schema"
# Insert a branch mid-stack (rebases subsequent branches automatically)
gt create --insert -am "fix: add missing migration"
# Push all branches in the stack as separate PRs
gt submit --stack
# Modify the current branch and restack descendants
gt modify
# Automatically rebase all dependent branches when a parent changes
gt restack
# Pull trunk changes and restack; clean up merged branches
gt syncBenefits
- Parallel Review: Different experts can review different parts simultaneously
- Atomic Reverts: Revert PR #3 without losing the DB schema in PR #1
- Reduced Cognitive Load: Reviewers focus on 100-200 lines at a time
- Faster Merge Cycles: Small PRs get approved faster
Best Practices
1. Title your stacks: [1/3] Database Setup, [2/3] API Implementation, [3/3] UI Component 2. Merge in order: Always merge the base of the stack first 3. Restack frequently: Keep your stack healthy by restacking against main daily 4. Aim for ~100-200 lines per PR: Right size for thorough review 5. Independent when possible: Design stack slices to minimize cross-PR dependencies
Trunk-Based Development
The preferred workflow for high-velocity teams. Focuses on small, frequent merges to a single main branch to minimize integration hell.
Core Principles
- Short-Lived Branches: Branches should exist for hours, not days (max 48 hours)
- Continuous Integration: Code is merged to
mainat least once a day - Feature Flags: Incomplete features are merged behind flags to keep
mainalways deployable - Automated Testing: All merges must pass CI; broken main is an emergency
Workflow
# 1. Start from latest main
git checkout main
git pull --rebase origin main
# 2. Create a tiny branch
git checkout -b fix/auth-header
# 3. Implement and test
# ... edit files ...
pnpm test
pnpm typecheck
# 4. Push and create PR
git push -u origin fix/auth-header
gh pr create --title "fix(auth): correct header validation"
# 5. Merge immediately after approval
gh pr merge --squashFeature Flags for Incomplete Work
Instead of long-lived feature branches, merge behind flags:
if (flags.isEnabled('new-checkout-flow')) {
return <NewCheckout />
}
return <LegacyCheckout />This allows merging incomplete code into main safely while it is still in progress.
When to Use
- Small to mid-sized teams: Fast communication and high trust
- Microservices: Isolated domains where breaking changes have limited blast radius
- SaaS products: Environments requiring multiple deployments per day
When NOT to Use
- Regulated industries requiring formal release processes (use Git Flow)
- Teams without adequate test coverage (fix tests first)
- Projects with long QA cycles before deployment
Anti-Patterns
| Anti-Pattern | Problem | Fix |
|---|---|---|
| Merging broken code | Red main is an emergency | Require 100% test pass rate on main |
| Large PRs | Defeats rapid integration purpose | Keep PRs under 200 lines |
| Ignoring the build | Cascading failures for the whole team | Fix red main immediately |
| Branches living over 48 hrs | Integration hell, stale code | Break work into smaller increments |
| No feature flags | Cannot merge incomplete work | Use flags to decouple deploy/release |