In a Git merge, when is a change applied automatically and when does it become a conflict?
answer
- Every decision is made against the base
- One side changed, the other did not
- Granularity is the region, not the file
- Identical edits on both sides are free
- Text agrees, meaning may not
basics
~20 sGit compares both sides against the merge base region by region. A region changed on only one side, or changed identically on both, is applied automatically; a region both sides changed differently is a conflict Git leaves for you.
solid answer
~50 sThe decision is made per region, not per file, and always relative to the merge base. If a hunk is unchanged on one side, the other side's version is taken. If both sides made the same edit, it is applied once. If both sides changed the same hunk to different content, Git cannot pick and marks a conflict. The same logic covers whole-file cases: modify on one side and delete on the other is a modify/delete conflict, and two sides adding a different file at the same path is an add/add conflict. Two consequences matter in practice. First, a file edited on both sides usually merges cleanly — overlap is what conflicts, not co-editing. Second, clean is not correct: Git compares text, so one side renaming a function and the other calling the old name merges silently and breaks the build.
code
bash · 4 linesgit merge-base main topic # the reference point
git diff --name-only $(git merge-base main topic) main
git diff --name-only $(git merge-base main topic) topic
# paths in BOTH lists are the only conflict candidatesgo deeper
Know that Git merges automatically when only one side changed a piece of a file, and reports a conflict when both sides changed the same piece differently.
Explain the base-relative decision table region by region, including identical-change and modify/delete cases, and why granularity is the hunk rather than the file.
Show that you plan around it — predicting conflict candidates from the base, recognizing why wholesale reformatting poisons every in-flight branch, and treating semantic conflicts as a testing obligation the merge cannot cover.
Own the levers that actually change conflict rates: how long branches live, how far the base drifts, and ownership boundaries that keep two teams out of the same regions — none of which the merge algorithm can compensate for.
## The rule For each region of each file, Git asks two questions against the merge base: *did our side change it?* and *did their side change it?* | ours vs base | theirs vs base | outcome | |---|---|---| | unchanged | unchanged | base content kept | | changed | unchanged | ours applied automatically | | unchanged | changed | theirs applied automatically | | changed, identical text | changed, identical text | applied once, no conflict | | changed differently | changed differently | **conflict** | Everything a candidate needs to explain about auto-merging follows from that table. The key insight is that "unchanged on one side" is a *positive* piece of information supplied by the base — it is the reason Git can act without asking. ## Granularity Regions are contiguous groups of lines, derived from the diffs between the base and each side. Two edits in the same file that are separated by enough unchanged context are independent regions and both apply. Two edits on the same line, or on adjacent lines with no unchanged context between them, cannot be separated and conflict. This is why "we both touched that file" is not a prediction of conflict, and why reformatting a whole file is so destructive to merges: it changes every region, so every incoming change from every other branch now overlaps. ## Beyond line hunks The same base-relative logic covers structural cases: - **modify/delete** — one side edited a file, the other removed it. Git cannot decide whether the deletion should win over the edits, so it conflicts and leaves the file present with the edits. - **add/add** — both sides created a file at the same path with different content. There is no base version at all for that path, so both are "additions" and Git conflicts. - **rename involvement** — if a side renamed a path, the merge strategy tries to follow the rename so edits from the other side land on the new path. Detection has limits, and when it fails you get changes applied to a path that no longer exists. - **mode changes** — the executable bit is merged the same way, and disagreeing changes conflict. ## Identical changes on both sides When both branches made exactly the same edit — a common outcome of cherry-picking a fix into a release branch — the base shows two identical changes and Git applies it once with no conflict. This is why merging a branch that already contains "your" fix is usually uneventful, and why a near-identical fix, differing by whitespace or a variable name, does conflict where the exact one would not. ## When Git stops On conflict, Git does not abort the whole merge. It completes every region it can decide, writes the conflicting regions into the working tree with markers, and records the competing versions in the index so the merge can be finished or abandoned. The merge is left in progress until you conclude it. (The anatomy of those markers and the commands for resolving them are their own topic; what matters here is that partial success is the norm — conflicts are localized, not repository-wide.) ## Clean does not mean correct The merge algorithm has no model of your language. Three routine ways to get a clean merge that does not work: 1. One side renames `parseDate`, the other adds a new call to `parseDate`. Different regions, different files — clean merge, compile error. 2. One side adds a caller of a function whose signature the other side changed. Clean merge, wrong arity. 3. One side adds a row to a config list, the other tightens the validation that list must satisfy. Clean merge, runtime failure. These are **semantic conflicts**, and no textual merge algorithm can catch them. They are the reason merge results are built and tested rather than reviewed by eye, and the reason a green build on both branches separately guarantees nothing about the merge. ## What actually reduces conflicts Since conflict is defined as "both sides changed the same region since the base", only two things reduce it: overlapping less, and having a more recent base. Shorter-lived branches produce a base close to both tips, so the merge reconsiders less history and there is less accumulated divergence to overlap. Long-lived branches accumulate exactly the opposite. That is mechanism, not methodology — the base is what the algorithm sees, and how far back it sits is decided by how long branches run before integrating.
- Why does merging a file that both branches edited usually succeed?Because conflict is decided per region. Each side's edits are hunks relative to the base, and hunks separated by unchanged context are independent — Git applies both. Only hunks that overlap, or sit adjacent with no context between them, cannot be separated and conflict.
- Both branches applied exactly the same fix. Does that conflict?No. The base shows two identical changes to the region, so Git applies it once and moves on. If the two fixes differ at all — a renamed variable, different whitespace — they are different changes to the same region and do conflict.
- What is a semantic conflict, and why can Git not detect one?It is a merge that is textually clean but broken in meaning: one side renames a function, the other adds a call to the old name. The edits sit in different regions, so nothing overlaps. Git merges text and has no model of the language, which is why merge results must be built and tested.
- What happens to the files Git could merge when another file conflicts?They are merged and staged normally. Git resolves everything it can, leaves only the conflicting regions unresolved in the working tree, and keeps the merge in progress. Conflicts are localized; the operation is not all-or-nothing.
saying these in an interview costs you the question
- Says any file changed on both branches conflicts
- Thinks Git picks the newer change when both sides edit
- Believes a clean merge means the code still works
- Cannot explain why identical edits on both sides do not conflict
- Says a conflict aborts the entire merge