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

我现在正在Linux上进行部分开发,我想清除行结束符。我如何能确保文件正确存储与LF在github上,并有LF在我的工作副本?

我已经设置了一个包含文本eol=LF的.gitattributes文件;对吗?有了承诺和推动,我可以只是rm我的本地回购和重新克隆从github得到想要的效果吗?


如果没有一点关于存储库中文件的信息(纯源代码、图像、可执行文件……),就很难回答这个问题:)

除此之外,我将认为您愿意在工作目录中默认使用LF作为行结束符,因为您愿意确保.git存储库中文本文件具有LF行结束符,无论您是在Windows还是Linux上工作。的确,安全总比遗憾好....

然而,有一个更好的选择:受益于Linux工作目录中的LF行结束符,Windows工作目录中的CRLF行结束符和存储库中的LF行结束符。

因为你的部分工作是在Linux和Windows上进行的,所以请确保使用core。Eol被设置为原生和核心。selflf被设置为true。

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

* text=auto

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

但是,由于您了解存储库的内容,您可以帮助Git从二进制文件中检测文本文件。

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

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

这将确保扩展名为c、h或txt的文件将在repo中以LF行结束符存储,并在工作目录中具有本机行结束符。Jpeg文件将不会被触及。所有其他的将受益于相同的自动过滤如上所示。

为了更深入地了解这一切的内在细节,我建议你深入研究这篇非常好的帖子“注意你的底线”,来自Tim Clem, Githubber。

作为一个真实的例子,您还可以查看这个提交,其中演示了对.gitattributes文件的更改。

更新答案考虑以下评论

我实际上不希望CRLF在我的Windows目录中,因为我的Linux环境实际上是一个共享Windows目录的VirtualBox

是有意义的。谢谢你的澄清。在这个特定的上下文中,.gitattributes文件本身是不够的。

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

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

由于您的存储库在Linux和Windows环境之间共享,这将更新两个环境的本地配置文件。核心。eol将确保文本文件在签出时采用LF行结束符。核心。selflf将确保文本文件中潜在的CRLF(例如,由复制/粘贴操作产生的)将转换为存储库中的LF。

可选的,你可以通过创建一个.gitattributes文件来帮助Git区分什么是文本文件,该文件包含类似以下内容:

# 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状态提到“nothing to commit(工作目录清洁)”,然后执行以下操作

$ git checkout-index --force --all

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

一旦这样做了,你的工作目录中的每个文本文件都将带有LF行结束符,git状态仍然认为工作目录是干净的。


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

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

这确保Git认为是文本文件的所有文件在存储库(通常是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文档:

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规范化文件,请检查Drupal核心的.gitattributes:

# 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

参见:

处理行结束在GitHub 当使用vagrant: Windows CRLF到Unix LF问题


从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的回答。


我正在克隆Chromium depot_tools到我的mac上,工作副本的所有文件都以CRLF结束。我发现这个脚本解决了我的问题。

cd <your repo>
# config the local repo to use LF
git config core.eol lf
git config core.autocrlf input

# Copy files from the index to the working tree
git checkout-index --force --all

# If above line doesn't work, delete all cached files and reset.
git rm --cached -r .
git reset --hard