Sharing a feature branch between developers Jump to heading
Most feature branches belong to one person, and their workflow — rebase freely, force-push, squash fixups — assumes it. When two people work on the same branch, those habits collide. One rebases and force-pushes, and the other’s next pull produces a tangle of duplicated commits. One pushes while the other is mid-rebase, and a plain --force silently discards the first person’s work. None of this needs a different branching model; it needs a few explicit agreements and settings that make the dangerous operations safe or impossible. This page sets those up for two or three people sharing a branch, within feature branch isolation.
When to use this approach Jump to heading
- Two or more people commit to the same feature branch — pairing, a hand-over, or a large feature split across a small team.
- Someone’s commits have disappeared after a colleague’s force-push.
git pullon a shared branch keeps producing merge commits or duplicated commits.- The branch will live for more than a day or two; for long-lived shared branches, also see keeping a long-lived branch in sync with main.
Step 1 — Agree who may rewrite history, and when Jump to heading
The core rule: on a shared branch, nobody rewrites history that others have fetched without telling them first. In practice teams pick one of two policies.
Write the choice in the pull request description, so anyone joining the branch knows.
Step 2 — Pull with rebase for your local commits only Jump to heading
To avoid “Merge branch ‘feature/x’ of origin into feature/x” commits, rebase your unpushed commits onto the shared tip when pulling. This rewrites only your local, unshared work.
git config --global pull.rebase true
git config --global rebase.autoStash true
git pull # replays your unpushed commits on top of what your colleague pushed The details and edge cases of this setting are in configuring git pull --rebase safely for a team.
# Verification: no merge commits from pulls on the shared branch
git log --merges --oneline origin/main..origin/feature/export-scheduling | grep -c "of github.com" || true Step 3 — Never plain --force; use a lease with inclusion check Jump to heading
If a force-push is needed — under the designated-owner policy — --force-with-lease refuses if the remote branch moved since you last fetched. --force-if-includes (Git 2.30+) adds a second check: your local branch must already include the remote tip you are about to overwrite, which catches the case where a background fetch updated your lease without you ever looking at the new commits.
git config --global alias.pushf 'push --force-with-lease --force-if-includes'
git pushf ⚠️ SAFETY WARNING:
git push --forceon a shared branch can silently delete a colleague’s commits. If it happens, the lost commits are still in the colleague’s local reflog and usually on the server for a while; recover them as in recovering from an accidental force-push. Configure the alias above and stop using plain--forceentirely.
Step 4 — Recover cleanly after someone rewrites the branch Jump to heading
When the branch owner announces a rewrite, everyone else resets their local branch to the new tip — keeping any unpushed work by rebasing it onto the new history, not by merging the old history back in.
git fetch origin
# If you have no unpushed commits:
git switch feature/export-scheduling && git reset --hard origin/feature/export-scheduling
# If you do: replay only your own commits onto the rewritten branch
git rebase --onto origin/feature/export-scheduling "$(git merge-base --fork-point origin/feature/export-scheduling)" --fork-point uses the remote-tracking reflog to find where your local work diverged from the old remote history, so only your commits are replayed. The general --onto technique is in rebasing onto a new base with --onto.
Step 5 — Split the branch when people stop overlapping Jump to heading
If two people sharing a branch are actually working on separable parts, give each a branch based on the shared one and merge them back — or stack them, so each part can be reviewed on its own. Shared branches work best for a short period of tight collaboration.
git switch -c feature/export-scheduling-ui feature/export-scheduling
git switch -c feature/export-scheduling-api feature/export-scheduling Stacking is covered in stacked pull requests without a dedicated tool.
Validation checklist Jump to heading
Frequently Asked Questions Jump to heading
Can the server enforce append-only on a feature branch? Jump to heading
Yes — apply a ruleset blocking force-pushes to the branch, or to a prefix such as shared/*. Most teams reserve that for long-lived shared branches rather than every feature.
Who should clean up history before merging? Jump to heading
Under append-only, one person does it once, after announcing it and when everyone else has pushed. Squash merging avoids the question entirely, at the cost of losing per-commit history.
What if both people need to amend the same commit? Jump to heading
That is the sign the branch has become one person’s job for the moment. Let one person finish that part, push, and hand back.
Related Jump to heading
- Feature Branch Isolation — the parent topic.
- Integrating Dependent Feature Branches — when shared work becomes dependent branches.
- Safe Git Rebase -i for Shared Branches — the rewrite itself, done safely.
- Blocking Force-Pushes with a pre-receive Hook — enforcing append-only on the server.