by Serguey Shinder
The conflict itself was about eleven lines. Two of us had touched the same handler in the same week, and the tool did what tools do, marked the overlap and waited for a human to decide. I remember being annoyed about it, because it was late in the afternoon and this was supposed to be the last thing before I stopped.
I opened both versions side by side expecting to pick the better one. What I found instead was that we had not written two versions of the same idea. We had written two different ideas that happened to live in the same place.
His version assumed the incoming record could arrive twice and quietly ignored the duplicate. Mine assumed it could not, and treated a second arrival as an error worth surfacing. Neither of us had written that assumption down. Neither of us had discussed it. We had each held a picture of how the system behaved, worked from that picture for months, and never had a reason to compare them, because the pictures agreed everywhere except at exactly this point.
There is no merge strategy for that. You can take his lines, or mine, or write a third thing, and all three choices are wrong until somebody decides which world we are actually in. So I closed the editor and it stopped being the last thing before I stopped, and we spent most of the next morning on a question that had nothing to do with the eleven lines.
The answer, when we got to it, was that he was right and I had been wrong for about a year, in a way that had never once produced a visible failure. My assumption had been protected by an upstream component that happened to deduplicate, for reasons unrelated to us, and that anybody could have removed at any time without knowing what it was holding up.
I think about that afternoon whenever a conflict feels like an inconvenience. Most of them are. Two people reformatted the same block, or renamed the same variable, and the tool is asking a question with no content behind it. But occasionally the overlap is not accidental at all. Two people converged on the same lines because that is where the system's real ambiguity lives, and the conflict is the first time anyone has been forced to look at it directly.
I have not found a way to tell those apart in advance. What I have changed is smaller. When a conflict is in code that carries an assumption rather than a shape, I stop trying to resolve it and go find the other person instead, because the merge is not the disagreement. It is the first evidence that a disagreement has existed for a long time, silently, in two heads that both believed they were building the same thing.
– Serguey Asael Shinder
Leave a Reply