You fixed a bug and reformatted the same file — how do you land two separate commits?
answer
- hunks, not files
- the fix goes in first, alone
- read what is staged before committing
- sometimes redoing beats untangling
basics
~20 sStage only the fix hunks with git add -p, review git diff --cached, commit the fix, then commit the formatting separately. Where fix and reformat share a line, use the e key to hand-edit the hunk.
solid answer
~50 sWork at hunk granularity and commit twice. Run `git add -p` on the file and accept only the hunks that are the bug fix, using **s** to split mixed hunks and **e** where a fix and a reformat land on the same line. Then read `git diff --cached` — that is exactly what the commit will contain — and check `git diff` to confirm the remaining formatting churn is all that is left. Commit the fix, then stage and commit the reformat with its own message. Two practical points make it convincing. The staged fix is a snapshot that has never been built, so if it is non-trivial verify it before pushing rather than assuming it compiles. And if the reformat came from a whole-file formatter, the cheapest recovery is often to discard the formatting entirely, commit the fix alone, then re-run the formatter as its own commit. The reason it matters is downstream: a formatting commit hides a fix from review, from `git blame`, and from bisect.
code
console · 8 lines$ git add -p src/pricing.js
Stage this hunk [y,n,q,a,d,s,e,?]? s
Stage this hunk [y,n,q,a,d,s,e,?]? y
Stage this hunk [y,n,q,a,d,s,e,?]? n
$ git diff --cached
$ git commit -m "fix: round tax to two decimals"
$ git add -u
$ git commit -m "style: reformat pricing module"go deeper
Know that git add -p lets you stage the fix hunks and commit them before staging the formatting, so the two land as separate commits.
Walk the sequence concretely — add -p with s and e, git diff --cached to review, commit, then commit the rest — and explain why a mixed diff hurts review and blame.
Show judgment beyond the keys: verify the never-built staged snapshot, recognise when redoing the mechanical change beats untangling it, and connect the split to bisect and revert staying useful.
Own the prevention — sequencing mechanical changes into their own commits, deciding how the team handles format-on-save, and setting expectations for what a reviewable commit contains.
## Why interviewers ask this It is the practical hygiene question of the staging area. Every engineer has produced a diff where a one-line fix is buried in four hundred lines of reflowed whitespace, and the answer reveals both tool fluency and an understanding of what commits are for. The cost of not splitting is concrete. A reviewer cannot see the fix, so it gets approved unread. `git blame` on the buggy line now points at the formatting commit, hiding the reasoning. `git bisect` lands on a commit that touched the whole file, so the culprit range is useless. And reverting the fix means reverting the reformat with it. ## The mechanical answer 1. `git status --short` first — confirm which files are involved and that nothing untracked is about to be swept in. 2. `git add -p <file>`. Accept the fix hunks with **y**, decline the formatting hunks with **n**, press **s** to subdivide any hunk that contains both, and fall back to **e** for a hunk where fix and reformat touch the same line. 3. `git diff --cached` — read the staged patch as if reviewing someone else. This is the commit. 4. `git diff` — confirm the leftovers are only the formatting. 5. Commit the fix with a message about the bug. Then stage the rest and commit it as a formatting-only change. When the fix and the reformat are hopelessly interleaved on the same lines, the honest move is to stop untangling and redo the work in order: discard the formatting, apply the fix cleanly, commit, then re-run the formatter and commit that. Reproducing a mechanical change is cheap; hand-editing a hundred patch hunks is slow and error-prone. ## The verification step people skip A partially staged commit records a state that never existed on disk. If the fix hunk you staged references a helper whose rename you left unstaged, the fix commit does not build — and nothing in your workflow told you, because your working tree was fine the whole time. For a small, self-contained fix, reading `git diff --cached` is enough. For anything larger, confirm the staged snapshot actually builds before it reaches a shared branch, because the commit that fails in isolation is the one a future bisect will waste an afternoon on. ## The senior framing The strongest answer treats the untangling as recovery from an avoidable situation. The root fix is ordering: land mechanical changes — formatter runs, import sorts, mass renames — as their own commits, before or after the behavioural change, never mixed into it. Then no splitting is needed. When a formatter runs automatically on save, that ordering has to be enforced rather than remembered: format the file as a separate commit before starting the fix, or configure the tool to touch only the lines you edited. It is also reasonable to say a large formatting commit is better landed on its own so reviewers can skip it wholesale, and so the repository has a single, greppable point where the style changed. What should not be part of the answer is squashing the two together and hoping review catches the fix. If a change cannot be described in one sentence, it is more than one commit.
- What if the bug fix and the reformat land on the very same line?Splitting cannot help, since s needs unchanged context between the changed regions. Press **e** to edit the hunk: delete `+` lines you do not want staged and turn `-` lines into context by replacing the minus with a space. If that gets fiddly, discard the formatting, apply the fix cleanly, commit, and re-run the formatter as its own commit.
- How do you make sure the fix-only commit actually builds?Remember that the index holds a snapshot that never existed on disk, so review `git diff --cached` and, for anything non-trivial, verify the staged tree builds before pushing. A commit that fails only in isolation is invisible today and expensive during a future bisect.
- How do you avoid ever needing to untangle this in the first place?Sequence the work: run the formatter as its own commit before or after the behavioural change, never during it. Where an editor formats on save, either format the file in a separate commit first, or restrict the tool to the lines you actually edit. Reordering is cheaper than splitting after the fact.
saying these in an interview costs you the question
- Commits everything and relies on review to spot the fix
- Thinks partial staging modifies the working tree
- Never verifies the staged snapshot builds
- Untangles interleaved edits by hand when redoing is cheaper
- Blames the formatter instead of sequencing the work