In version control, how do you choose between a merge commit that records the true graph and replaying commits onto a straight line?
answer
- Two shapes, not two qualities
- One tells the truth, one tells a story
- Ask who already holds copies
- Replaying produces new commit identifiers
- Grouping versus stepping through cleanly
basics
~20 sChoose by what the history must answer later. A merge commit preserves what actually happened and keeps existing commit identifiers stable; replaying produces a linear story that never happened and writes new commits, so it is safe only on a line nobody else has copied.
solid answer
~50 sThese are two **history shapes**, not two qualities of merge. A merge commit records the truth: two lines existed, here is where they rejoined, and every commit keeps the identifier it already had. Replaying takes your commits and re-records them one at a time on top of the current target, producing a straight line that reads as if the work had been done last — a story that never happened, made of **new commits with new identifiers**. The honest tradeoff: the linear shape is far easier to read and to bisect, and it costs you the record of concurrency and, more sharply, identifier stability. Anyone who already has copies of the original commits now holds work that no longer exists on the shared line. So the practical rule is about audience, not taste: replay a line only you hold; merge anything others have already taken a copy of.
code
pseudocode · 12 linesstarting point -- both lines moved since Q
shared line: P -- Q -- T -- U
your line: P -- Q -- R -- S
merge -- one new commit, two parents:
P -- Q -- T -- U ------- M
`-- R -- S ---'
R, S, T, U keep their identifiers. M records both tips.
replay -- your work re-recorded on top of U:
P -- Q -- T -- U -- R2 -- S2
R2 and S2 are NEW commits. R and S are no longer named.go deeper
Know that the same work can be brought back as a junction in the graph or re-recorded as a straight line, and that the second one produces new commits rather than moving the old ones.
Explain the mechanics of replaying — each commit re-applied on the new base and recorded afresh — and be able to say why that means the identifiers change and the originals are simply left unnamed.
Show the judgement: pick the shape from what the history must answer and who already holds copies, and be honest that the tidier line costs the record of concurrency and can hide points that were never built.
Own it as a policy with a stated audience rule rather than a preference, and be able to defend why private and shared lines can justifiably follow different rules across a large estate.
## Two shapes for the same work When a line of work has to come back to a shared line that has moved on, there are two answers, and they differ in what the resulting history *claims*. **Merge.** Write one new commit whose parents are both tips. The recorded graph then says, truthfully: two lines existed in parallel, they both descend from a common ancestor, and here is the point at which they were reconciled. Every existing commit is untouched and keeps its identifier. **Replay** (the operation most systems name *rebase*). Take each commit of your line in order, apply the change it represents on top of the current target tip, and record the result as a **new** commit. The old commits are not modified — they cannot be, they are immutable — they are simply no longer referenced by your name, which now points at the last replayed commit. The result is a straight line that reads as though the work had been done after everything already on the target, which is not what happened. ## What each preserves and what each costs | | Merge commit | Replay onto a line | |---|---|---| | Records that work was concurrent | yes | no | | Commit identifiers | unchanged | all new | | Shape | junctions in a graph | one straight line | | Stepping through to find a defect | junctions to reason about | uniform sequence | | Contested regions | resolved once, at the junction | possibly once per replayed commit | | Safe when others hold copies | yes | no | | Each recorded commit was ever built | as recorded | as re-recorded, often never | Two rows deserve the emphasis. The **identifier row** is the one with teeth: a replayed commit is a different commit, so anyone who already has the original now holds a line that has been superseded, and reconciling their copy with the new one is real work and a real chance to lose changes. That is why the durable rule is about audience — replay a line while it is still private, and stop replaying it once anyone else has taken a copy. The **was-it-ever-built row** is the quieter cost. Replayed commits are re-recorded against a base they were never written against. Each one compiles in theory and may never have existed on any machine, so a linear history that looks perfectly bisectable can contain intermediate points that do not build. Merged history has the opposite property: the commits are exactly as they were tested on their own line, and it is the junction that is new. ## A worked case A hospital rostering product runs a 23-service estate, and a customer contract that insists on fixed scope means every change has to be traceable to the item it belongs to. A shift-swap feature sat on its own line for 6 working days and grew 37 commits while the shared line took 14 of its own. Two options: 1. **Merge.** One junction, resolved once. Later, when a night-shift rota defect appears, the on-call engineer can point at that junction and say *these 37 commits arrived as one unit for this item* — and revert or review the item as a unit. The graph is wider and reading it linearly is harder. 2. **Replay.** 37 new commits on one line, no junction, and any contested region potentially revisited as each of the 37 is re-applied. Stepping through to isolate the defect is uniform and pleasant. But the item has stopped being a visible unit, and if a colleague had already taken a copy of the line to review it, their copy now describes commits that no longer exist on the shared line. Under a fixed-scope contract, the traceable unit is worth more than the tidy line, so the junction wins for that item — while a two-commit typo fix on the same estate is better replayed, because a junction for it is noise nobody will ever query. ## How to decide 1. **Ask who already holds the commits.** If the answer is anyone but you, the shape question is already settled: do not replay. 2. **Ask what the history will be asked later.** "Which commits belong to this item?" argues for junctions. "Which commit introduced this defect?" argues for a line. 3. **Ask how far the line has drifted.** A long-lived line replayed commit by commit can re-open the same contested region many times over, which is a cost the merge pays exactly once. 4. **Ask what the item is worth as a unit.** Multi-commit features benefit from grouping; one-commit corrections are pure noise as junctions. 5. **Be consistent within a line's audience, not across the estate.** Private lines and shared lines can honestly follow different rules, because the risk that separates them is different. The answer an interviewer wants is not a preference. It is that these shapes make different promises, that one of them rewrites identity, and that the choice follows from what the history has to answer and who is already holding a copy.
- Why is replaying a line that a colleague has already copied dangerous?Because the replayed commits are new commits with new identifiers, not edited versions of the originals. Your name now points at work your colleague's copy has never seen, while their copy still references commits the shared line no longer names. Reconciling the two is manual, easy to get wrong, and the usual way changes get lost. Replay while a line is private; stop once anyone else holds it.
- A perfectly linear history is easy to step through. Is every commit in it trustworthy?Not necessarily. Replayed commits were re-recorded against a base they were never written or tested against, so intermediate points can fail to build even though the final state is fine. The linear shape makes stepping through convenient but does not make each step verified — that only comes from having actually built each recorded point.
- Does a merge commit mean somebody had to reconcile something by hand?No. The commit is required because the two lines diverged, not because a region was contested. Two lines touching unrelated files still need a commit to hold the combined state, and it is written with both tips as parents whether or not anyone was asked a question during the comparison.
saying these in an interview costs you the question
- Calls one shape simply cleaner without naming a cost
- Thinks replaying edits the original commits in place
- Says replayed commits keep their original identifiers
- Ignores who already holds a copy of the line
- Assumes a linear history means every point builds
- Claims a junction only appears after a contested region