【问题标题】:Force LF eol in git repo and working copy在 git repo 和工作副本中强制 LF eol
【发布时间】:2012-04-16 03:30:36
【问题描述】:

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

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

我已经建立了一个包含text eol=LF.gitattributes 文件;那是对的吗?有了这个提交和推送,我可以只 rm 我的本地 repo 并从 github 重新克隆以获得预期的效果吗?

【问题讨论】:

  • 这些都不是我要问的。我是唯一的开发人员,我非常愿意将我所有的机器设置为相同。我有一个现有的存储库,其中已经提交了一些 CRLF 文件,以及不同机器上的几个克隆。如何更新 repo 和每个工作副本,以便到处都有 LF?
  • 你看过this Github指南吗?

标签: git github eol


【解决方案1】:

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

除此之外,我认为您愿意在工作目录中默认使用 LF 作为行尾,因为您愿意确保文本文件在您的 .git 存储库中具有 LF 行尾Windows 或 Linux。确实比抱歉更安全....

但是,还有一个更好的选择:受益于 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 行结尾存储在您的 repo 中,并且在工作目录中将具有本地行结尾。 Jpeg 文件不会被触及。所有其他人都将受益于与上述相同的自动过滤。

为了更深入地了解这一切的内在细节,我建议您深入研究来自 Githubber 的 Tim Clem 的这篇非常好的帖子 "Mind the end of your line"

作为一个真实的示例,您还可以查看此 commit,其中演示了对 .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。

或者,您可以通过创建包含类似于以下内容的 .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 status提到“nothing to commit (working directory clean)”,然后执行以下操作

$ git checkout-index --force --all

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

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

【讨论】:

  • 我其实不希望在我的 Windows 目录中使用 CRLF,因为我的 Linux 环境实际上是一个共享 Windows 目录的 VirtualBox;虽然 Notepad++ 等可以在 Windows 上仅处理 LF,但 vi 对 CRLF 不太满意。我是否只想将其更改为 core.autocrlffalse(或 input)?
  • 优秀的答案。使用此设置的其他人的快速说明:“* text=auto”行应该是 .gitattributes 文件中的第一行,以便后续行可以覆盖该设置。
  • @CMCDragonkai 根据您的外壳,git checkout-index --force --all 可能会更好。关于原始问题,第二点看起来有点偏离主题。问一个专门的问题怎么样?
  • 我不明白为什么 .gitattributes 无法处理在 Linux 和 Windows 之间共享工作副本的情况。我们可以不设置texteol=lf 以通过core.eolcore.autocrlf 达到您在回答中描述的相同结果吗?
  • git checkout-index --force --all 对我没有任何帮助。 list of commands in the GitHub instructions 可以解决这个问题。
【解决方案2】:

从 Git 2.10(2016-09-03 发布)开始,无需单独枚举每个文本文件。 Git 2.10 fixed the behavior of text=auto together with eol=lfSource.

.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.

来源:Answer by kenorb

【讨论】:

  • Git 2.10 已于 2016 年 9 月 3 日发布。
  • 我运行了这个,它把我所有的非文本文件都变砖了
  • 您可以为某些文件显式设置二进制模式。 - 我想知道为什么某些文件的自动检测(仍然?!)被破坏了
【解决方案3】:

要对所有文本文件强制使用 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 post

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

manual.pdf      -text

或将其显式标记为二进制:

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

要查看更高级的 git 规范化文件,请查看.gitattributes Drupal core

# 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

另见:

【讨论】:

  • 1. text=auto 具有误导性。您不能同时使用text=autoeol。设置eol 禁用自动检测文本文件。这就是为什么您必须指定所有这些文件类型的原因。如果启用了auto,则不需要所有这些。 2. 你不需要texteol=lfeol=lf 有效地设置了text
  • 第二个 @Ben 说的,如果你没有明确标记所有的二进制文件,这个配置目前是错误和危险的。
  • 我读到* text=auto eol=lf 第一个text=autoeol=lf 覆盖。你在哪里找到这个功能的?这是我的来源:stackoverflow.com/questions/29435156/…
  • 从示例中删除了 * text=auto eol=lf,因为它也是来自 Drupal 的 removed。也可以考虑移除 cmets。
  • 重要的是要注意@Ben 所说的不再正确,它始终是一个错误 - 不是预期的行为。
【解决方案4】:

我正在将 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    • 2011-11-06
    • 2014-11-01
    相关资源
    最近更新 更多