Line Endings¶
Line endings affect the on-disk bytes of every text file. For vendored code
this matters in two ways: tools and compilers on Windows may require CRLF, and
Dfetch hashes the directory after fetching to detect local modifications. A
file with LF endings has a different hash from the same file with CRLF endings,
so fixing the line-ending style at fetch time prevents dfetch check from
reporting false local modifications.
Where the preference comes from¶
Dfetch reads the line-ending preference from the superproject that owns the manifest. There is no separate dfetch setting.
Superproject type |
Where the preference comes from |
|---|---|
Git |
|
SVN |
|
The preference is resolved for a hypothetical file inside the dependency’s
destination directory, so directory-level rules such as
vendor/mylib/* text=auto eol=lf are picked up correctly.
If no preference is found, Dfetch leaves line endings as the remote provides them.
What happens on fetch¶
The table below shows what ends up on disk for each combination of remote content and superproject preference.
Remote has |
Superproject wants |
Result on disk |
|---|---|---|
LF |
lf |
LF (no conversion needed) |
LF |
crlf |
CRLF (converted during checkout) |
CRLF |
lf |
LF (renormalized after checkout) |
CRLF |
crlf |
CRLF (no conversion needed) |
CRLF in |
lf |
CRLF (remote per-file attribute wins, see below) |
any |
(none) |
unchanged |
Remote per-file attributes take precedence¶
The superproject preference is a default, not an override. If the remote
declares per-file line-ending rules in its own .gitattributes, those rules
win for the files they cover.
A common case is Windows batch files. A remote might have:
# .gitattributes in the remote repo
* text=auto
*.bat eol=crlf
*.cmd eol=crlf
Even when the superproject requests eol=lf, .bat and .cmd files
keep their CRLF endings. Files that have no explicit eol= attribute in the
remote fall back to the superproject preference.
Binary files are never converted regardless of any attribute.
Effect on the integrity hash¶
The hash in .dfetch_data.yaml is computed from the files after
line-ending conversion. Running dfetch update twice on the same remote
version always produces the same hash because the on-disk content is identical.
Changing the superproject’s line-ending preference and running dfetch update
again will produce a different hash. The vendored files have genuinely changed,
so this is expected. Running dfetch update after a preference change
re-aligns the hash with the new on-disk content.
Examples¶
Example: Git superproject forces <eol> on git subproject with <remote_eol> remote content
Given a git-repository "SomeProject.git" with <remote_eol> content
And a local git repo "MyProject" with the manifest
"""
manifest:
version: '0.0'
projects:
- name: SomeProject
url: some-remote-server/SomeProject.git
tag: v1
"""
And ".gitattributes" in MyProject is created and committed with
"""
* text=auto eol=<eol>
"""
When I run "dfetch update" in MyProject
Then 'MyProject/SomeProject/README.md' has <eol> line endings
Examples:
| remote_eol | eol |
| LF | crlf |
| CRLF | lf |
| CRLF | crlf |
| LF | lf |
Example: SVN superproject forces <eol> on git subproject with <remote_eol> remote content
An SVN superproject declares its line-ending preference with svn's own
mechanism: the ``svn:auto-props`` property (e.g. ``* = svn:eol-style=LF``).
Given a git-repository "SomeProject.git" with <remote_eol> content
And a local svn repo "MyProject" with the manifest
"""
manifest:
version: '0.0'
projects:
- name: SomeProject
url: some-remote-server/SomeProject.git
tag: v1
"""
And svn:auto-props in MyProject requests <eol> line endings
When I run "dfetch update" in MyProject
Then 'MyProject/SomeProject/README.md' has <eol> line endings
Examples:
| remote_eol | eol |
| LF | crlf |
| CRLF | lf |
| CRLF | crlf |
| LF | lf |
Example: SVN superproject forces <eol> on SVN subproject with <remote_eol> remote content
Given a svn-server "SomeSvnProject" with <remote_eol> content
And a local svn repo "MyProject" with the manifest
"""
manifest:
version: '0.0'
projects:
- name: SomeSvnProject
url: some-remote-server/SomeSvnProject
tag: v1
"""
And svn:auto-props in MyProject requests <eol> line endings
When I run "dfetch update" in MyProject
Then 'MyProject/SomeSvnProject/README.md' has <eol> line endings
Examples:
| remote_eol | eol |
| LF | crlf |
| CRLF | lf |
| CRLF | crlf |
| LF | lf |
Example: SVN superproject without a preference leaves line endings unchanged
Without a line-ending preference (``.gitattributes`` in a git
superproject, ``svn:auto-props`` in an SVN superproject), fetched files
keep the line endings the remote provides. A stray ``.gitattributes``
file next to the manifest of an SVN superproject is not used.
Given a git-repository "SomeProject.git" with CRLF content
And a local svn repo "MyProject" with the manifest
"""
manifest:
version: '0.0'
projects:
- name: SomeProject
url: some-remote-server/SomeProject.git
tag: v1
"""
And ".gitattributes" in MyProject is changed with
"""
* text=auto eol=lf
"""
When I run "dfetch update" in MyProject
Then 'MyProject/SomeProject/README.md' has CRLF line endings
Example: Git superproject forces <eol> on SVN subproject with <remote_eol> remote content
Given a svn-server "SomeSvnProject" with <remote_eol> content
And a local git repo "MyProject" with the manifest
"""
manifest:
version: '0.0'
projects:
- name: SomeSvnProject
url: some-remote-server/SomeSvnProject
tag: v1
"""
And ".gitattributes" in MyProject is created and committed with
"""
* text=auto eol=<eol>
"""
When I run "dfetch update" in MyProject
Then 'MyProject/SomeSvnProject/README.md' has <eol> line endings
Examples:
| remote_eol | eol |
| LF | crlf |
| CRLF | lf |
| CRLF | crlf |
| LF | lf |
Example: Remote gitattributes eol=crlf for a file type overrides the superproject lf preference
A remote repo that marks ``*.bat`` files as ``eol=crlf`` in its own
``.gitattributes`` keeps those line endings even when the superproject
globally requests ``lf``, so Windows batch files are never corrupted.
Given a git-repository "SomeProject.git" with a CRLF "script.bat" and "*.bat eol=crlf" gitattributes
And a local git repo "MyProject" with the manifest
"""
manifest:
version: '0.0'
projects:
- name: SomeProject
url: some-remote-server/SomeProject.git
tag: v1
"""
And ".gitattributes" in MyProject is created and committed with
"""
* text=auto eol=lf
"""
When I run "dfetch update" in MyProject
Then 'MyProject/SomeProject/script.bat' has CRLF line endings