Skip to main content

Working with Feature & Sub-branches

A guide for managing hierarchical feature branches without losing your proverbial shit 💩

Overview

main
└── main-feature/base-branch (PR target: main)
├── feature-one/sub-branch (PR target: main-feature/base-branch)
└── feature-two/sub-branch (PR target: main-feature/base-branch)

Step One: Create Your Main Feature Branch

This is your base feature branch that eventually targets main. All sub-branches stem from here.

# Freshen up main
git checkout main && git pull -p --all

# Create your base feature branch
git checkout -b main-feature/base-branch

# Push it so you have a remote reference
git push -u origin main-feature/base-branch

💡 Pro Tip: Push immediately so git reset --hard origin/... actually has something to reset to.

Step Two: Create a sub branch

Sub-branches are where you actually do work. They target your base feature branch in PRs.

# Create sub-branch from your base feature branch
git checkout -b feature-one/sub-branch main-feature/base-branch

# Push it
git push -u origin feature-one/sub-branch

Step Three: Keep Your Base Feature Branch Synced with Main

Do this regularly to avoid a rebase shit show later.

# Update main and rebase your base feature branch
git checkout main \
&& git pull -p --all \
&& git checkout main-feature/base-branch \
&& git rebase main \
&& git push --force-with-lease

⚠️ Important: You'll need to force-push after rebasing. Use --force-with-lease to avoid overwriting someone else's changes.

Step Four: Keep Your Sub-branch Synced with the Base Feature Branch

After updating your base branch, sync your sub-branch:

# Pull latest base branch and rebase your sub-branch onto it
git checkout main-feature/base-branch \
&& git pull -p --all \
&& git checkout feature-one/sub-branch \
&& git rebase main-feature/base-branch \
&& git push --force-with-lease

The Correct Sync Order

Always follow this hierarchy (never skip levels):

  1. main -> main-feature/base-branch (Step 3)
  2. main-feature/base-branch -> feature-one/sub-branch (Step 4)

❌ Never do this:

# DON'T rebase main directly onto sub-branches
git checkout feature-one/sub-branch && git rebase main # 🙅 NOPE

Recovery Commands

Reset a Branch to Remote State

If you've messed something up locally:

# Nuclear option - throw away all local changes
git checkout feature-one/sub-branch
git reset --hard origin/feature-one/sub-branch

Abort a Rebase Gone Wrong

git rebase --abort

Check What You're About to Rebase

# See commits that will be replayed
git log origin/main-feature/base-branch..feature-one/sub-branch

Common Pitfalls

  • Forgetting to push the base branch initially
    • You can't reset to origin/... if it doesn't exist
  • Rebasing sub-branches directly onto main
    • This breaks the branch hierarchy
  • Using --force instead of --force-with-lease
    • The latter prevents you from accidentally destroying someone else's pushed commits
  • Not pulling before rebasing
    • Always git pull on the target branch first