Git Advanced Guide 2026: Branching Strategies, Rebase, and Team Workflows
Advertisement
Git 2026: Beyond git add and git commit
Most developers use 10% of Git's capabilities. This guide covers the advanced techniques that make you a better collaborator and faster debugger.
- Branching Strategies
- Interactive Rebase: Rewrite History
- Cherry-Pick: Take Specific Commits
- Git Bisect: Binary Search for Bugs
- Stash: Save Work Without Committing
- Rebase vs Merge
- Git Hooks: Automate Quality Checks
- Conventional Commits + Changelog
- Monorepo with Turborepo
Branching Strategies
Trunk-Based Development (recommended for teams using CI/CD):
main (always deployable)
├── feature/add-auth → merge to main within 1-2 days
├── fix/login-bug → merge to main within hours
└── release/v1.2 → cut from main, hotfix-only
Git Flow (for software with scheduled releases):
main (production)
develop (integration)
├── feature/* → merge to develop
├── release/* → from develop → main
└── hotfix/* → from main → main + develop
Interactive Rebase: Rewrite History
# Clean up last 5 commits before pushing
git rebase -i HEAD~5
# Opens editor with:
pick a1b2c3d Add user authentication
pick e4f5g6h Fix typo in login form
pick h7i8j9k Add tests for auth
pick l0m1n2o WIP
pick p3q4r5s Fix the WIP stuff
# Change to:
pick a1b2c3d Add user authentication
squash e4f5g6h Fix typo in login form # Merge into previous
pick h7i8j9k Add tests for auth
fixup l0m1n2o WIP # Merge + discard message
fixup p3q4r5s Fix the WIP stuff # Merge + discard message
# Commands:
# pick = use commit as-is
# squash = merge into previous, combine messages
# fixup = merge into previous, discard message
# reword = change commit message
# drop = delete commit
# edit = stop to amend
# Result: 2 clean commits instead of 5 messy ones
Cherry-Pick: Take Specific Commits
# Apply a commit from another branch
git cherry-pick a1b2c3d
# Cherry-pick a range
git cherry-pick a1b2c3d..p3q4r5s
# Cherry-pick without committing (to inspect first)
git cherry-pick --no-commit a1b2c3d
# Use case: hotfix deployed to production from a feature branch
# cherry-pick just the fix to the hotfix branch
git checkout hotfix/login-fix
git cherry-pick a1b2c3d # Only the bug fix commit
Git Bisect: Binary Search for Bugs
# "My app broke somewhere in the last 200 commits. Where?"
git bisect start
git bisect bad # Current commit is broken
git bisect good v1.0.0 # This version was fine
# Git checks out the middle commit
# Test your app, then:
git bisect good # This commit is OK → search later half
git bisect bad # This commit is broken → search earlier half
# After ~8 iterations (log₂ 200 ≈ 8), Git identifies the culprit
# Result: abc1234 is the first bad commit
git bisect reset # Go back to HEAD
# Automated bisect with test script
git bisect run npm test # Runs test suite on each candidate
Stash: Save Work Without Committing
# Save current changes
git stash # Quick save
git stash push -m "WIP: auth feature" # With name
git stash push --include-untracked # Include new files
# List stashes
git stash list
# stash@{0}: WIP: auth feature
# stash@{1}: On main: fix login bug
# Apply stash
git stash pop # Apply and remove stash@{0}
git stash apply stash@{1} # Apply without removing
git stash drop stash@{0} # Delete specific stash
git stash clear # Delete all stashes
# Create branch from stash
git stash branch feature/auth stash@{0}
Rebase vs Merge
# Scenario: main has new commits, you want them in your feature branch
# MERGE approach (creates merge commit)
git checkout feature/auth
git merge main
# Creates: "Merge branch 'main' into feature/auth" commit
# Pro: preserves exact history
# Con: messy commit history
# REBASE approach (rewrites history, linear)
git checkout feature/auth
git rebase main
# Replays your commits on top of main
# Pro: clean, linear history
# Con: rewrites commits (never rebase shared branches!)
# Interactive rebase during PR
git fetch origin
git rebase -i origin/main # Clean up before merging
Git Hooks: Automate Quality Checks
#!/bin/sh
# .git/hooks/pre-commit (chmod +x)
# Run linting before every commit
echo "Running linting..."
npm run lint
if [ $? -ne 0 ]; then
echo "Linting failed. Fix errors before committing."
exit 1
fi
# Run type check
echo "Running type check..."
npm run typecheck
if [ $? -ne 0 ]; then
echo "Type errors found."
exit 1
fi
echo "Pre-commit checks passed!"
#!/bin/sh
# .git/hooks/commit-msg
# Enforce conventional commit format
commit_msg_file=$1
commit_msg=$(cat "$commit_msg_file")
pattern="^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,72}"
if ! echo "$commit_msg" | grep -qE "$pattern"; then
echo "Invalid commit message format!"
echo "Expected: type(scope): description"
echo "Example: feat(auth): add JWT refresh token rotation"
exit 1
fi
# Install with Husky (works across the team)
npm install -D husky lint-staged
# package.json
{
"scripts": {
"prepare": "husky install"
},
"lint-staged": {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{json,md}": ["prettier --write"]
}
}
npx husky add .husky/pre-commit "npx lint-staged"
Conventional Commits + Changelog
# Format: type(scope): description
feat(auth): add Google OAuth login
fix(api): handle null user in getProfile
docs(readme): update installation steps
refactor(db): extract query helpers
test(auth): add unit tests for JWT refresh
perf(search): add vector index for embeddings
ci(actions): add staging deploy workflow
chore(deps): bump Next.js to 15.2.0
# Generate changelog automatically
npm install -D @changesets/cli
npx changeset # Create a changeset
npx changeset version # Bump versions
npx changeset publish # Publish to npm
Monorepo with Turborepo
{
"name": "webcoderspeed-monorepo",
"workspaces": ["apps/*", "packages/*"]
}
// turbo.json
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "dist/**"]
},
"test": {
"outputs": ["coverage/**"]
},
"lint": {}
}
}
# Run commands across all packages
turbo build # Build all (with caching)
turbo test # Test all in parallel
turbo lint --filter=web # Only the web app
turbo build --filter=...api # api and its dependencies
Git is not just version control — it's your collaboration infrastructure. Master these techniques and you'll debug faster, review better, and ship cleaner code.
Advertisement