Branch Operations
Branch Operations
Creating and Switching Branches
# List branches
git branch # Local branches
git branch -r # Remote branches
git branch -a # All branches (local + remote)
git branch -v # Last commit on each branch
# Create a new branch
git branch feature/auth
# Create and switch
git checkout -b feature/auth
git switch -c feature/auth # Modern Git (2.23+)
# Switch to existing branch
git checkout main
git switch main
# Create branch from specific commit
git branch hotfix/bugfix abc1234
# Rename branch
git branch -m old-name new-name
# Delete branch
git branch -d feature/auth # Safe delete (only if merged)
git branch -D feature/auth # Force delete
# Delete remote branch
git push origin --delete feature/auth
git push origin :feature/auth # Same thing
# See merged branches
git branch --merged
git branch --merged main # Merged into main
# See unmerged branches
git branch --no-merged
Tracking Remote Branches
# Set upstream
git push -u origin feature/auth
# See which branch tracks what
git branch -vv
# Change tracking
git branch --set-upstream-to=origin/main main
# Prune stale remote branches
git fetch --prune
git remote prune origin
Merging
Merging
Fast-Forward Merge
When the target branch has no new commits since you branched off:
git checkout feature/auth
git merge main
# Just moves the pointer forward — clean history
# Fast-forward only
git merge --ff-only main
# No fast-forward (always create a merge commit)
git merge --no-ff main -m "Merge main into feature/auth"
Three-Way Merge
When both branches have diverged:
git checkout main
git merge feature/auth
# Creates a merge commit that combines both histories
# Example merge commit message:
# Merge branch 'feature/auth' into main
#
# * Add JWT validation
# * Implement login endpoint
# * Add password hashing
Squash Merge
Combines all commits from a branch into one:
git checkout main
git merge --squash feature/auth
git commit -m "Add complete user authentication module"
# This takes all changes from feature/auth,
# stages them as one commit, keeping history clean
Merge Strategies
# Recursive (default) — handles multiple merge bases
git merge -s recursive feature
# Ours — keep our version of conflicts
git merge -s ours feature
# Octopus — merge multiple branches at once
git merge branch1 branch2 branch3
Rebasing
Rebasing
Basic Rebase
# Move feature branch commits on top of main
git checkout feature/auth
git rebase main
# This rewrites history — commits get new hashes
# Result: linear history (no merge commits)
Interactive Rebase
# Rebase last 3 commits
git rebase -i HEAD~3
# Editor opens with:
pick abc1234 Add login endpoint
pick def5678 Fix typo in login
pick ghi9012 Add tests for login
# Commands:
# pick = keep commit as-is
# reword = keep commit, edit message
# squash = combine with previous commit
# fixup = combine, discard this commit's message
# drop = remove commit entirely
# Example: squash fix typo into login endpoint
pick abc1234 Add login endpoint
squash def5678 Fix typo in login
pick ghi9012 Add tests for login
# This creates:
# abc1234 Add login endpoint (with typo fixed)
# ghi9012 Add tests for login
Rebase vs Merge
# Merge: preserves history, creates merge commits
git checkout main
git merge feature # Creates merge commit
# Result:
# * Merge branch 'feature' (merge commit)
# |\
# | * Add feature B
# | * Add feature A
# *|
# * Initial commit
# Rebase: rewrites history, linear
git checkout feature
git rebase main
# Result:
# * Add feature B
# * Add feature A
# * Initial commit
# Rule of thumb:
# - Rebase local/private branches (not pushed)
# - Merge public/shared branches (don't rewrite history)
Handling Conflicts During Rebase
git rebase main
# CONFLICT in src/app.js
# 1. Edit the file to resolve conflicts
# 2. Stage the resolved file
git add src/app.js
# 3. Continue rebase
git rebase --continue
# 4. If you want to abort
git rebase --abort
# Skip a conflicting commit
git rebase --skip
Stashing and Worktrees
Stashing and Worktrees
Git Stash
# Stash current changes
git stash
git stash push -m "WIP: auth feature"
# Stash including untracked files
git stash -u
git stash --include-untracked
# List stashes
git stash list
# stash@{0}: On feature/auth: WIP: auth feature
# stash@{0}: On main: WIP: hotfix work
# Apply stash (keep in stash list)
git stash apply
git stash apply stash@{1} # Apply specific stash
# Apply and remove
git stash pop
git stash pop stash@{1}
# Drop a stash
git stash drop stash@{0}
# Clear all stashes
git stash clear
# Show stash diff
git stash show -p
git stash show -p stash@{0}
# Create branch from stash
git stash branch feature-from-stash
git stash branch feature-from-stash stash@{0}
Git Worktree
Worktrees let you check out multiple branches simultaneously in separate directories:
# Create a worktree for a hotfix
git worktree add ../hotfix-branch hotfix/bugfix
# Work in the hotfix directory
cd ../hotfix-branch
# Make fixes, commit
# Return to main worktree
cd ../repo
# List worktrees
git worktree list
# Remove worktree
git worktree remove ../hotfix-branch
# Prune stale worktree references
git worktree prune
Practical Stash Scenarios
# Quick context switch: stash, switch, unstash
git stash push -m "Half-done feature"
git checkout main
# Do urgent hotfix
git checkout feature
git stash pop
# Stash only specific files
git stash push -m "Stash config changes" -- config.js .env
# Apply stash without removing
git stash apply stash@{0}
# If conflicts, fix them, then:
git stash drop stash@{0}
# Stash with message for organization
git stash push -m "[BUG] Fix in progress: memory leak"
git stash push -m "[FEATURE] WIP: new endpoint"
git stash list
# Shows clear labels for each stash
Git Workflows
Git Workflows
GitHub Flow (Simple)
Best for: small teams, continuous deployment
1. Pull latest main
git checkout main
git pull origin main
2. Create feature branch
git checkout -b feature/new-feature
3. Make changes, commit often
git add .
git commit -m "Add new feature part 1"
git commit -m "Add new feature part 2"
4. Push and create PR
git push -u origin feature/new-feature
# Create PR on GitHub
5. Code review, address feedback
6. Merge PR (merge button on GitHub)
7. Delete feature branch
git checkout main
git pull
git branch -d feature/new-feature
Gitflow (Structured)
Best for: scheduled releases, multiple versions
Branches:
- main: production code
- develop: integration branch
- feature/*: new features
- release/*: release preparation
- hotfix/*: production fixes
# Start a feature
git checkout develop
git pull
git checkout -b feature/user-auth
# ... work ...
git checkout develop
git merge --no-ff feature/user-auth
git push origin develop
# Start a release
git checkout develop
git checkout -b release/1.0.0
git commit -m "Bump version to 1.0.0"
git checkout main
git merge --no-ff release/1.0.0
git tag -a v1.0.0 -m "Release 1.0.0"
git checkout develop
git merge --no-ff release/1.0.0
# Hotfix
git checkout main
git checkout -b hotfix/critical-bug
# ... fix ...
git checkout main
git merge --no-ff hotfix/critical-bug
git tag -a v1.0.1
git checkout develop
git merge --no-ff hotfix/critical-bug
Trunk-Based Development
Best for: high-performing teams, feature flags
1. Short-lived branches (hours, not days)
git checkout -b my-feature
# Quick changes, quick PR
2. Merge to main daily or more often
3. Use feature flags for incomplete features
if (featureFlags.enabled('new-auth')) {
// new code
}
4. Never commit directly to main
git checkout -b fix/tiny-bug
# Commit, push, PR, merge