skip to content

How do you review a rename an assistant applied across forty files without reading all forty?

level: seniorimportance: should knowfreq 50%

answer

  1. A mechanical change should look the same everywhere
  2. Classification, not reading
  3. Read what breaks the shape
  4. Where can a rename not follow the name?

basics

~20 s

Review by shape, not by file: decide what every hunk should look like, read the ones that break the pattern, and search separately for the names a rename cannot reach - in configuration, stored data or message text.

solid answer

~50 s

A mechanical change has a property other changes do not: it should look identical everywhere, so the review is classification rather than reading. I write down the expected shape first - the old name replaced by the new one and nothing else on the line - then group the hunks and read, in full, only the ones that break it: an extra edit riding along, a file where the occurrence count does not match, a changed file I did not expect. Then I check the places a rename cannot follow, because they do not appear in the diff and are not caught by the build: configuration, stored data, message text, and names assembled at run time. Finally I refuse the diff if a formatting sweep or a small improvement was mixed in, because that is what destroys the pattern the whole review depends on.

code

text · 13 lines
text
stated shape: OrderId -> PurchaseOrderId, nothing else on the line

  file 07 of 40   billing/invoice
  -   id: OrderId = row.id
  +   id: PurchaseOrderId = row.id

  file 18 of 40   shipping/label
  -   print(id: OrderId)
  +   print(id: PurchaseOrderId)

  file 31 of 40   orders/audit
  -   record(id: OrderId, at: timestamp)
  +   record(id: PurchaseOrderId)

go deeper

for a junior

Know that a large mechanical diff is reviewed by pattern rather than line by line, and that the parts worth your attention are the ones that do not match the pattern.

for a middle

Explain what a rename cannot reach - a name in stored data, configuration, message text, or assembled at run time - and how you search for those separately from the diff.

for a senior

Show the discipline: state the expected shape before opening the diff, group the hunks, read the exceptions and the count mismatches, and reject a diff that mixes a tidy-up into the rename.

for a principal

Own the argument for keeping mechanical changes in their own commit. The cost of a mixed diff is paid by every later reviewer and by whoever bisects it, not by the author who saved a step.

## The property that makes a large diff reviewable at all A mechanical change has a property that other changes do not: **it should look the same everywhere**. Forty files of a single rename should be forty files of one repeated transformation. That turns review from reading into **classification** - you are not checking forty edits, you are checking that forty edits belong to one class, and reading the ones that do not. Reviewing a forty-file rename by opening file one and working down is a plan that runs out of attention long before it runs out of files, and the hunk that matters is usually not near the top. Reviewing a change an autonomous agent made across many files on its own initiative is a different subject; this is the change you asked for, applied wider than you can read. ## State the shape before you open the diff Write down, in one sentence, what every hunk should be: *the old name replaced by the new one, and nothing else on the line*. Do it before opening the diff, because once you are inside it you will rationalise whatever you find. That sentence is the classifier. Everything the diff contains is now either an instance of it or an exception, and exceptions are the entire job. ## Sorting the hunks 1. **Group by shape.** Most tooling can show you the diff as text; sort or group the changed lines and the repeated transformation collapses into one visual block. What remains standing out is the list you actually read. 2. **Read every exception in full.** A hunk that also reordered arguments, changed a default, adjusted whitespace inside a string, or renamed a second thing along the way is not part of the mechanical class, whatever it looks like. 3. **Read every file where the counts disagree.** If a file had six occurrences of the name and the diff changed four, the two survivors have a reason. Find it and name it. 4. **Read the declaration and one representative use in full**, even when nothing looks wrong - so that "the shape" you have been classifying against is a shape you have actually verified once. | hunk class | what it means | what you do | |---|---|---| | Matches the stated shape | the mechanical majority | verify by count and sample, not by reading each | | Extra edit on the same line | an improvement rode along | read it; ask for it as a separate change | | Whitespace or formatting churn | a sweep got mixed in | reject the mix, not the rename | | Occurrence count mismatch | something was unresolvable | read that file completely | | Changed file you did not expect | the name meant two things | read it; the rename may be over-applied | ## Where a rename cannot reach A structural rename follows references. Names also live where nothing resolves them: - stored data - a column, a field name inside a serialised record, a key in a cache; - configuration and deployment files, including ones outside this repository; - message, log and error text that a person or a dashboard greps for; - names assembled or looked up at run time from strings; - documentation, runbooks and comments, where the old name is now a lie. None of these is caught by the build, and none of them appears in the diff. They are found with a plain whole-project search for the old name, run afterwards, plus a moment's thought about who outside the project consumes the name. ## The counts that turn review into measurement Three cheap numbers make the mechanical majority trustworthy without reading it: the number of occurrences of the old name before, the number of the new name after, and the number of remaining old-name hits with a reason attached to each. When those line up, the class is verified. When they do not, the gap is exactly the list to read. This is what lets you say "I reviewed a forty-file rename" honestly in ten minutes, rather than either lying about it or spending a day. ## Why the tidy-up has to be a separate commit The most useful thing you can do to a large mechanical diff is to refuse to let anything else into it. A formatting sweep or a small improvement mixed into the rename destroys the one property the review depends on - that every hunk looks the same - and it does so silently, because the noise looks harmless one line at a time. Ask for the mechanical change alone, land it, then ask for the improvement as its own change with its own reasoning. The cost of a mixed diff is not paid by whoever saved a commit; it is paid by every reviewer afterwards, and by whoever bisects it later.

  • What belongs in the commit with a mechanical rename, and what does not?
    Only the rename. Formatting sweeps, import reordering and small improvements each go in their own commit. Mixed in, they destroy the one property that makes a large diff reviewable - that every hunk should look the same - and they do it quietly, because each line looks harmless.
  • Your search finds fewer changed occurrences than the old name had. What now?
    Read the difference file by file and give each survivor a reason. Either the tool could not resolve those uses, or your search matched a different thing that shares the spelling. Both are real outcomes and neither is safe to assume without looking.
  • How do you review the same change when the rename was textual rather than name-resolving?
    The same classification, with the opposite default: assume over-application rather than under-application. Read every changed file you did not predict, because a text match hits comments, unrelated identifiers that share the spelling, and strings that were never meant to change.

saying these in an interview costs you the question

  • Reads a forty-file rename hunk by hunk until attention runs out
  • Treats a green build as proof the rename reached every occurrence
  • Accepts a diff that mixes reformatting into the mechanical change
  • Assumes a name only appears in code the tool can parse
  • Uses the number of changed files as the measure of risk