我在Windows上遇到core.autocrlf
已停用:
$ git config core.autocrlf; git config --global core.autocrlf
false
false
现在,我认为,git不会破坏任何行结尾,但我的仓库中的某些文件会导致问题。
我刚刚克隆了一份repo的新副本,git已经告诉我有没有分期更改。当我git diff -R
时,我可以看到CRLF行结尾已添加到文件中:
diff --git b/nginx-1.11.1/contrib/geo2nginx.pl a/nginx-1.11.1/contrib/geo2nginx.pl
index bc8af46..29243ec 100644
--- b/nginx-1.11.1/contrib/geo2nginx.pl
+++ a/nginx-1.11.1/contrib/geo2nginx.pl
@@ -1,58 +1,58 @@
-#!/usr/bin/perl -w
-
-# (c) Andrei Nigmatulin, 2005
+#!/usr/bin/perl -w^M
+^M
+# (c) Andrei Nigmatulin, 2005^M
我不明白这些行结尾的来源,但我也无法回复"这种变化。当我再次签出文件时,之后仍然会对其进行修改:
$ git checkout -f nginx-1.11.1/contrib/geo2nginx.pl
$ git status
On branch dev
Your branch is up-to-date with 'origin/dev'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: nginx-1.11.1/contrib/geo2nginx.pl
no changes added to commit (use "git add" and/or "git commit -a")
这对我没用,所以我只在文件上运行dos2unix
:
$ dos2unix nginx-1.11.1/contrib/geo2nginx.pl
dos2unix: converting file nginx-1.11.1/contrib/geo2nginx.pl to Unix format...
现在肯定不会有任何改变,对吧?但该文件仍在git status
中显示为已修改,git diff
仍会在工作副本中报告CRLF行结尾。
当我现在暂存并提交文件时,生成的文件将具有LF行结尾,即使差异显示CRLF行结尾。
我没有全局.gitattributes
(git config --global core.attributesfile
不输出任何内容)。项目中的.gitattributes
已* text eol=lf
设置(full .gitattributes
)。
这里发生了什么,我该如何解决?
我可以使用开源project I'm maintaining来重现此问题:
$ git clone git@github.com:fairmanager/fm-log.git
Cloning into 'fm-log'...
remote: Counting objects: 790, done.
remote: Total 790 (delta 0), reused 0 (delta 0), pack-reused 790
Receiving objects: 100% (790/790), 201.71 KiB | 138.00 KiB/s, done.
Resolving deltas: 100% (418/418), done.
Checking connectivity... done.
$ cd fm-log/
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: .idea/dictionaries/OliverSalzburg.xml
modified: .idea/inspectionProfiles/Project_Default.xml
modified: .idea/inspectionProfiles/profiles_settings.xml
no changes added to commit (use "git add" and/or "git commit -a")
答案 0 :(得分:5)
有趣的是:通过新添加到问题的回购,我尝试克隆它,在BSD上看到同样的事情:
$ git clone git@github.com:fairmanager/fm-log.git
Cloning into 'fm-log'...
remote: Counting objects: 790, done.
remote: Total 790 (delta 0), reused 0 (delta 0), pack-reused 790
Receiving objects: 100% (790/790), 201.71 KiB | 0 bytes/s, done.
Resolving deltas: 100% (418/418), done.
Checking connectivity... done.
$ cd fm-log/
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: .idea/dictionaries/OliverSalzburg.xml
modified: .idea/inspectionProfiles/Project_Default.xml
modified: .idea/inspectionProfiles/profiles_settings.xml
no changes added to commit (use "git add" and/or "git commit -a")
试着看看发生了什么:
$ git diff
warning: CRLF will be replaced by LF in .idea/dictionaries/OliverSalzburg.xml.
[snip]
似乎HEAD:.idea/
个文件实际上有回车符(并且最后一行没有换行符,因此在关闭尖括号后面的提示符):
$ git show HEAD:.idea/dictionaries/OliverSalzburg.xml | vis
<component name="ProjectDictionaryState">\^M
<dictionary name="OliverSalzburg">\^M
<words>\^M
<w>colorizer</w>\^M
<w>multiline</w>\^M
</words>\^M
</dictionary>\^M
</component>$
工作树版本同样具有回车符(没有剪切和粘贴,但vis
显示相同的\^M
行结尾。)
所以在这种情况下发生的事情,至少是由于.gitattributes
设置:
$ head -2 .gitattributes
# In general, use LF for text
* text eol=lf
Git会在提交期间将这些文件转换为LF,而不是包含CR-LF结尾的HEAD
版本。这就是git status
在这里所说的内容。
评论* text eol=lf
中的.gitattributes
会使状态消失(因为文件不会被转换),当然.gitattributes
现在已标记为已修改。有趣的是,再次返回属性行,状态完全无声:强制git checkout
替换工作树版本以获取状态(例如,手动rm -rf .idea
并再次检出,或git reset --hard
)。
(大概 - 我在这里猜一点 - 当Git注意到工作树和HEAD版本不同时,索引条目在git checkout
期间被特别标记。这使得Git密切检查文件。修改{{通过.gitattributes
运行内部差异可能会取消标记索引条目。这部分是纯粹的推测,旨在解释git status
的奇怪行为...)
答案 1 :(得分:2)
如果本地设置git config core.autocrlf
确实属于false
,那么这些eol更改必须来自.gitattributes
file(请参阅man page)。
在您的本地仓库中查找一个包含eol规则的内容(例如* text=auto eol=crlf
我mentioned here)。
或check if you have a global gitattributes档案。
git config --global core.attributesfile
关于fairmanager/fm-log
,你可以看到commit e6f823b中添加了一个“修改过的”文件.idea/dictionaries/OliverSalzburg.xml
,最后是crlf。
由于the .gitattributes
具有* text eol=lf
规则,因此工作目录结帐使用lf eol blob,因此git diff
。