Document Workflow

Compare text revisions and verify a unified diff

Build an exact text-comparison baseline, separate CRLF or edge-whitespace noise, inspect changed hunks, and verify a unified patch before use.

Written and tested by Published: Reviewed:

How this workflow was checked

In Diff Checker for Text, Code, and Unified Patches, the “Review a configuration change before preparing a patch” fixture was run without repairing or simplifying its input. We verified the transition from “Create an exact line baseline” to “Diagnose line-ending and edge-whitespace noise”, compared the final artifact or values, and reviewed “Counting a visual replacement once” plus “Treating indentation as cosmetic everywhere” as non-success paths.

The comparison reported three added patch lines, two removed patch lines, two paired replacements, and one hunk, with the port, log level, and /ready route changes visible in the exported patch.

Problem

A comparison can look clean while hiding the wrong difference. CRLF versus LF may overwhelm a review, trimming may conceal meaningful indentation, a missing final newline can break checks, and position-by-position comparison can turn one insertion into hundreds of apparent replacements. A unified diff adds another risk: context and file headers must match the target, and a patch created under an ignore rule no longer represents every source byte. The reliable workflow therefore keeps an exact baseline, treats filtered views as diagnosis, distinguishes patch additions and removals from visual replacement pairing, and proves the exported artifact against a copy of the intended file.

When to use this

  • A code or configuration revision must be reviewed outside a full repository client.
  • Two environment files appear different and CRLF or line-edge whitespace may be the cause.
  • A document edit needs exact inserted and deleted text without uploading confidential content.
  • Generated output or a snapshot changed and the producing step needs to be audited.
  • A unified diff will be handed to another person or checked before repository application.

Steps

  1. Step 1

    Freeze and classify both sources

    Keep untouched copies and label which is original and which is revised. Confirm text encoding before pasting, identify whether secrets or personal data are present, and remove only data that is not required for the comparison. Do not reformat either source yet.

  2. Step 2

    Create an exact line baseline

    Load the original on the left and revision on the right. Choose Line mode, leave both equivalence filters off, use three context lines, and run the comparison. Record raw added lines, raw removed lines, hunk count, and final-newline markers.

  3. Step 3

    Explain each changed block

    Read hunk ranges before individual rows. Check whether every addition and removal is intentional. Paired replacement rows are adjacent patch lines aligned for display; compare their actual text instead of assuming the pair is semantically related.

  4. Step 4

    Diagnose line-ending and edge-whitespace noise

    If the exact baseline is dominated by formatting, first inspect the files with Line Ending Detector. Then rerun with Treat CRLF as LF or Ignore line-edge whitespace one option at a time. Keep internal spaces significant and preserve the exact baseline as the source of truth.

  5. Step 5

    Use character mode only for a bounded edit

    For a short changed sentence or identifier, compare the relevant excerpt in Character mode. Interpret highlights as Unicode code points, not grapheme clusters; combining marks, flags, and ZWJ emoji may use several units. Return to Line mode for patch output.

  6. Step 6

    Export only an unfiltered patch

    Disable both filters, rerun, open Unified patch, and confirm the `--- before.txt` and `+++ after.txt` headers, hunk ranges, and missing-final-newline markers. The default labels are review names; replace them with validated repository-relative paths only in a controlled patch preparation step.

  7. Step 7

    Dry-run, apply to a copy, and retest

    Use the destination tool's check mode, such as `git apply --check` after preparing correct path headers, or a patch dry run. Apply to a disposable working copy, compare the result with the intended revision, run formatters and tests separately, and retain the exact inputs and reviewed patch with the change record.

Example

Review a configuration change before preparing a patch

Input

before.txt (ends with newline)
server:
  port: 8080
  log: info
routes:
  - /health

after.txt (ends with newline)
server:
  port: 8081
  log: debug
routes:
  - /health
  - /ready

Output

Exact line result: 3 added patch lines, 2 removed patch lines, 2 visually paired replacements, 1 changed hunk. Review port and log changes, confirm /ready is intentional, keep filters off, inspect generic before.txt/after.txt headers, then prepare and dry-run destination paths separately.

Common mistakes

Starting with ignore options enabled

A clean filtered result cannot reveal what the filter removed. Capture the exact baseline first, then use one filter at a time to classify noise.

Counting a visual replacement once

Unified diff represents a replacement as a removal plus an addition. The paired-row count is a scanning aid and does not replace raw patch counts.

Treating indentation as cosmetic everywhere

Leading whitespace changes semantics in Python, YAML, Makefiles, and other formats. Even line-edge filtering should be diagnostic, not a blanket approval.

Applying generic patch headers

The exported review patch uses before.txt and after.txt. Repository application requires deliberately prepared target paths and a check or dry run.

Assuming a completed diff proves behavior

A textual change can still be wrong. Parse configuration, run tests, validate generated artifacts, and review runtime behavior after the patch.

FAQ

Why must the first comparison be unfiltered?

It preserves every line and terminator difference as evidence. Later filtered runs can explain noise, but they cannot reconstruct differences they intentionally ignored.

Should CRLF and LF differences be committed?

Follow the repository's documented policy, commonly expressed in .gitattributes and editor settings. Diagnose first, normalize in a separate intentional change when practical, and avoid mixing wholesale line-ending churn with logic edits.

Does ignore line-edge whitespace ignore indentation?

Yes, for equality it trims both the beginning and end of each line. That can hide meaningful indentation, so use it only to diagnose and return to exact comparison before approval.

Why do replacement counts differ from additions and removals?

The patch has independent removed and added lines. The side-by-side view pairs adjacent members by position to reduce visual gaps; those pairs are not an additional edit category in the patch.

Can character mode safely compare emoji text?

It accurately compares Unicode code points, but one perceived emoji can contain regional indicators, modifiers, variation selectors, and ZWJ joins. Review the surrounding grapheme and rendered result.

What should be retained as review evidence?

Keep the identities or hashes of exact source files, selected options, raw counts, reviewed hunks, final-newline status, the unfiltered patch, path preparation, dry-run result, and post-application tests without storing secrets unnecessarily.