In a Git repo, what are the real costs of requiring every branch to be rebased before landing?
answer
- Start from copying, not moving
- Count how many times one conflict is resolved
- Ask who else already has these commits
- Were the intermediate states ever built?
- Hashes escape the repository
basics
~20 sA linear history buys readable logs and simpler bisecting, but every rebase copies commits: conflicts are re-resolved per commit and per rebase, shared branches need coordinated force-pushes, intermediate commits are combinations that were never tested, and old hashes recorded elsewhere stop resolving.
solid answer
~50 sThe benefits are real — `git log` reads as a sequence, `git bisect` walks a straight line, and reverting a single change is unambiguous. The costs all follow from rebase copying rather than moving commits. Every rebase re-resolves the same conflicts, once per replayed commit, and repeats that on each rebase as trunk moves; a branch rebased daily pays daily. Anything already pushed must be force-pushed, so shared branches need coordination and give collaborators a divergence to untangle. The replayed intermediate commits are combinations that never existed before and were never built, so a bisect can land on one that fails for reasons unrelated to the bug. And hashes recorded outside the repo — in notes, links or build records — stop referring to commits on the branch. The reasonable policy is usually scoped: rebase private branches freely, treat shared ones as append-only.
go deeper
Not an expected question at this level. What matters is knowing that rebasing rewrites commits and that branches other people use are the risky ones.
Be able to name the concrete costs — repeated per-commit conflicts and the force-push requirement — and tie each back to the fact that rebase copies commits.
Demonstrate operational experience: helping a teammate recover after a rewrite, noticing untested intermediate states, and recognising when repeated rebasing signals a branch that should have landed already.
Own the tradeoff and scope the policy by branch ownership rather than decreeing one rule. Acknowledge the readability benefits honestly and connect recurring rebase pain to batch size and delivery cadence.
## What the policy buys A rebase-before-landing rule produces a first-parent history that is a straight line. Concretely: - `git log` without graph flags is readable, because commits arrive in the order they landed rather than interleaved by authorship time. - `git bisect` walks a simple sequence rather than a graph, and its output is easier to interpret. - Reverting a change means reverting one ordinary commit, with no mainline argument to reason about. - Reviewers see a branch as a clean series of steps against current trunk rather than a series plus catch-up merges. These are genuine engineering benefits, not aesthetics, and a principal-level answer should concede them plainly before listing costs. ## Cost one: conflict work multiplies A merge resolves a disagreement once, against the combined tips. A rebase resolves it per replayed commit, because each commit is applied separately to an evolving base. A ten-commit branch can therefore present ten stops for what was conceptually one conflict. Then trunk moves again, the branch is rebased again, and the same resolutions are made again. Recording resolutions for automatic reuse blunts this, but that machinery is local to each engineer and reapplies past decisions without asking — it manages the symptom. ## Cost two: coordination on shared branches Rewriting means the remote branch no longer fast-forwards, so the update must be forced. On a branch only you use, that is a non-event. On a branch a colleague has pulled, it hands them commits that no longer exist upstream, and a naive pull produces duplicated work. The team then needs a convention — who may rewrite what, and how the other person recovers — which is organisational overhead created purely by the policy. ## Cost three: untested intermediate states The replayed commits are new combinations: your change applied to a base it was never written against. Nothing built or tested those intermediate states. If CI only tests the branch tip, a bisect through the branch's interior can stop on a commit that fails for reasons unrelated to the bug being hunted. This is the quiet cost that undercuts one of the headline benefits — the linear history is easier to bisect, but its intermediate points are less trustworthy. ## Cost four: identity churn outside the repo Commit hashes leak out of the repository. They appear in tickets, in chat, in build and deployment records, in code comments referencing a fix. Every rebase invalidates the ones it copies. Anything that depended on those identities — including a signature attached to a commit object, which does not survive re-creation unless the rebase re-signs — has to be regenerated or accepted as lost. In a repository with heavy external referencing, this is a recurring tax. ## Cost five: the record stops being a record A merge-preserving history says what actually happened, including that two lines of work proceeded in parallel and were reconciled at a specific moment with a specific resolution. A rebased history asserts a sequence that never occurred. For most teams that fiction is a fair trade for readability; for teams doing forensic work — regulated changes, incident reconstruction, provenance questions — the loss of the true shape is worth weighing. ## How to actually decide A defensible position is scoped rather than absolute: - **Private, unpushed, or personally-owned branches**: rebase freely. Nobody pays. - **Branches anyone else has pulled**: treat as append-only. The coordination cost exceeds the log-readability benefit. - **Long-lived branches that need repeated rebases**: treat the repetition as the signal it is. A branch rebased for three weeks is a branch that should have been split and landed. The rebase pain is a proxy metric for batch size, and fixing the batch size fixes the pain. - **Stacks of dependent branches**: budget for restacking, and make sure the tooling that repoints intermediate branch refs is enabled, or the policy quietly costs an hour a week. ## What distinguishes a strong answer Not a preference, but a derivation: every cost traced back to the copy semantics, the benefits acknowledged honestly, the policy scoped by branch ownership rather than declared repo-wide, and at least one acknowledgement that recurring rebase pain is usually a symptom of how work is sliced rather than of the command itself.
- Why can a linear rebased history still make bisect results misleading?Because the replayed intermediate commits are combinations that never existed before — your change applied to a base it was not written against — and nothing built or tested them. A bisect can stop on such a commit failing for a reason unrelated to the bug, especially if CI only ever tested branch tips.
- How would you scope the policy rather than applying it repo-wide?By ownership. Branches that are unpushed or personally owned can be rebased freely because nobody else pays the cost. Branches other people have pulled are treated as append-only, since forcing an update hands collaborators a divergence. That split captures nearly all the readability benefit with almost none of the coordination cost.
- A branch has needed rebasing every day for three weeks. What does that tell you?That the batch is too large, not that rebase is the problem. Repeated identical conflicts are a proxy metric for how long work sits unlanded. Splitting the branch so parts land sooner removes the repetition at its source; reusing recorded resolutions only makes the repetition cheaper to endure.
- What breaks outside the repository when commits are rewritten?Any recorded hash stops referring to a commit on the branch — references in tickets, chat, code comments, build and deployment records. Signatures attached to the original commit objects also do not survive re-creation unless the rebase re-signs. In repositories that reference commits heavily, this is a recurring tax rather than a one-off.
saying these in an interview costs you the question
- Presents linear history as free of drawbacks
- Treats force-pushing a shared branch as routine
- Ignores that intermediate commits were never built
- Applies one policy repo-wide regardless of ownership
- Blames rebase rather than oversized long-lived branches