Reputation: 15091
I have code (written in C#) that will run on both Linux and Windows. As part of the automated build process, unit/integration tests are run on TeamCity build machines. If a change is made, it will trigger both a Linux and Windows build, and the same unit tests will be executed on Linux and Windows.
Those build agents use git to pull down the source/build/test.
The desired behavior is for the Linux agent to have source code using Linux style (LF) line endings, while the Windows agent's code will have Windows style (CR LF) line endings. The reason for this is that the code uses multiline string literals as input to some of the unit tests, and the code under test uses Environment.NewLine
var example = @"This is a really,
really long string";
In both Linux and Windows I want to have the system defined Environment.NewLine appear in the string, but I've been unable to accomplish this given my constraints.
I do not have access to the build agents. Any settings or values that it would need to do it's job need to be captured in my source code, not some local value on the machine. My limited understanding tells me that I should rely on a .gitattributes
file, and while I've seen, and even slightly understand, some of the various settings around line endings that I can use within the .gitattributes
file.
I can't just configure the Windows machines to use core.autocrlf=true
and the Linux machines to use core.autocrlf=false
or some variation, unless I can do it only by adding or modifying files contained within my repository.
Is there a way to accomplish this using git, given my constraints?
Upvotes: 3
Views: 1073
Reputation: 77014
Git by default performs line ending conversions on text files. If you want files to have their line endings converted, you can mark them as text by flagging them in your .gitattributes
file:
*.cs text
If you'd like Git to guess about which files are text automatically, then you should write something like this:
* text=auto
Assuming your build agents do not have custom Git configuration that overrides line endings, that should be sufficient for Git to convert line endings to the native ones. If you'd like to be explicit, you can perform the clone with core.eol
set to native
, like so: git -c core.eol=native clone URL
.
However, having said that, it's generally not a good idea in your code to make assumptions about line endings. If your users are using the Windows Subsystem for Linux, they may well be using a Unix Git and use Unix line endings in their working tree, and that shouldn't affect the correctness of your unit tests. Line endings should be set either explicitly to LF or CRLF because of functional reasons (e.g., shell scripts won't work with CRLF endings on any platform) or left to the user's desires based on their development environment.
If you need to explicitly use the platform's native line endings in a test, you should write an explicit string that will be parsed appropriately based on the platform, or wrap your test strings in a helper function that converts them based on the platform.
Upvotes: 1
Reputation: 1329822
I can't just configure the Windows machines to use core.autocrlf=true and the Linux machines to use core.autocrlf=false
Perfect, core.autocrlf
should (almost) always be set to false, anyway.
The code itself should be LF only: it will be interpreted correctly by an IDE both on Windows and Linux.
As for the string, the unit test code should:
Meaning: Git has nothing to do with how the unit test should run.
Said unit tests should not depend on an external tool (here a version control one) being correctly configured or not.
They should run correctly independently of any .gitattributes
: their code should take care of building the expected result.
Upvotes: 2