Git clean/checkout normalization and staged content, not formatter execution routing or offline dependency transfer.
Substantively revised October 21, 2026. Author interpretation, documented cases and hypothetical examples are distinguished below.
A file can show CRLF on a developer's machine while Git has already staged LF for the next commit. Another file can contain the same visible lines and still introduce a large byte-level change when a text policy is applied. An editor's line-ending indicator therefore cannot answer the whole repository question. The reviewer needs to know which representation changed, which rule caused it and whether the proposed commit contains anything beyond the intended conversion.
Direct answer
Inspect the index, working files and applicable text attributes separately before introducing a Git line-ending policy. Use an explicit, scoped rule for intended text paths, examine staged bytes and test newly materialized checkout files. Renormalization stages a new clean-process result for tracked paths; it is not a promise that existing working files are immediately rewritten or that every unusual newline is repaired. Keep unrelated edits and binary exceptions visible, then review the actual staged change before committing the policy.
Key takeaways
Git's index and the current working file can intentionally contain different newline bytes. A conversion warning can describe that boundary without establishing that an unwanted content change has occurred. Inspect the representations instead of making the warning itself the acceptance criterion.
An eol attribute describes checkout behavior for the path under the relevant text rules. It does not turn an existing file into proof of a fresh checkout. A newly materialized file is a more useful controlled specimen when the question concerns what another environment would receive.
A normalization change should be distinguishable from an editorial change. Line endings can make an entire text diff appear changed, so preserve the ability to review the intended content and exceptions separately. A clean-looking display alone does not establish byte identity or program correctness.
Definitions and relationships
The working tree contains the files a developer currently edits. The index contains the staged representation used to prepare a commit. A committed object records a repository representation after an actual commit. These are related states, not three names for whatever the editor currently displays.
LF is a line-feed byte; CRLF is a carriage-return byte followed by line feed. A mixed fixture in this article contains both LF and CRLF endings. Binary is an explicit policy exception in the experiment, not an inference that every file with a particular extension is correctly classified by every tool.
A path's attributes connect its intended handling to the conversion between working-file and index representations. Local configuration also matters in contexts where attributes leave behavior unspecified. To interpret a result, record the actual rule and configuration used rather than infer them only from the operating system or a colleague's editor preference.
The problem with comparing only editor settings
Consider a hypothetical team introducing a shared line-ending convention after several contributors have used different editor settings. One developer shows an LF indicator; another shows CRLF. Each can demonstrate that the visible lines are the same, and neither demonstration reveals the exact bytes already staged for the next commit.
The team then adds a policy file and assumes that saving it completed the migration. Some tracked files may still have an older representation in the index until the relevant clean process is applied again. An existing working file can also remain as it was while the index has changed. The disagreement cannot be resolved by asking which editor indicator is correct, because the indicators may be describing different intended states.
The useful acceptance example is a path whose working bytes, staged bytes and fresh checkout output are all recorded under one stated rule. That example connects the policy to the actual Git boundary. It makes a review more precise than a general assurance that everyone has enabled the same newline option.
Root cause: one file path stands for several representations
A path is a convenient label that can hide a changing object. Before staging, the investigator may mean the working file. During review, a colleague may mean the index entry. When discussing the release, both may actually need the committed object. Calling all of them the file makes a real conversion look like contradictory evidence.
The second failure is treating normalization as cosmetic by definition. A policy can alter bytes that other tools inspect, and a careless rule can include a path whose content should be preserved. The intended visual sameness of ordinary text does not authorize an unexplained transformation of every object in the repository.
The root repair is to make the conversion route inspectable. Name the path, state which representation is being examined, identify the rule and retain an actual before-and-after result. That method does not require a universal operating-system preference. It requires enough evidence to distinguish an intended conversion from a hidden edit or an inappropriate exception.
Framework: the Index Checkout Split
The Index Checkout Split is the author's proposed review method. It uses three observations for a selected path: Existing Working Bytes, Staged Bytes and Fresh Output. Alongside them, record the applicable rule. The method is designed for a scoped policy change, not as an instruction to normalize an arbitrary repository immediately.
Existing Working Bytes answers what is currently on disk before the experiment. Preserve unrelated local edits before starting an actual maintenance change. A mixed file is useful diagnostic material because it can expose a conversion that a uniformly LF example would not reveal. The observed bytes are evidence about that object, not a verdict about the entire project's intended policy.
Staged Bytes answers what the index is preparing to record. Inspect this representation after the proposed clean process. A successful command does not substitute for checking that the selected paths and exceptions are correct. The review should be able to explain both an intended changed text entry and an intended unchanged binary entry.
Fresh Output answers what a newly materialized file receives under the tested checkout rule. Keep it separate from an existing working file whose history and cached state may complicate the observation. In the research below, fresh output uses new directories in a disposable repository. No production files are removed or replaced to create the demonstration.
Apply the split to a proposed team convention by selecting representative text paths and explicit exceptions, then observing the three states under the actual rule. Compare the result with the project's required checkout behavior. Keep any substantive edits in a separately inspectable change so an all-lines newline diff cannot conceal a consequential modification.
Three documented Git mechanisms
Git's attributes documentation supplies the first real mechanism. An explicit text attribute enables end-of-line normalization to LF in the index; eol can select the working-tree form on checkout. Unsetting text prevents that conversion. The documentation distinguishes explicit text handling from automatic classification, which is why the local experiment uses a deliberate binary exception instead of claiming to evaluate Git's classifier. [S1]
The git-add documentation supplies the second mechanism. Its renormalize option reapplies the clean process to tracked files and implies update behavior. It is useful after a relevant attribute change, but it is not a universal newline-repair function: the manual specifically notes that lone CR characters are untouched. Scope the affected paths and inspect what was staged. [S2]
The git-ls-files documentation supplies the third mechanism. The eol option reports index information with i/, working-tree information with w/ and the applicable attribute with attr/. Those columns describe different evidence. A row reporting LF in the index and CRLF on disk is not internally contradictory; its interpretation depends on the rule and the task being checked. [S3]
Case study: a disposable repository with four fixtures
A local research script ran with Git 2.51.0.windows.1 and passed 22 assertions in a disposable repository under the workspace's temporary test directory. It changed only that repository's local configuration, index and synthetic files. It did not renormalize the production repository, change global Git settings or publish a commit.
The four initial fixtures are lf.txt, crlf.txt, mixed.txt and binary.bin. The text fixtures contain the same two visible words on two lines, with different newline byte patterns. The binary fixture contains CRLF bytes and a NUL byte. Its later exception is explicit. The script records exact hexadecimal bytes rather than relying on an editor preview to describe these objects.
With local autocrlf conversion disabled and no introduced text policy, staging the four selected paths retains their input bytes in the index. The resulting diagnostic rows include an LF index/working pair, a CRLF pair and a mixed pair for the three text files. This is the baseline for this isolated configuration, not a statement that every developer's unspecified configuration behaves the same way.
The script then introduces two explicit attribute patterns: txt paths are text with LF checkout output, and bin paths have text conversion unset. It stages the policy and runs a renormalization limited to the tracked txt paths. All three staged text entries become the same LF byte sequence. Their existing working files remain in their original forms, and the binary index entry remains unchanged.
This is the central observed distinction. The crlf.txt row now shows LF in the index and CRLF in the working file under an LF attribute rule. The mixed fixture similarly retains its current mixed working bytes while its staged representation is LF. Staging changed the representation prepared for the commit; it did not establish that each existing working file had been freshly written under the new checkout policy.
Fresh output tests the checkout claim
The next part materializes indexed files into a new output directory inside the disposable repository. All three fresh text outputs contain LF endings under the LF rule, while the binary output preserves its original bytes. The assertion concerns newly produced output files, not a claim that an arbitrary existing checkout was forcibly refreshed.
The experiment changes the synthetic txt checkout rule to CRLF, stages that policy and materializes another fresh output directory. The new text outputs use CRLF, while the corresponding index entries remain LF. The binary output again remains unchanged. The two output directories make the distinction visible without requiring the investigator to delete or overwrite the input specimens.
These observations show how one staged representation can support different deliberate checkout forms in the controlled example. They do not establish the intended policy for another repository, classify its unknown files or prove that every external tool accepts the resulting bytes. A repository maintaining source, generated data and format-sensitive assets may need a different set of explicit exceptions.
The research also preserves a correction to the test method. An initial attempt to use checkout-index with all and force on existing fixture files did not rematerialize the CRLF fixture as the author had assumed. The completed exercise therefore uses fresh prefixed output directories. This records what was actually observed instead of turning an unverified expectation about refreshing existing files into published advice.
Failure example: the unrelated edit inside the normalization diff
Imagine a fictional maintainer applying a new text policy while also changing an important configuration value in the same file. The resulting diff appears to replace every line because its endings changed. A reviewer decides the commit is only normalization and misses the substantive setting change hidden in the same large diff.
The failure is not that normalization is always undesirable. It is that the review's description no longer matches the contents it authorizes. A byte-level maintenance change and an application-behavior change need enough separation for each to be inspected. Calling the whole diff cosmetic does not establish that every changed value is harmless.
The Index Checkout Split addresses this by recording the expected conversion and requiring inspection of the actual staged result. A clean starting point helps isolate the operation. If other edits already exist, preserve them and prepare the policy change so their content remains reviewable. The article does not supply a universal command that can infer which changes a maintainer intended to keep.
Counterargument and tradeoff: a shared policy can reduce noise
A shared policy can be useful when a project has repeated newline disagreement. It can make checkout expectations easier to explain and prevent accidental conversion churn. Requiring every contributor to memorize undocumented machine-specific behavior is not a good substitute for a deliberate project decision.
The tradeoff is in introduction and scope. A broad conversion can create a large review, interact with local edits or include files whose bytes are format-sensitive. A narrowly specified rule with explicit exceptions may be easier to inspect. The appropriate choice depends on the repository's contents and collaborating tools, not only on a general preference for LF or CRLF.
A team can therefore adopt a common policy without treating normalization as a race to eliminate every warning. Select the paths, preserve a clean comparison, test actual fresh output and explain any remaining exceptions. The policy becomes useful because collaborators can predict its effect, not because it hides the distinction between their working files and the staged repository representation.
Common mistakes and precise corrections
Mistake: treating the editor's current indicator as the committed representation. Correction: inspect the relevant index or committed bytes directly for the question being asked. The research shows why a current working file can retain CRLF while the index prepares LF.
Mistake: assuming an attribute edit automatically rewrites every tracked object. Correction: distinguish the policy declaration from reapplying the relevant clean process and from materializing fresh output. Inspect the selected paths at each boundary instead of deriving an entire migration result from the presence of one configuration line.
Mistake: claiming a successful binary fixture proves general automatic detection. Correction: state the explicit exception used. The synthetic bin path has conversion disabled deliberately; the experiment does not measure how Git classifies every unknown object under text=auto.
Mistake: describing renormalization as a repair for every carriage return. Correction: keep the manual's lone-CR limitation visible. The completed fixtures cover LF, CRLF and their selected mixture, not arbitrary malformed endings, encoding conversions or every possible byte pattern.
Action plan for a scoped policy change
Choose the repository paths and the required output behavior before running a broad maintenance command. Identify explicit exceptions and inspect the current working state for unrelated edits. Preserve the work needed to make a clean comparison; a policy task should not silently discard someone else's changes.
Select specimens that expose the relevant difference, including a current text representation that would change and an exception that must not. Record the local Git version, relevant settings and effective attribute rule. Do not use the operating system's name as the complete explanation for the observed result.
Prepare the policy change and inspect the actual staged representation of selected tracked paths. Use diagnostic columns to separate index, working tree and rule, then verify the claim about fresh output with an appropriate controlled checkout specimen. Do not replace a source file merely to make a demonstration look tidy.
Review what the final commit would record and keep substantive edits separately inspectable. Record the expected conversion and the exceptions another contributor should retain. Repeat the relevant check when attributes, checkout tooling or format-sensitive paths change. The purpose is predictable byte handling at the Git boundary, not a blanket claim that the underlying program became correct.
FAQ
Can a working file use CRLF while the index uses LF?
Yes. The executed controlled example records exactly that state after the selected text policy is applied. Inspect the rule and representation rather than treating the differing diagnostic columns as an automatic error.
Does git add rewrite the existing working file in the rehearsal?
The selected renormalization changes staged text entries while their working bytes remain unchanged. That observation is tied to the recorded fixtures and settings. A later materialization is a separate boundary.
What does the eol attribute decide here?
Under the explicit text handling used by the experiment, it selects the newly materialized working-file newline form. The index remains LF in both tested checkout variants. The rule should be interpreted together with its text context.
Is text=auto the same as an explicit text rule?
No. Automatic classification and explicit marking are different documented choices. The research deliberately uses explicit rules and therefore does not claim to test the reliability of classifying arbitrary files.
Why include a NUL-containing binary fixture?
It gives the experiment an object whose exact bytes must remain under an explicit no-conversion rule. Its purpose is to expose an inappropriate broad transformation in the controlled set, not establish a universal definition of binary data.
Does renormalize repair a lone CR character?
The git-add manual states that lone CR is untouched. The article's completed assertions do not test a general repair method for every unusual newline. Keep the intended scope narrow.
Do these results imply every production path should use LF?
No. The experiment compares two deliberate checkout policies. Another project's format-sensitive assets and collaborating tools require their own decision. The evidence explains the representation boundary rather than choosing every project's policy.
Why use two fresh output directories?
They isolate newly materialized LF and CRLF outputs without overwriting the input specimens. The author corrected an earlier assumption about refreshing existing files and records the completed method explicitly.
Did the research force-normalize this website repository?
No. It used a disposable isolated repository in the workspace's temporary test directory. Only synthetic files and that repository's local settings and index were affected; global settings were not changed.
Was a production commit created by the exercise?
No. The assertions inspect staged representations and fresh materializations. A real maintenance change still requires review of the actual commit content and normal project checks before release.
What do i/, w/ and attr/ describe?
They describe index information, current working-tree information and the attribute rule in git-ls-files eol output. Their different roles explain why the same row can report different newline states coherently.
Can a line-ending-only description hide a real edit?
Yes, if the actual staged diff includes more than the described conversion. Separate or otherwise make substantive content changes inspectable. A large all-lines diff is not evidence that every change is merely formatting.
Does a fresh checkout test prove code correctness?
No. It tests a stated byte-conversion claim for selected paths. Program behavior, builds, external file consumers and any intended content changes need their appropriate separate validation.
How should an unexpected exception be handled?
Preserve the object and inspect its actual format requirements before applying a broader rule. A successful conversion of ordinary text does not authorize altering a file whose consumer requires its existing bytes.
What belongs in the handoff note?
Record the selected paths, rule, relevant local settings, staged representation and fresh-output observation. State the exceptions and the actual Git version. A reviewer should be able to tell what the commit changes without relying on a screenshot of an editor indicator.
Recommended books
Pro Git, second edition, by Scott Chacon and Ben Straub, published by Apress, supplies background on working-tree, staging and repository concepts. The Git project's online book identifies the 2014 second edition and later community corrections. Use the current manuals for command-specific claims in the deployed Git version rather than treating an older book as a test result.
Version Control with Git, second edition, by Jon Loeliger and Matthew McCullough, published by O'Reilly in August 2012, provides historical context for the index and the repository model. Its relevance is conceptual: the path a developer edits and the content prepared for a commit are distinct. The actual newline observations here come from the stated Git 2.51 research exercise.
The Pragmatic Programmer, 20th Anniversary Edition, by David Thomas and Andrew Hunt, published in 2019, provides broader context for making changes understandable and testable. It does not define current Git attribute behavior or certify a normalization migration. The Index Checkout Split remains the author's proposed review method, supported by the documented mechanisms and bounded experiment.
Further exploration
Inspect one authorized newline disagreement by recording the three representations before changing any project policy. Determine whether the disagreement concerns current working bytes, the next commit or output another environment will materialize. The relevant observation should answer that specific question.
Then examine a real exception whose consumer needs stable bytes. Preserve its reason alongside the text rule and test the appropriate fresh output. A predictable policy makes both intentional conversion and intentional preservation explainable, with each claim limited to the evidence actually collected.
Primary evidence sources
- [S1] Actual text/eol working tree versus normalized LF repository sections read.
- [S2] Actual renormalize option located; author must read complete option before an actual disposable-repository exercise.
- [S3] Actual --eol index/worktree/attribute triplet read.
Related concepts: systems thinking, wealth structure, and the survival loop. Read the editorial policy and citation guide.