简体   繁体   English

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

[英]Force LF eol in git repo and working copy

I have a git repository hosted on github. Many of the files were initially developed on Windows, and I wasn't too careful about line endings.我在 github 上有一个 git 存储库。许多文件最初是在 Windows 上开发的,我不太注意行尾。 When I performed the initial commit, I also didn't have any git configuration in place to enforce correct line endings.当我执行初始提交时,我也没有任何 git 配置来强制执行正确的行尾。 The upshot is that I have a number of files with CRLF line endings in my github repository.结果是我的 github 存储库中有许多带有 CRLF 行结尾的文件。

I'm now developing partially on Linux, and I'd like to clean up the line endings.我现在在 Linux 上进行部分开发,我想清理行尾。 How can I ensure the files are stored correctly with LF on github, and have LF in my working copy?如何确保文件在 github 上使用 LF 正确存储,并在我的工作副本中包含 LF?

I've set up a .gitattributes file containing text eol=LF ;我已经设置了一个包含text eol=LF.gitattributes文件; is that correct?那是对的吗? With that committed and pushed, can I just rm my local repo and re-clone from github to get the desired effect?有了这个承诺和推动,我可以只rm我的本地 repo 并从 github 重新克隆以获得预期的效果吗?

Without a bit of information about what files are in your repository (pure source code, images, executables, ...), it's a bit hard to answer the question :)如果没有关于您的存储库中有哪些文件的一些信息(纯源代码、图像、可执行文件等),回答这个问题有点困难:)

Beside this, I'll consider that you're willing to default to LF as line endings in your working directory because you're willing to make sure that text files have LF line endings in your .git repository wether you work on Windows or Linux.除此之外,我认为您愿意将 LF 默认为工作目录中的行尾,因为无论您在 Windows 还是 Linux 上工作,您都愿意确保文本文件在 .git 存储库中具有 LF 行尾. Indeed better safe than sorry....确实比抱歉更安全......

However, there's a better alternative: Benefit from LF line endings in your Linux workdir, CRLF line endings in your Windows workdir AND LF line endings in your repository.但是,还有一个更好的选择:受益于 Linux 工作目录中的 LF 行结尾、Windows 工作目录中的 CRLF 行结尾和存储库中的 LF 行结尾。

As you're partially working on Linux and Windows, make sure core.eol is set to native and core.autocrlf is set to true .当您部分使用 Linux 和 Windows 时,请确保将core.eol设置为native并且将core.autocrlf设置为true

Then, replace the content of your .gitattributes file with the following然后,用以下内容替换.gitattributes文件的内容

* text=auto

This will let Git handle the automagic line endings conversion for you, on commits and checkouts.这将使 Git 在提交和检出时为您处理自动换行符。 Binary files won't be altered, files detected as being text files will see the line endings converted on the fly.二进制文件不会被更改,被检测为文本文件的文件将看到行尾动态转换。

However, as you know the content of your repository, you may give Git a hand and help him detect text files from binary files.但是,当您知道存储库的内容时,您可以帮助 Git 并帮助他从二进制文件中检测文本文件。

Provided you work on a C based image processing project, replace the content of your .gitattributes file with the following如果您从事基于 C 的图像处理项目,请将.gitattributes文件的内容替换为以下内容

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

This will make sure files which extension is c, h, or txt will be stored with LF line endings in your repo and will have native line endings in the working directory.这将确保扩展名为 c、h 或 txt 的文件将与 LF 行结尾一起存储在您的存储库中,并且将在工作目录中具有本机行结尾。 Jpeg files won't be touched. Jpeg 文件不会被触及。 All of the others will be benefit from the same automagic filtering as seen above.所有其他人都将受益于与上述相同的自动过滤。

In order to get a get a deeper understanding of the inner details of all this, I'd suggest you to dive into this very good post "Mind the end of your line" from Tim Clem, a Githubber.为了更深入地了解所有这些的内部细节,我建议您深入阅读 Githubber 上的 Tim Clem 的这篇非常好的帖子“注意行尾”

As a real world example, you can also peek at this commit where those changes to a .gitattributes file are demonstrated.作为一个真实世界的例子,您还可以查看此提交,其中演示了对.gitattributes文件的更改。

UPDATE to the answer considering the following comment考虑以下评论更新答案

I actually don't want CRLF in my Windows directories, because my Linux environment is actually a VirtualBox sharing the Windows directory我实际上不想在我的 Windows 目录中使用 CRLF,因为我的 Linux 环境实际上是一个共享 Windows 目录的 VirtualBox

Makes sense.说得通。 Thanks for the clarification.感谢您的澄清。 In this specific context, the .gitattributes file by itself won't be enough.在这个特定的上下文中, .gitattributes文件本身是不够的。

Run the following commands against your repository针对您的存储库运行以下命令

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

As your repository is shared between your Linux and Windows environment, this will update the local config file for both environment.由于您的存储库在 Linux 和 Windows 环境之间共享,因此这将更新两个环境的本地配置文件。 core.eol will make sure text files bear LF line endings on checkouts. core.eol将确保文本文件在结帐时带有 LF 行结尾。 core.autocrlf will ensure potential CRLF in text files (resulting from a copy/paste operation for instance) will be converted to LF in your repository. core.autocrlf将确保文本文件中的潜在CRLF(例如由复制/粘贴操作产生)将在您的存储库中转换为 LF。

Optionally, you can help Git distinguish what is a text file by creating a .gitattributes file containing something similar to the following:或者,您可以通过创建包含类似于以下内容的.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

If you decided to create a .gitattributes file, commit it .如果您决定创建一个.gitattributes文件,请提交它

Lastly, ensure git status mentions "nothing to commit (working directory clean)" , then perform the following operation最后,确保git status提到"nothing to commit (working directory clean)" ,然后执行以下操作

$ git checkout-index --force --all

This will recreate your files in your working directory, taking into account your config changes and the .gitattributes file and replacing any potential overlooked CRLF in your text files.这将在您的工作目录中重新创建您的文件,考虑您的配置更改和.gitattributes文件并替换文本文件中任何可能被忽视的 CRLF。

Once this is done, every text file in your working directory WILL bear LF line endings and git status should still consider the workdir as clean.完成此操作后,您工作目录中的每个文本文件都将带有 LF 行结尾,并且git status仍应将工作目录视为干净的。

Starting with git 2.10 (released 2016-09-03), it is not necessary to enumerate each text file separately.从 git 2.10(2016-09-03 发布)开始,不需要单独枚举每个文本文件。 Git 2.10 fixed the behavior of text=auto together with eol=lf . Git 2.10 修复了 text=auto 和 eol=lf 的行为 Source .来源

.gitattributes file in the root of your git repository: git 存储库根目录中的.gitattributes文件:

* text=auto eol=lf

Add and commit it.添加并提交它。

Afterwards, you can do following to steps and all files are normalized now:之后,您可以执行以下步骤,现在所有文件都已标准化:

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.

Source: Answer by kenorb .资料来源: kenorb 的回答

To force LF line endings for all text files, you can create .gitattributes file in top-level of your repository with the following lines (change as desired):要强制所有文本文件使用 LF 行结尾,您可以使用以下行(根据需要更改)在存储库的顶层创建.gitattributes文件:

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

which ensures that all files that Git considers to be text files have normalized ( LF ) line endings in the repository (normally core.eol configuration controls which one do you have by default).这确保 Git 认为是文本文件的所有文件都在存储库中标准化 ( LF ) 行结尾(通常core.eol配置控制默认情况下您拥有哪个)。

Based on the new attribute settings, any text files containing CRLFs should be normalized by Git.基于新的属性设置,任何包含 CRLF 的文本文件都应该被 Git 规范化。 If this won't happen automatically, you can refresh a repository manually after changing line endings, so you can re-scan and commit the working directory by the following steps (given clean working directory):如果这不会自动发生,您可以在更改行结尾后手动刷新存储库,因此您可以通过以下步骤重新扫描并提交工作目录(给定干净的工作目录):

$ 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"

or as per GitHub docs :或根据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.

See also: @Charles Bailey post .另见: @Charles Bailey 帖子

In addition, if you would like to exclude any files to not being treated as a text, unset their text attribute, eg此外,如果您想排除任何文件不被视为文本,请取消设置它们的文本属性,例如

manual.pdf      -text

Or mark it explicitly as binary:或者将其明确标记为二进制:

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

To see some more advanced git normalization file, check .gitattributes at Drupal core :要查看一些更高级的 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

See also:也可以看看:

I was cloning the Chromium depot_tools to my mac and all files of the work copy were ended with CRLF.我正在将 Chromium depot_tools克隆到我的 mac 上,工作副本的所有文件都以 CRLF 结尾。 I found this script which fixed my problem.我发现这个脚本解决了我的问题。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM