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):
main->main-feature/base-branch(Step 3)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
--forceinstead 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