ChatGPT解决这个技术问题 Extra ChatGPT

Why should I use core.autocrlf=true in Git?

I have a Git repository that is accessed from both Windows and OS X, and that I know already contains some files with CRLF line-endings. As far as I can tell, there are two ways to deal with this:

Set core.autocrlf to false everywhere, Follow the instructions here (echoed on GitHub's help pages) to convert the repository to contain only LF line-endings, and thereafter set core.autocrlf to true on Windows and input on OS X. The problem with doing this is that if I have any binary files in the repository that: are not correctly marked as binary in gitattributes, and happen to contain both CRLFs and LFs, they will be corrupted. It is possible my repository contains such files.

So why shouldn't I just turn off Git's line-ending conversion? There are a lot of vague warnings on the web about having core.autocrlf switched off causing problems, but very few specific ones; the only that I've found so far are that kdiff3 cannot handle CRLF endings (not a problem for me), and that some text editors have line-ending issues (also not a problem for me).

The repository is internal to my company, and so I don't need to worry about sharing it with people with different autocrlf settings or line-ending requirements.

Are there any other problems with just leaving line-endings as-is that I am unaware of?

Would stackoverflow.com/questions/2333424/… help? I has link to specific reasons for leaving autocrlf to false.
@VonC Thanks, but I am already able to dictate that all users in the company set autocrlf to false and currently believe that to be the best option. But I want to know if there are any reasons why I shouldn't do that, because I can find there's a lot of people (e.g. GitHub) that say I autocrlf should be set but no actual specifics as to why.
@VonC i.e. I'm not looking for reasons to set autocrlf to false. I'm looking for reasons to set it to true.
Why not use autocrlf = input: it seems to be the perfect resolution between the two extremes: you keep your repo clean from CRLF crap, and locally Windows developers can use whatever they want without their local files having anything magic done automatically to them. (They may want LF locally for various reasons, so true is bad, in my opinion.) I can't see any downsides to using autocrlf = input.
@iconclast, one reason I've run into is if you build distributions that include both Windows batch files and Unix shell scripts. You want to use the correct line ending in each case, and this is harder to do if Git is swizzling things around even after you explicitly set them one way or the other.

V
VonC

The only specific reasons to set autocrlf to true are:

avoid git status showing all your files as modified because of the automatic EOL conversion done when cloning a Unix-based EOL Git repo to a Windows one (see issue 83 for instance)

and your coding tools somehow depends on a native EOL style being present in your file: for instance, a code generator hard-coded to detect native EOL other external batches (external to your repo) with regexp or code set to detect native EOL I believe some Eclipse plugins can produce files with CRLF regardless on platform, which can be a problem. You code with Notepad.exe (unless you are using a Windows 10 2018.09+, where Notepad respects the EOL character detected).

for instance, a code generator hard-coded to detect native EOL

other external batches (external to your repo) with regexp or code set to detect native EOL

I believe some Eclipse plugins can produce files with CRLF regardless on platform, which can be a problem.

You code with Notepad.exe (unless you are using a Windows 10 2018.09+, where Notepad respects the EOL character detected).

Unless you can see specific treatment which must deal with native EOL, you are better off leaving autocrlf to false (git config --global core.autocrlf false).

Note that this config would be a local one (because config isn't pushed from repo to repo)

If you want the same config for all users cloning that repo, check out "What's the best CRLF handling strategy with git?", using the text attribute in the .gitattributes file.

Example:

*.vcproj    text eol=crlf
*.sh        text eol=lf

Note: starting git 2.8 (March 2016), merge markers will no longer introduce mixed line ending (LF) in a CRLF file.
See "Make Git use CRLF on its “<<<<<<< HEAD” merge lines"


@VonC Thanks! That helps me feel more confident that it's safe for me to use autocrlf=false. Out of interest, do you know why git still does eol conversion even if you have autocrlf set to false?
@VonC: I don't think this answer is correct. Using core.autocrlf=true on Windows works as expected. All files from the repo (which should have LF line endings in this scenario) are converted to CRLF line endings on checkout to a Windows PC. All files are converted back to LF line endings on commit from a Windows PC. The way to get in trouble is to checkout initially to a Windows PC with the wrong core.autocrlf setting (which is entirely too easy to do).
@Michael So in that case is the only reason not to use core.autocrlf=false in my scenario be if I had some tool/editor that would get confused by the line-endings?
I would definitely use false, I've never been a big fan of automatic or magic things happening in the background. Just use \n and UTF-8 everywhere and you will be fine. If some nut-head does not understand that there are conventions and rules and forgets to use UTF-8 or \n, then someone converts them manually and slaps his face.
@Pauld'Aoust I would still prefer to specify the type of file needing that CRLF through core.eol attributes in a .gitattributes file, rather than using this global core.autocrlf setting which applies indiscriminately to all files.
V
Vlad L.

I am a .NET developer and have used Git and Visual Studio for years. My strong recommendation is to set line endings to true. And do it as early as you can in the lifetime of your Repository.

That being said, I HATE that Git changes my line endings. Source control should only save and retrieve the work I do, it should NOT modify it. Ever. But it does.

What will happen if you don't have every developer set to true, is ONE developer eventually will set to true. This will begin to change the line endings of all of your files to LF in your repo. And when users set to false check those out, Visual Studio will warn you, and ask you to change them. You will have 2 things happen very quickly. One, you will get more and more of those warnings, the bigger your team the more you get. The second, and worse thing, is that it will show that every line of every modified file was changed(because the line endings of every line will be changed by the true guy). Eventually, you won't be able to track changes in your repo reliably anymore. It is MUCH easier and cleaner to make everyone keep to true than to try to keep everyone false. As horrible as it is to live with the fact that your trusted source control is doing something it should not. Ever.


The problem with doing this with a policy(file enforced) is that on a windows machine you can have a local, a global, and a hidden config file(ProgramData/Git/Confg). You can enforce the local by checking it into the repo, but the Global AND the hidden files take precedence. Also it is possible to have local and global(or hidden) be different. If they are, they will conflict with each other on the SAME machine causing line ending errors where there are none. This is a pain to track down. :(
exactly what I think. its not the job of a source control to mess with code files as it pleases. line endings should simply be a concern of editing tools, nothing more.
If your project is Windows-only then there's no problem. However if you or your colleagues work on a *nix platform then your "strong recommendation" will cause problems. Try running a bash, perl or python script with the shebang ending with \r\n and you'll see.
The situation you described as is not problem of GIT, set the setting to FALSE as it usually should be and it's gone. Instad, it is a problem in the team work. What does it mean "eventually one developer sets true"? Why would you allow them that in the first place? when you set them up for accessing git repo, then just like you don't allow polluting certain areas with different langs (so anyone working on that can read it), or just like you keep branches/merges/rebases/etc along the chosen policy, they should get a clear rule: set correct crlf.
Posts like these remind me that we must treat line endings as first class citizens in code culture.
R
Rich

Update 2:

Xcode 9 appears to have a "feature" where it will ignore the file's current line endings, and instead just use your default line-ending setting when inserting lines into a file, resulting in files with mixed line endings.

I'm pretty sure this bug didn't exist in Xcode 7; not sure about Xcode 8. The good news is that it appears to be fixed in Xcode 10.

For the time it existed, this bug caused a small amount of hilarity in the codebase I refer to in the question (which to this day uses autocrlf=false), and led to many "EOL" commit messages and eventually to my writing a git pre-commit hook to check for/prevent introducing mixed line endings.

Update:

Note: As noted by VonC, starting from Git 2.8, merge markers will not introduce Unix-style line-endings to a Windows-style file.

Original:

One little hiccup that I've noticed with this setup is that when there are merge conflicts, the lines git adds to mark up the differences do not have Windows line-endings, even when the rest of the file does, and you can end up with a file with mixed line endings, e.g.:

// Some code<CR><LF>
<<<<<<< Updated upstream<LF>
// Change A<CR><LF>
=======<LF>
// Change B<CR><LF>
>>>>>>> Stashed changes<LF>
// More code<CR><LF>

This doesn't cause us any problems (I imagine any tool that can handle both types of line-endings will also deal sensible with mixed line-endings--certainly all the ones we use do), but it's something to be aware of.

The other thing* we've found, is that when using git diff to view changes to a file that has Windows line-endings, lines that have been added display their carriage returns, thus:

    // Not changed

+   // New line added in^M
+^M
    // Not changed
    // Not changed

* It doesn't really merit the term: "issue".


N.B. When Visual Studio encounters such a file, it offers to normalize the line-endings for you. Picking either Windows line-endings or electing not to normalize the line-endings works fine (as VS still displays it correctly the offending lines will have been deleted once the conflict has been resolved).
Unfortunately corporate version control nazis disagree with it (LF on merge conflict markers) not being an issue.
I agree that LF on merge conflict markers should not be an issue. Those lines shouldn't be committed to the repo anyway.
Note: starting git 2.8 (March 2016), merge markers will actually have CRLF line ending. See stackoverflow.com/a/35474954/6309
S
Shinji

For me.

Edit .gitattributes file.

add

*.dll binary

Then everything goes well.


Unfortunately, there are many binary files that are not DLLs in my repository: in order to be certain I'd got the correct list of file extensions to add to .gitattributes would require reviewing tens of thousands of files.
J
Jeff

I am working on GitHub and I found this article helpful.

It describes the config of git autocrlf and the setting .gitattributes file.


D
Demwis

In our project we declared necessity of setting autocrlf to input value. Here is why you may be interested in this:

Your project runs in Linux/Unix environment and developers are writing code in Windows. During push CRLF is transformed into LF automatically, thus you just need to checkout Git repo on Unix server and everything will be good out of the box.

Sometimes developers upload configuration from Windows machines to servers manually using WinSCP. This leads to CRLF line endings on Unix machines and failed app starts. "input" value partially eliminates the number of such cases

The issues we faced not long ago:

If the line endings are set to CR (not CRLF) on DEV's machine, during push they won't be transformed to LF and will stay CR in GIT repository. Do checks of line-endings thoroughly