我在Windows上,我已core.autocrlf禁用:
$ git config core.autocrlf; git config --global core.autocrlf
false
false
Run Code Online (Sandbox Code Playgroud)
现在,我认为,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
Run Code Online (Sandbox Code Playgroud)
我不明白这些行结尾的来源,但我也无法"恢复"这种变化.当我再次签出文件时,它仍将在以后修改:
$ 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")
Run Code Online (Sandbox Code Playgroud)
这对我没有意义,所以我只是运行dos2unix文件:
$ dos2unix nginx-1.11.1/contrib/geo2nginx.pl
dos2unix: converting file nginx-1.11.1/contrib/geo2nginx.pl to Unix format...
Run Code Online (Sandbox Code Playgroud)
现在肯定不应该有任何改变,对吧?但该文件仍显示为已修改,git status并git diff仍将在工作副本中报告CRLF行结尾.
当我现在暂存并提交文件时,生成的文件将具有LF行结尾,即使diff显示CRLF行结尾.
我没有全局.gitattributes(git config --global core.attributesfile不输出任何东西).并且.gitattributes在项目中* text eol=lf设置(完整.gitattributes).
这里发生了什么,我该如何解决这个问题?
$ 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")
Run Code Online (Sandbox Code Playgroud)
有趣的是:使用新添加到问题的仓库,我尝试克隆它,在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")
Run Code Online (Sandbox Code Playgroud)
试着看看发生了什么:
$ git diff
warning: CRLF will be replaced by LF in .idea/dictionaries/OliverSalzburg.xml.
[snip]
Run Code Online (Sandbox Code Playgroud)
看来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>$
Run Code Online (Sandbox Code Playgroud)
工作树版本同样具有回车符(没有剪切和粘贴,但vis显示相同的\^M行结尾).
所以在这种情况下发生的事情至少是由于以下原因.gitattributes:
$ head -2 .gitattributes
# In general, use LF for text
* text eol=lf
Run Code Online (Sandbox Code Playgroud)
Git会在提交期间将这些文件转换为LF,而HEAD不是包含CR-LF结尾的版本.这就是git status这里所说的.
该注出* text eol=lf在.gitattributes使得状况消失(因为这些文件将不被转换),但当然.gitattributes现在被标记为修改.有趣的是,再次返回属性行,状态完全无声:必须强制git checkout替换工作树版本以获取状态(例如,手动rm -rf .idea并再次签出,或git reset --hard).
(据推测 - 我在这里猜测一下 - git checkout当Git注意到工作树和HEAD版本不同时,索引条目会被特别标记.这使得Git会仔细检查文件.修改.gitattributes并运行内部差异git status可能是未标记的索引条目.这部分是纯粹的炒作的意思来解释的怪异的行为git status...)
| 归档时间: |
|
| 查看次数: |
3248 次 |
| 最近记录: |