在git repo和工作副本中强制LF eol


170

我在github上托管了一个git存储库。许多文件最初是在Windows上开发的,我对行尾不太谨慎。在执行初始提交时,我也没有任何git配置来强制执行正确的行尾。结果是我的github仓库中有许多CRLF行结尾的文件。

我现在正在Linux上进行部分开发,我想清理行尾。如何确保使用LF在github上正确存储文件,并在我的工作副本中包含LF?

我已经建立了一个.gitattributes包含text eol=LF; 那是对的吗?提交并推送后,我是否可以rm从github重新克隆本地存储库并重新获得所需的效果?




这些都不是我要的。我是唯一的开发人员,我很愿意以相同的方式设置所有机器。我有一个现有的回购协议,其中已经提交了一些CRLF文件,并且在不同的计算机上有几个克隆。如何更新仓库和每个工作副本,以便到处都有LF?
Chowlett

您看过这个 Github指南吗?
安迪

Answers:


237

没有有关存储库中哪些文件的信息(纯源代码,图像,可执行文件...),很难回答这个问题:)

除此之外,我认为您愿意在工作目录中默认使用LF作为行尾,因为您愿意确保在Windows或Linux上工作时,文本文件在.git存储库中都具有LF行尾。 。确实比后悔更好....

但是,还有更好的选择:受益于Linux工作目录中的LF行结尾,Windows工作目录中的CRLF行结尾以及存储库中的LF行结尾。

在Linux和Windows上部分工作时,请确保core.eol将设置为,native并将core.autocrlf其设置为true

然后,将.gitattributes文件内容替换为以下内容

* text=auto

这将使Git在提交和结帐时为您处理自动行尾转换。二进制文件不会被更改,被检测为文本文件的文件将看到行尾的转换。

但是,您知道存储库的内容后,可以帮助Git并帮助他从二进制文件中检测文本文件。

如果您从事基于C的图像处理项目,请.gitattributes使用以下内容替换文件内容

* text=auto
*.txt text
*.c text
*.h text
*.jpg binary

这将确保扩展名为c,h或txt的文件将以LF行尾存储在您的存储库中,并将在工作目录中包含本机行尾。不会触摸Jpeg文件。其他所有功能都将从上述相同的自动过滤中受益。

为了更深入地了解所有这些内容,我建议您深入阅读Githubber的Tim Clem撰写的一篇很好的文章“ Mind your line of end”

作为一个真实的例子,您还可以查看此提交,在该提交中将.gitattributes展示对文件的那些更改。

考虑以下评论的答案更新

我实际上不想在Windows目录中使用CRLF,因为我的Linux环境实际上是共享Windows目录的VirtualBox

说得通。感谢您的澄清。在这种特定情况下,.gitattributes文件本身是不够的。

对您的存储库运行以下命令

$ git config core.eol lf
$ git config core.autocrlf input

由于您的存储库在Linux和Windows环境之间共享,因此这将更新两个环境的本地配置文件。core.eol将确保文本文件在结帐时带有LF行尾。core.autocrlf将确保文本文件中的潜在 CRLF(例如,由于复制/粘贴操作而产生)将在您的存储库中转换为LF。

或者,你可以帮助的Git分清哪些通过创建一个文本文件.gitattributes包含类似以下内容的文件:

# Autodetect text files
* text=auto

# ...Unless the name matches the following
# overriding patterns

# Definitively text files 
*.txt text
*.c text
*.h text

# Ensure those won't be messed up with
*.jpg binary
*.data binary

如果您决定创建一个.gitattributes文件,请提交它

最后,确保git status提及“什么都不提交(工作目录干净)”,然后执行以下操作

$ git checkout-index --force --all

这将在您的工作目录中重新创建文件,同时考虑到配置更改和.gitattributes文件,并替换文本文件中任何可能被忽略的CRLF。

完成此操作后,工作目录中的每个文本文件都将带有LF行结尾,并且git status仍应将workdir视为干净的。


34
实际上,我不想在Windows目录中使用CRLF,因为我的Linux环境实际上是共享Windows目录的VirtualBox。虽然Notepad ++等可以在Windows上仅处理LF,vi但对CRLF不太满意。难道我只是想改变它,这样core.autocrlffalse(或input)?
Chowlett

5
极好的答案。使用此设置的其他用户的快速注意事项:行“ * text = auto”应该是.gitattributes文件中的第一行,以便后续行可以覆盖该设置。
阿里·帕特里克

9
@CMCDragonkai取决于您的外壳,git checkout-index --force --all可能效果更好。第二点看起来与原始问题无关。问一个专门的问题怎么样?
nulltoken

8
我不明白为什么.gitattributes无法处理在Linux和Windows之间共享工作副本的情况。我们是否可以通过和设置texteol=lf获得与您的答案中所述相同的结果?core.eolcore.autocrlf
DanielSank 2014年

10
git checkout-index --force --all对我没有任何帮助。起作用的是GitHub指令中用于解决此问题的命令列表
罗曼·斯塔科夫

126

从git 2.10(发布于2016-09-03)开始,不必分别枚举每个文本文件。Git 2.10修复了text = auto和eol = lf的行为来源

.gitattributes git存储库根目录中的文件:

* text=auto eol=lf

添加并提交。

之后,您可以按照以下步骤进行操作,现在所有文件都已标准化:

git rm --cached -r .  # Remove every file from git's index.
git reset --hard      # Rewrite git's index to pick up all the new line endings.

资料来源:kenorb回答


7
Git 2.10已于2016
。– Stil

我运行了它,它使我的所有非文本文件变砖了
Anthony

您可以为某些文件显式设置二进制模式。-我不知道为什么某些文件的自动检测仍然(仍然?!)
koppor

这应该是公认的答案。
CletusW

25

要强制所有文本文件使用LF行结尾,您可以.gitattributes在存储库的顶层使用以下行创建文件(根据需要更改):

# Ensure all C and PHP files use LF.
*.c         eol=lf
*.php       eol=lf

这样可以确保Git认为所有文本文件都LF在存储库中具有规范化()行结尾(通常是core.eol配置控制您默认拥有哪个)。

基于新的属性设置,任何包含CRLF的文本文件都应由Git进行规范化。如果这不会自动发生,那么您可以在更改行尾后手动刷新存储库,因此您可以按照以下步骤重新扫描并提交工作目录(给出干净的工作目录):

$ echo "* text=auto" >> .gitattributes
$ rm .git/index     # Remove the index to force Git to
$ git reset         # re-scan the working directory
$ git status        # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"

或根据GitHub docs

git add . -u
git commit -m "Saving files before refreshing line endings"
git rm --cached -r . # Remove every file from Git's index.
git reset --hard # Rewrite the Git index to pick up all the new line endings.
git add . # Add all your changed files back, and prepare them for a commit.
git commit -m "Normalize all the line endings" # Commit the changes to your repository.

另请参阅:@Charles Bailey帖子

另外,如果您想排除任何不被视为文本的文件,请取消设置其文本属性,例如

manual.pdf      -text

或将其明确标记为二进制:

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary

看到一些更高级的git的规范化文件,检查.gitattributesDrupal核心

# Drupal git normalization
# @see https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
# @see https://www.drupal.org/node/1542048

# Normally these settings would be done with macro attributes for improved
# readability and easier maintenance. However macros can only be defined at the
# repository root directory. Drupal avoids making any assumptions about where it
# is installed.

# Define text file attributes.
# - Treat them as text.
# - Ensure no CRLF line-endings, neither on checkout nor on checkin.
# - Detect whitespace errors.
#   - Exposed by default in `git diff --color` on the CLI.
#   - Validate with `git diff --check`.
#   - Deny applying with `git apply --whitespace=error-all`.
#   - Fix automatically with `git apply --whitespace=fix`.

*.config  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.css     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.dist    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.engine  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.html    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=html
*.inc     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.install text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.js      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.json    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.lock    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.map     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.md      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.module  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.php     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.po      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.profile text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.script  text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.sh      text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.sql     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.svg     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.theme   text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.twig    text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.txt     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.xml     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.yml     text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2

# Define binary file attributes.
# - Do not treat them as text.
# - Include binary diff in patches instead of "binary files differ."
*.eot     -text diff
*.exe     -text diff
*.gif     -text diff
*.gz      -text diff
*.ico     -text diff
*.jpeg    -text diff
*.jpg     -text diff
*.otf     -text diff
*.phar    -text diff
*.png     -text diff
*.svgz    -text diff
*.ttf     -text diff
*.woff    -text diff
*.woff2   -text diff

也可以看看:


2
1. text=auto具有误导性。您不能一起使用text=autoeol。设置eol禁用自动检测文本文件。这就是为什么必须指定所有这些文件类型的原因。如果auto启用,则不需要所有这些。2.您不需要texteol=lfeol=lf有效设置text
2016年

2
@Ben所说的第二点,如果您未明确标记所有二进制文件,则此配置当前错误且危险。
Michael R

1
我已经读到* text=auto eol=lf第一个text=auto被覆盖eol=lf。您在哪里找到此功能?下面是我的源:stackoverflow.com/questions/29435156/...
CMCDragonkai

* text=auto eol=lf从示例中删除,因为它也从Drupal 中删除。也考虑删除评论。
kenorb

4
重要的是要注意,@ Ben所说的不再正确,它始终是一个错误-并非预期的行为。
塞梅尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.