Git 处理 CRLF(回车、换行)的策略是什么?

发布于 2024-07-06 21:19:04 字数 197 浏览 5 评论 0原文

我尝试提交以 CRLF 结尾的行的文件,但失败了。

我花了一整天的时间在我的 Windows 计算机上尝试不同的策略,并且几乎被吸引停止尝试使用 Git,而是尝试 水银

如何正确处理 CRLF 行结尾?

I tried committing files with CRLF-ending lines, but it failed.

I spent a whole work day on my Windows computer trying different strategies and was almost drawn to stop trying to use Git and instead try Mercurial.

How to properly handle CRLF line endings?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

哆兒滾 2024-07-13 21:19:04

在问这个问题近四年后,我终于
找到一个完全令我满意的答案

请参阅 github:help 指南中的详细信息
处理行结尾

Git 允许您设置行结束属性
直接使用 文本属性 进行存储
.gitattributes 文件。 该文件被提交到
存储库并覆盖 core.autocrlf 设置,
让您确保所有人的行为一致
用户无论其 git 设置如何。

因此

这样做的好处是你的行尾
配置现在与您的存储库一起移动,并且您
无需担心是否有合作者
有正确的全局设置。

这是 .gitattributes 文件的示例

# Auto detect text files and perform LF normalization
*        text=auto

*.cs     text diff=csharp
*.java   text diff=java
*.html   text diff=html
*.css    text
*.js     text
*.sql    text

*.csproj text merge=union
*.sln    text merge=union eol=crlf

*.docx   diff=astextplain
*.DOCX   diff=astextplain

# absolute paths are ok, as are globs
/**/postinst* text eol=lf

# paths that don't start with / are treated relative to the .gitattributes folder
relative/path/*.txt text eol=lf

有一个方便的现成使用的集合。最流行的编程语言的 gitattributes 文件。 这对您入门很有用。

创建或调整 .gitattributes 后,您应该执行一劳永逸的 行尾重新规范化

请注意,GitHub Desktop 应用程序可以在您选择后建议并创建一个 .gitattributes 文件在应用程序中打开项目的 Git 存储库。 要尝试此操作,请单击齿轮图标(位于右上角)> 存储库设置...>> 行结束符和属性。 系统会要求您添加推荐的 .gitattributes,如果您同意,该应用程序还将对存储库中的所有文件执行规范化。

最后,注意行尾一文
提供更多背景知识并解释 Git 的演变过程
关于手头的事情。 我认为这是必读的内容。

您的团队中可能有用户使用 EGit 或 JGit(Eclipse 和 TeamCity 等工具使用它们)来提交更改。 那么你就不走运了,正如 @gatinueta 在这个答案的评论中解释的那样:

如果您的团队中有人使用 Egit 或 JGit,则此设置不会完全满足您的要求,因为这些工具只会忽略 .gitattributes 并愉快地签入 CRLF 文件 https://bugs.eclipse.org/bugs/show_bug.cgi?id=342372

一个技巧可能是让他们在另一个客户端中提交更改,例如 SourceTree。 对于许多用例,我们的团队当时更喜欢该工具,而不是 Eclipse 的 Egit。

谁说软件很简单? :-/

Almost four years after asking this question, I have finally
found an answer that completely satisfies me!

See the details in github:help's guide to
Dealing with line endings.

Git allows you to set the line ending properties for a
repo directly using the text attribute in the
.gitattributes file. This file is committed into
the repo and overrides the core.autocrlf setting,
allowing you to ensure consistent behaviour for all
users regardless of their git settings.

And thus

The advantage of this is that your end of line
configuration now travels with your repository and you
don't need to worry about whether or not collaborators
have the proper global settings.

Here's an example of a .gitattributes file

# Auto detect text files and perform LF normalization
*        text=auto

*.cs     text diff=csharp
*.java   text diff=java
*.html   text diff=html
*.css    text
*.js     text
*.sql    text

*.csproj text merge=union
*.sln    text merge=union eol=crlf

*.docx   diff=astextplain
*.DOCX   diff=astextplain

# absolute paths are ok, as are globs
/**/postinst* text eol=lf

# paths that don't start with / are treated relative to the .gitattributes folder
relative/path/*.txt text eol=lf

There is a convenient collection of ready to use .gitattributes files for the most popular programming languages. It's useful to get you started.

Once you've created or adjusted your .gitattributes, you should perform a once-and-for-all line endings re-normalization.

Note that the GitHub Desktop app can suggest and create a .gitattributes file after you open your project's Git repo in the app. To try that, click the gear icon (in the upper right corner) > Repository settings ... > Line endings and attributes. You will be asked to add the recommended .gitattributes and if you agree, the app will also perform a normalization of all the files in your repository.

Finally, the Mind the End of Your Line article
provides more background and explains how Git has evolved
on the matters at hand. I consider this required reading.

You've probably got users in your team who use EGit or JGit (tools like Eclipse and TeamCity use them) to commit their changes. Then you're out of luck, as @gatinueta explained in this answer's comments:

This setting will not satisfy you completely if you have people working with Egit or JGit in your team, since those tools will just ignore .gitattributes and happily check in CRLF files https://bugs.eclipse.org/bugs/show_bug.cgi?id=342372

One trick might be to have them commit their changes in another client, say SourceTree. Our team back then preferred that tool to Eclipse's EGit for many use cases.

Who said software is easy? :-/

淤浪 2024-07-13 21:19:04

不要转换行结尾。 VCS 的工作不是解释数据,而是存储数据并对其进行版本控制。 无论如何,每个现代文本编辑器都可以读取这两种行结尾。

Don't convert line endings. It's not the VCS's job to interpret data -- just store and version it. Every modern text editor can read both kinds of line endings anyway.

┊风居住的梦幻卍 2024-07-13 21:19:04

除非您真的知道自己在做什么,否则您几乎总是需要autocrlf=input

下面是一些附加上下文:

如果您愿意,它应该是 core.autocrlf=true
如果您愿意,DOS 结尾或 core.autocrlf=input
Unix 换行符。 在这两种情况下,您的 Git 存储库都会
只有 LF,这是正确的事情。 唯一的
core.autocrlf=false 的参数是自动的
启发式可能会错误地将某些二进制文件检测为文本
然后你的瓷砖就会被损坏。 所以,
引入了 core.safecrlf 选项来警告用户
发生不可逆转的变化。 事实上,有两个
不可逆转的变化的可能性 -- -- 混合的
文本文件中的行结束符,在此标准化中是
理想的,因此可以忽略此警告,或者
(极不可能)Git 错误地检测到你的
二进制文件作为文本。 然后你需要使用属性
告诉 Git 该文件是二进制文件。

上面的段落最初是从 gmane.org 上的一个帖子中提取的,但后来它已经被删除了。

You almost always want autocrlf=input unless you really know what you are doing.

Some additional context below:

It should be either core.autocrlf=true if you like
DOS ending or core.autocrlf=input if you prefer
unix-newlines. In both cases, your Git repository will
have only LF, which is the Right Thing. The only
argument for core.autocrlf=false was that automatic
heuristic may incorrectly detect some binary as text
and then your tile will be corrupted. So,
core.safecrlf option was introduced to warn a user if
a irreversable change happens. In fact, there are two
possibilities of irreversable changes -- mixed
line-ending in text file, in this normalization is
desirable, so this warning can be ignored, or
(very unlikely) that Git incorrectly detected your
binary file as text. Then you need to use attributes to
tell Git that this file is binary.

The above paragraph was originally pulled from a thread on gmane.org, but it has since gone down.

错々过的事 2024-07-13 21:19:04

在混合环境(Microsoft + Linux + Mac)中保持行尾一致的两种替代策略:

A. 全局 所有存储库设置

  1. 转换全部为一种格式

    查找 .   -type f -not -path "./.git/*" -exec dos2unix {} \; 
      git commit -a -m 'dos2unix 转换' 
      
  2. 在 Linux/UNIX 上将 core.autocrlf 设置为 input 或在 MS Windows(存储库或全局)上设置 true

    git config --global core.autocrlf 输入 
      
  3. (可选)将core.safecrlf设置为true(停止)或warn(唱歌:)以添加额外的保护来比较反向换行符转换将产生相同的文件

    git config --global core.safecrlf true 
      

B. 或每个存储库设置

  1. 全部转换为一种格式

    查找 .   -type f -not -path "./.git/*" -exec dos2unix {} \; 
      git commit -a -m 'dos2unix 转换' 
      
  2. .gitattributes 文件添加到您的存储库

    echo "* text=auto" >   .gitattributes 
      git 添加 .gitattributes 
      git commit -m '添加 .gitattributes 以实现统一行结束' 
      

不要担心您的二进制文件 - Git 应该对它们足够聪明。


有关 safecrlf/autocrlf 变量的更多信息

Two alternative strategies to get consistent about line-endings in mixed environments (Microsoft + Linux + Mac):

A. Global All Repositories Setup

  1. Convert all to one format

    find . -type f -not -path "./.git/*" -exec dos2unix {} \;
    git commit -a -m 'dos2unix conversion'
    
  2. Set core.autocrlf to input on Linux/UNIX or true on MS Windows (repository or global)

    git config --global core.autocrlf input
    
  3. Optionally, set core.safecrlf to true (to stop) or warn (to sing:) to add extra guard comparing if the reversed newline transformation would result in the same file

    git config --global core.safecrlf true
    

B. Or per Repository Setup

  1. Convert all to one format

    find . -type f -not -path "./.git/*" -exec dos2unix {} \;
    git commit -a -m 'dos2unix conversion'
    
  2. Add a .gitattributes file to your repository

    echo "* text=auto" > .gitattributes
    git add .gitattributes
    git commit -m 'adding .gitattributes for unified line-ending'
    

Don't worry about your binary files—Git should be smart enough about them.


More about safecrlf/autocrlf variables

七秒鱼° 2024-07-13 21:19:04

--- UPDATE 3 --- (与 UPDATE 2 不冲突)

考虑到 Windows 用户更喜欢在 CRLF 上工作,而 linux/mac 用户更喜欢在 LF 上工作文本文件。 从存储库维护者的角度提供答案

对我来说,最佳策略(需要解决的问题较少)是:保留所有文本文件即使您正在处理仅限 Windows 的项目,LF inside git repo 也是如此。 然后,给予客户自由,让他们可以使用他们偏好的行结束样式,前提是他们选择的 core.autocrlf 属性值符合以下条件:在暂存文件以供提交时将尊重您的策略(LF on repo)

分期是许多人在试图理解换行策略如何工作时感到困惑的地方。 在为 core.autocrlf 属性选择正确的值之前,必须了解以下几点:

  • 添加用于提交的文本文件(暂存)就像复制文件到 .git/ 子目录中的另一个位置,并带有转换后的行尾(取决于您的 core.autocrlf 值)客户端配置)。 所有这些都是在本地完成的。
  • 设置core.autocrlf就像为问题提供答案(在所有操作系统上都完全相同):“应该git 客户端:
    • a. 从远程签出(拉取)存储库更改时将 LF 转换为 CRLF
    • b. 添加文件进行提交时将 CRLF 转换为 LF?"
  • ,可能的答案(值)是:
    • false:不执行上述任何操作”,
    • 输入:只做b
    • true:“执行a 和 b
    • 请注意,没有“只做一个

幸运的是

  • git 客户端默认值 (windows: core.autocrlf: true, linux/mac:
    core.autocrlf: false) 将与 LF-only-repo 策略兼容。
    含义:Windows 客户端在签出存储库时默认会转换为 CRLF,在添加提交时会默认转换为 LF。 Linux 客户端默认不会进行任何转换。 从理论上讲,这只会使您的存储库保持在 lf 状态。

不幸的是:

  • 可能有 GUI 客户端不尊重 git core.autocrlf
  • 可能有人不使用值来尊重您的 lf-repo 策略。 例如,他们使用 core.autocrlf=false 并添加带有 CRLF 的文件进行提交。

要尽快检测上述客户端提交的非 lf 文本文件,您可以按照 --- update 2 --- 中的描述进行操作:(git grep -I --files-with-匹配 --perl-regexp '\r' HEAD,在使用 --with-libpcre 标志编译的客户端上)

这里是问题:。 作为仓库维护者,我保留了一个 git.autocrlf=input ,这样我就可以通过再次添加它们进行提交来修复任何错误提交的文件。 我提供了一个提交文本:“修复错误提交的文件”。

.gitattributes 而言。 我不指望它,因为有更多的 ui 客户端不理解它。 我只用它来提供文本和二进制文件的提示,并且可能标记一些应该在各处保持相同行结尾的特殊文件:

*.java          text !eol # Don't do auto-detection. Treat as text (don't set any eol rule. use client's)
*.jpg           -text     # Don't do auto-detection. Treat as binary
*.sh            text eol=lf # Don't do auto-detection. Treat as text. Checkout and add with eol=lf
*.bat           text eol=crlf # Treat as text. Checkout and add with eol=crlf

问题:但是为什么我们对换行处理策略感兴趣?

答案:为了避免单字母更改提交,显示为 5000 行更改,只是因为执行更改的客户端自动将整个文件从 crlf 转换为 lf (或相反)在添加它进行提交之前。 当涉及冲突解决时,这可能会相当痛苦。 或者在某些情况下它可能成为不合理冲突的原因。


--- 更新 2 ---

git 客户端的默认设置在大多数情况下都可以工作。 即使您只有 Windows 客户端、Linux 客户端或两者都有。 它们是:

  • windows: core.autocrlf=true 表示在签出时将行转换为 CRLF,在添加文件时将行转换为 LF。
  • linux: core.autocrlf=input 表示在签出时不转换行(不需要,因为文件预计以 LF 提交)并将行转换为 LF(如果添加文件时需要)。
    -- update3 --:默认情况下似乎这是 false,但同样没问题)

该属性可以在不同的范围内设置。 我建议在 --global 范围中显式设置,以避免最后描述的一些 IDE 问题。

git config core.autocrlf
git config --global core.autocrlf
git config --system core.autocrlf
git config --local core.autocrlf
git config --show-origin core.autocrlf

另外,我强烈不鼓励在Windows上使用git config --global core.autocrlf false(如果您只有Windows客户端)与提议的内容相反 git 文档。 设置为 false 将在存储库中提交带有 CRLF 的文件。 但确实没有理由。 您永远不知道是否需要与 Linux 用户共享该项目。 另外,对于加入该项目的每个客户来说,这是一个额外的步骤,而不是使用默认值。

现在,对于某些特殊情况的文件(例如 *.bat *.sh),您希望使用 LF 或 CRLF 检出它们,您可以使用 .gitattributes

对我来说,最佳实践是:

  • 确保每个非二进制文件都在 git repo 上使用 LF 提交(默认行为)。
  • 使用此命令确保没有使用 CRLF 提交文件:git grep -I --files-with-matches --perl-regexp '\r' HEAD注意: 在 Windows 客户端上只能通过 git-bash 工作,在 Linux 客户端上只有在 ./configure 中使用 --with-libpcre 编译时才有效) 。
  • 如果执行上述命令发现任何此类文件,请更正它们。 这涉及(至少在 Linux 上):
    • 设置core.autocrlf=input---更新3--
    • 更改文件
    • 恢复更改(文件仍显示为已更改)
    • 提交
  • 仅使用最低限度.gitattributes
  • 指示用户将上述 core.autocrlf 设置为其默认值。
  • 不要 100% 相信 .gitattributes 的存在。 IDE 的 git 客户端可能会忽略它们或以不同的方式对待它们。

正如所说,有些东西可以在 git 属性中添加:

# Always checkout with LF
*.sh            text eol=lf
# Always checkout with CRLF
*.bat           text eol=crlf

我认为 .gitattributes 的其他一些安全选项而不是对二进制文件使用自动检测:

  • -text(例如 < code>*.zip 或 *.jpg 文件:不会被视为文本,因此可能不会通过转换程序尝试进​​行行结束转换)
  • 。 text !eol (例如,对于*.java*.html:视为文本,但未设置 eol 样式首选项。因此使用客户端设置。 )
  • -text -diff -merge (例如对于 *.hugefile:不被视为文本。无法进行差异/合并)

--- 上一次更新 ---

一个 错误提交文件的客户端的痛苦示例

netbeans 8.2(在 Windows 上),将错误地使用 CRLF 提交所有文本文件,除非您有<强>显式将core.autocrlf设置为全局。 这与标准 git 客户端行为相矛盾,并在更新/合并时导致很多问题。 这就是为什么某些文件看起来不同(尽管事实并非如此)即使您恢复了的原因。

即使您已将正确的 .gitattributes 添加到项目中,netbeans 中也会发生相同的行为。

提交后使用以下命令,至少可以帮助您尽早检测 git 存储库是否存在行结束问题: git grep -I --files-with-matches --perl-regexp '\r' HEAD

我花了几个小时来想出 .gitattributes 的最佳用法,最终意识到我不能指望它。
不幸的是,只要基于 JGit 的编辑器存在(无法正确处理 .gitattributes),安全的解决方案就是在任何地方强制使用 LF,甚至在编辑器级别也是如此。

使用以下 抗CRLF消毒剂。

--- UPDATE 3 --- (does not conflict with UPDATE 2)

Considering the case that windows users prefer working on CRLF and linux/mac users prefer working on LF on text files. Providing the answer from the perspective of a repository maintainer:

For me the best strategy(less problems to solve) is: keep all text files with LF inside git repo even if you are working on a windows-only project. Then give the freedom to clients to work on the line-ending style of their preference, provided that they pick a core.autocrlf property value that will respect your strategy (LF on repo) while staging files for commit.

Staging is what many people confuse when trying to understand how newline strategies work. It is essential to undestand the following points before picking the correct value for core.autocrlf property:

  • Adding a text file for commit (staging it) is like copying the file to another place inside .git/ sub-directory with converted line-endings (depending on core.autocrlf value on your client config). All this is done locally.
  • setting core.autocrlf is like providing an answer to the question (exact same question on all OS): "Should git-client:
    • a. convert LF-to-CRLF when checking-out (pulling) the repo changes from the remote?
    • b. convert CRLF-to-LF when adding a file for commit?"
  • and the possible answers (values) are:
    • false: "do none of the above",
    • input: "do only b"
    • true: "do a and and b"
    • note that there is NO "do only a"

Fortunately

  • git client defaults (windows: core.autocrlf: true, linux/mac:
    core.autocrlf: false) will be compatible with LF-only-repo strategy.
    Meaning: windows clients will by default convert to CRLF when checking-out the repository and convert to LF when adding for commit. And linux clients will by default not do any conversions. This theoretically keeps your repo lf-only.

Unfortunately:

  • There might be GUI clients that do not respect the git core.autocrlf value
  • There might be people that don't use a value to respect your lf-repo strategy. E.g. they use core.autocrlf=false and add a file with CRLF for commit.

To detect ASAP non-lf text files committed by the above clients you can follow what is described on --- update 2 ---: (git grep -I --files-with-matches --perl-regexp '\r' HEAD, on a client compiled using: --with-libpcre flag)

And here is the catch:. I as a repo maintainer keep a git.autocrlf=input so that I can fix any wrongly committed files just by adding them again for commit. And I provide a commit text: "Fixing wrongly committed files".

As far as .gitattributes is concearned. I do not count on it, because there are more ui clients that do not understand it. I only use it to provide hints for text and binary files, and maybe flag some exceptional files that should everywhere keep the same line-endings:

*.java          text !eol # Don't do auto-detection. Treat as text (don't set any eol rule. use client's)
*.jpg           -text     # Don't do auto-detection. Treat as binary
*.sh            text eol=lf # Don't do auto-detection. Treat as text. Checkout and add with eol=lf
*.bat           text eol=crlf # Treat as text. Checkout and add with eol=crlf

Question: But why are we interested at all in newline handling strategy?

Answer: To avoid a single letter change commit, appear as a 5000-line change, just because the client that performed the change auto-converted the full file from crlf to lf (or the opposite) before adding it for commit. This can be rather painful when there is a conflict resolution involved. Or it could in some cases be the cause of unreasonable conflicts.


--- UPDATE 2 ---

The dafaults of git client will work in most cases. Even if you only have windows only clients, linux only clients or both. These are:

  • windows: core.autocrlf=true means convert lines to CRLF on checkout and convert lines to LF when adding files.
  • linux: core.autocrlf=input means don't convert lines on checkout (no need to since files are expected to be committed with LF) and convert lines to LF (if needed) when adding files.
    (-- update3 -- : Seems that this is false by default, but again it is fine)

The property can be set in different scopes. I would suggest explicitly setting in the --global scope, to avoid some IDE issues described at the end.

git config core.autocrlf
git config --global core.autocrlf
git config --system core.autocrlf
git config --local core.autocrlf
git config --show-origin core.autocrlf

Also I would strongly discourage using on windows git config --global core.autocrlf false (in case you have windows only clients) in contrast to what is proposed to git documentation. Setting to false will commit files with CRLF in the repo. But there is really no reason. You never know whether you will need to share the project with linux users. Plus it's one extra step for each client that joins the project instead of using defaults.

Now for some special cases of files (e.g. *.bat *.sh) which you want them to be checked-out with LF or with CRLF you can use .gitattributes

To sum-up for me the best practice is:

  • Make sure that every non-binary file is committed with LF on git repo (default behaviour).
  • Use this command to make sure that no files are committed with CRLF: git grep -I --files-with-matches --perl-regexp '\r' HEAD (Note: on windows clients works only through git-bash and on linux clients only if compiled using --with-libpcre in ./configure).
  • If you find any such files by executing the above command, correct them. This in involves (at least on linux):
    • set core.autocrlf=input (--- update 3 --)
    • change the file
    • revert the change(file is still shown as changed)
    • commit it
  • Use only the bare minimum .gitattributes
  • Instruct the users to set the core.autocrlf described above to its default values.
  • Do not count 100% on the presence of .gitattributes. git-clients of IDEs may ignore them or treat them differrently.

As said some things can be added in git attributes:

# Always checkout with LF
*.sh            text eol=lf
# Always checkout with CRLF
*.bat           text eol=crlf

I think some other safe options for .gitattributes instead of using auto-detection for binary files:

  • -text (e.g for *.zip or *.jpg files: Will not be treated as text. Thus no line-ending conversions will be attempted. Diff might be possible through conversion programs)
  • text !eol (e.g. for *.java,*.html: Treated as text, but eol style preference is not set. So client setting is used.)
  • -text -diff -merge (e.g for *.hugefile: Not treated as text. No diff/merge possible)

--- PREVIOUS UPDATE ---

One painful example of a client that will commit files wrongly:

netbeans 8.2 (on windows), will wrongly commit all text files with CRLFs, unless you have explicitly set core.autocrlf as global. This contradicts to the standard git client behaviour, and causes lots of problems later, while updating/merging. This is what makes some files appear different (although they are not) even when you revert.
The same behaviour in netbeans happens even if you have added correct .gitattributes to your project.

Using the following command after a commit, will at least help you detect early whether your git repo has line ending issues: git grep -I --files-with-matches --perl-regexp '\r' HEAD

I have spent hours to come up with the best possible use of .gitattributes, to finally realize, that I cannot count on it.
Unfortunately, as long as JGit-based editors exist (which cannot handle .gitattributes correctly), the safe solution is to force LF everywhere even on editor-level.

Use the following anti-CRLF disinfectants.

Spring初心 2024-07-13 21:19:04

当我在我的 Visual Studio 2010 项目。 开发团队的另外两名成员也使用 Windows 系统,因此混合环境没有发挥作用,但存储库附带的默认设置始终将所有文件标记为在克隆后立即更新。

我想最重要的是找到适合您的环境的 CRLF 设置。 特别是因为在我们的 Linux 机器上的许多其他存储库中设置 autocrlf = true 会产生更好的结果。

20 多年过去了,我们仍在处理操作系统之间的行尾差异......令人难过。

Using core.autocrlf=false stopped all the files from being marked updated as soon as I checked them out in my Visual Studio 2010 project. The other two members of the development team are also using Windows systems so a mixed environment didn't come into play, yet the default settings that came with the repository always marked all files as updated immediately after cloning.

I guess the bottom line is to find what CRLF setting works for your environment. Especially since in many other repositories on our Linux boxes setting autocrlf = true produces better results.

20+ years later and we're still dealing with line ending disparities between OSes... sad.

傲影 2024-07-13 21:19:04

尝试将 core.autocrlf 配置选项设置为 true。 另请查看 core.safecrlf 选项。

实际上,听起来 core.safecrlf 可能已经在您的存储库中设置了,因为(强调我的):

如果 core.autocrlf 的当前设置不是这种情况,git 将拒绝该文件

如果是这种情况,那么您可能需要检查您的文本编辑器是否配置为一致地使用行结尾。 如果文本文件包含 LF 和 CRLF 行结尾的混合,您可能会遇到问题。

最后,我认为简单地“使用你所得到的”并在 Windows 上使用 LF 终止行的建议会导致比它解决的问题更多的问题。 Git 有上述选项来尝试以合理的方式处理行结尾,因此使用它们是有意义的。

Try setting the core.autocrlf configuration option to true. Also have a look at the core.safecrlf option.

Actually it sounds like core.safecrlf might already be set in your repository, because (emphasis mine):

If this is not the case for the current setting of core.autocrlf, git will reject the file.

If this is the case, then you might want to check that your text editor is configured to use line endings consistently. You will likely run into problems if a text file contains a mixture of LF and CRLF line endings.

Finally, I feel that the recommendation to simply "use what you're given" and use LF terminated lines on Windows will cause more problems than it solves. Git has the above options to try to handle line endings in a sensible way, so it makes sense to use them.

故事与诗 2024-07-13 21:19:04

对于与 MacLinux 用户共享代码的 WindowsVisual Studio 用户来说,有两个选项。 有关详细说明,请阅读 gitattributes 手册

* text=auto

在存储库的 .gitattributes 文件中添加:

*   text=auto

这将规范存储库中以 LF 行结尾的所有文件。

根据您的操作系统(core.eol 设置),工作树中的文件将标准化为 LF(对于基于 Unix 的系统)或 CRLF对于 Windows 系统。

这是 Microsoft .NET 存储库使用的配置。

示例:

Hello\r\nWorld

将在存储库中始终标准化为:

Hello\nWorld

结帐时,Windows 中的工作树将转换为:

Hello\r\nWorld

结帐时,Mac 中的工作树将保留为:

Hello\nWorld

注意:如果您的存储库已包含未标准化的文件,则下次对这些文件进行任何更改时,git status 会将这些文件显示为已完全修改,并且其他用户可能会很痛苦稍后合并他们的更改。 请参阅刷新更改行结尾后的存储库以获取更多信息。

core.autocrlf = true

如果 .gitattributes 文件中未指定 text,Git 使用 core.autocrlf 配置变量来确定该文件是否应该被转换。

对于 Windows 用户,git config --global core.autocrlf true 是一个不错的选择,因为:

  • 文件仅在添加时标准化为 LF 行结尾到回购协议。 如果存储库中存在未标准化的文件,则此设置不会影响它们。
  • 所有文本文件都将转换为工作目录中的 CRLF 行结尾。

这种方法的问题在于:

  • 如果您是使用 autocrlf = input 的 Windows 用户,您将看到一堆带有 LF 行结尾的文件。 对于团队的其他成员来说这不是危险,因为您的提交仍将以 LF 行结尾进行标准化。
  • 如果您是使用 core.autocrlf = false 的 Windows 用户,您将看到一堆带有 LF 行结尾的文件,并且您可能会引入带有 CRLF 的文件code> 行结尾到存储库中。
  • 大多数 Mac 用户使用 autocrlf = input,并且可能会获取带有 CRLF 文件结尾的文件,这些文件可能来自带有 core.autocrlf = false 的 Windows 用户。

These are the two options for Windows and Visual Studio users that share code with Mac or Linux users. For an extended explanation, read the gitattributes manual.

* text=auto

In your repo's .gitattributes file add:

*   text=auto

This will normalize all the files with LF line endings in the repo.

And depending on your operating system (core.eol setting), files in the working tree will be normalized to LF for Unix based systems or CRLF for Windows systems.

This is the configuration that Microsoft .NET repos use.

Example:

Hello\r\nWorld

Will be normalized in the repo always as:

Hello\nWorld

On checkout, the working tree in Windows will be converted to:

Hello\r\nWorld

On checkout, the working tree in Mac will be left as:

Hello\nWorld

Note: If your repo already contains files not normalized, git status will show these files as completely modified the next time you make any change on them, and it could be a pain for other users to merge their changes later. See refreshing a repository after changing line endings for more information.

core.autocrlf = true

If text is unspecified in the .gitattributes file, Git uses the core.autocrlf configuration variable to determine if the file should be converted.

For Windows users, git config --global core.autocrlf true is a great option because:

  • Files are normalized to LF line endings only when added to the repo. If there are files not normalized in the repo, this setting will not touch them.
  • All text files are converted to CRLF line endings in the working directory.

The problem with this approach is that:

  • If you are a Windows user with autocrlf = input, you will see a bunch of files with LF line endings. Not a hazard for the rest of the team, because your commits will still be normalized with LF line endings.
  • If you are a Windows user with core.autocrlf = false, you will see a bunch of files with LF line endings and you may introduce files with CRLF line endings into the repo.
  • Most Mac users use autocrlf = input and may get files with CRLF file endings, probably from Windows users with core.autocrlf = false.
依 靠 2024-07-13 21:19:04

这只是一个解决方法解决方案:

在正常情况下,使用 git 附带的解决方案。 这些在大多数情况下都很有效。 如果您通过设置 .gitattributes 在基于 Windows 和 Unix 的系统上共享开发,则强制为 LF。

就我而言,有超过 10 名程序员在 Windows 中开发一个项目。 这个项目是用 CRLF 签入的,没有强制换成 LF 的选项。

一些设置是在我的机器上内部编写的,对 LF 格式没有任何影响; 因此,在每次小文件更改时,某些文件都会全局更改为 LF。

我的解决方案:

Windows 机器:
让一切保持原样。 无需关心任何事情,因为您是默认的 Windows“独狼”开发人员,并且您必须这样处理:“世界上没有其他系统,不是吗?”

Unix-Machines

  1. 将以下行添加到配置的 [alias] 部分。 此命令列出所有已更改(即修改/新)的文件:

    lc = "!f() { git status --porcelain \ 
                   |   egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \ 
                   |   切-c 4- ;   };   F ” 
      
  2. 将所有这些已更改文件转换为 dos 格式:

    unix2dos $(git lc) 
      
  3. 可选...

    1. 为此创建一个 git 钩子自动化此过程的操作

    2. 使用参数并包含它并修改 grep 函数以仅匹配特定文件名,例如:

      <代码>... |   egrep -r "^(\?| ).*\.(txt|conf)" |   ... 
        
    3. 随意使用额外的快捷方式使其更加方便:

      c2dos = "!f() { unix2dos $(git lc) ; }; f " 
        

      ...并通过键入来触发转换后的内容

      git c2dos 
        

This is just a workaround solution:

In normal cases, use the solutions that are shipped with git. These work great in most cases. Force to LF if you share the development on Windows and Unix based systems by setting .gitattributes.

In my case there were >10 programmers developing a project in Windows. This project was checked in with CRLF and there was no option to force to LF.

Some settings were internally written on my machine without any influence on the LF format; thus some files were globally changed to LF on each small file change.

My solution:

Windows-Machines:
Let everything as it is. Care about nothing, since you are a default windows 'lone wolf' developer and you have to handle like this: "There is no other system in the wide world, is it?"

Unix-Machines

  1. Add following lines to a config's [alias] section. This command lists all changed (i.e. modified/new) files:

    lc = "!f() { git status --porcelain \
                 | egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \
                 | cut -c 4- ; }; f "
    
  2. Convert all those changed files into dos format:

    unix2dos $(git lc)
    
  3. Optionally ...

    1. Create a git hook for this action to automate this process

    2. Use params and include it and modify the grep function to match only particular filenames, e.g.:

      ... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
      
    3. Feel free to make it even more convenient by using an additional shortcut:

      c2dos = "!f() { unix2dos $(git lc) ; }; f "
      

      ... and fire the converted stuff by typing

      git c2dos
      
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文