Why can't a version-control merge be decided by comparing only the two branch tips?
answer
- Two versions are not enough evidence
- You need the shared past
- Attribution, not just difference
- Most recent commit both lines reach
- Base, yours, theirs — three inputs
basics
~20 sTwo tips reveal that they differ but not who changed what. The system also reads the merge base — the most recent commit both lines share — so a change only one side made can be taken automatically instead of being questioned.
solid answer
~50 sComparing two tips is a **two-way** comparison: it can say a region differs, but not which side moved. That is fatal, because taking a change and reverting a change look identical from the tips alone. So the system first finds the **merge base** — the most recent commit reachable from both names — and then compares three things: base, yours, theirs. Now each region answers a decidable question. If only one side differs from the base, that side changed it and its version is taken with no human involved. If both sides differ from the base in the same way, either version will do. Only when both differ from the base *differently* is the outcome genuinely undecidable, and the system reports that region rather than guessing. The base is what turns a difference into an attribution.
code
pseudocode · 14 linesbase (their last agreement): timeout = 30
retries = 3
yours: timeout = 30
retries = 5
theirs: timeout = 45
retries = 3
decision, region by region:
timeout -> base and yours agree, theirs moved -> take theirs (45)
retries -> base and theirs agree, yours moved -> take yours (5)
result: timeout = 45
retries = 5go deeper
Recall that a merge looks at three things, not two: the two current versions plus the last point the lines agreed on. Being able to name that third input is most of what is expected here.
Explain the mechanics with the deletion case: identical pairs of tips mean opposite things depending on the base, so the base is what turns a difference into an attribution. Walk the base-yours-theirs table out loud.
Demonstrate the limits in production terms — the comparison is textual, so an automatic clean result says no region was contested and nothing about whether the combination builds, and a moved block is two independent changes.
Own the organisational consequence: because attribution is per region, shared files are not a reason to serialise people, and the real lever on integration pain is how far lines are allowed to drift from their base.
## The problem with two tips Put two versions of a file side by side and you can list where they disagree. What you cannot recover is **who moved**. Consider a single line that reads `retryLimit = 3` on one side and is absent on the other. Two readings fit that evidence perfectly: - One side **added** the line, and the other side is simply older — so the line should be kept. - One side **deleted** the line deliberately, and the other side is simply older — so the line should go. A two-way comparison cannot distinguish those. Both produce the identical pair of texts. Any system that decided merges from the tips alone would have to guess, and it would guess wrong roughly half the time on exactly the changes people care most about — deliberate removals. ## The merge base The missing evidence is the shared past. Both lines descend from a common history, and the system finds the **merge base**: the most recent commit that is reachable from both tips. That commit is the last state the two lines agreed on, and it is the reference point that makes attribution possible. With three inputs — **base**, **yours**, **theirs** — each region of each file answers a decidable question: | base | yours | theirs | decision | |---|---|---|---| | X | X | Y | take **theirs** — only they changed it | | X | Y | X | take **yours** — only you changed it | | X | Y | Y | take either — both made the same change | | X | Y | Z | undecidable — reported for a human | Run the earlier example through it. If the base *lacks* the line and one side has it, that side added it and the addition is taken. If the base *has* the line and one side lacks it, that side deleted it and the deletion is taken. Same two tips, opposite and correct answers, purely because the base was consulted. ## Why the base must be the most recent common ancestor Any shared ancestor would let you attribute changes, but an older one attributes too much. Suppose both lines already agreed on a rename made twenty commits back. Against the true base, that rename is present in base, yours and theirs alike, so it is not a change on either side and never comes up. Against an ancient ancestor, the rename shows as a change made by *both* sides, and the system must reason about it again. Every commit the two lines already share and that you place before the base becomes redundant work and a redundant chance to report a region that nobody actually contested. Choosing the *most recent* common ancestor keeps the decidable set as small as it honestly can be. ## What this model does and does not promise 1. **It is textual, not semantic.** The three-way rule decides regions of text. If your side renamed a value and theirs added a new use of the old name, both changes are in different regions, both are taken cleanly, and the result is broken. A clean automatic result is not a claim that the combination works — it is a claim that no region was contested. This is exactly why an integration is not finished until the combined result has been built and tested. 2. **It scales down to the region, not the file.** Two people editing the same file are not in conflict. They are only in conflict where they changed the *same* region differently. This is the single most useful thing to be able to say about the model, because it dissolves the common team belief that shared files must be serialised. 3. **A move is two changes.** Deleting a region here and adding it there is, to the comparison, an unrelated deletion and an unrelated addition. When the other side edited the region in place, the edit and the move are attributed independently and the result rarely reads the way anyone intended. 4. **It reports rather than guesses.** When both sides changed the same region differently, no rule can recover the intent, so the system stops and marks the region. What you then do about that region is a separate skill and a separate subject. ## Saying it in an interview The compact version is one sentence: *a two-way comparison sees a difference, a three-way comparison sees who made it.* Then give the deletion example, because it is the case where the two readings diverge most sharply, and finish with the region-level point — that the base makes most of a merge decidable without anyone being asked, and that only genuinely competing edits on the same region are left over. That progression, from why two are not enough, to what the third input is, to what it makes decidable, is what an interviewer is listening for.
- Why does the three-way comparison correctly keep a deletion that only one side made?Because the base still contains the region. The side that lacks it differs from the base, so it is credited with the removal, while the side that still has it matches the base and is credited with nothing. The deletion is therefore taken. From the two tips alone that same evidence would equally support one side having added the region.
- Two people edited the same file on both lines. Does that force a conflict?No. Attribution is done per region, not per file. If their edits land in different regions, each region has exactly one side differing from the base and each is taken automatically. Only regions where both sides differ from the base in different ways are undecidable, so a shared file is not by itself a reason to serialise work.
- The merge completed automatically and the build then failed. Was the merge wrong?The merge did what it promises: no region was contested. It compares text, not meaning, so a rename on one side and a new use of the old name on the other are separate uncontested regions and both are taken. A clean automatic result is a statement about regions, not a statement about correctness — which is why the merged result must still be built and tested.
Two edited copies of a contract tell you the wording differs; only the original draft both were made from tells you which side struck the clause out.
saying these in an interview costs you the question
- Says a merge compares only the two current versions
- Cannot name the merge base or say what it is for
- Thinks two edits to the same file always conflict
- Believes a clean automatic merge proves the result works
- Says the system picks the newer change when both sides differ
- Treats a moved block as one change rather than two