我很高兴Git本身如何通过core.autocrlf
,core.eol
+ gitattributes(Tim's post is excellent)处理行结尾。
我有一个将autocrlf
设置为true
的Windows Git仓库。因此,所有文本文件都作为LF
存储在repo中,并作为CRLF
存在于工作目录中。这个仓库是从一个SVN仓库中克隆出来的,我们仍然使用这个仓库从/拉到(SVN仓库是我们用于触发CI等的中央,受祝福的仓库)。
但我不知道git-svn
在推/拉操作期间如何处理行结尾。
有人可以解释git-svn
在这个例子中做了什么吗?
答案 0 :(得分:15)
我也对此感兴趣。假设你有一个通过git svn clone创建的repo,我想你可以将它分解为三个不同的问题:
我很想听听这些问题在理论上应该是什么,但是现在我做了一个小实验,似乎表明至少在情况#1中没有新行标准化:
rem We'll make a svn repo with CRLF newlines, clone it into git with
rem autocrlf enabled, and try to see if that results in LF-only newlines
rem getting stored in the git repo
cd c:\code
rem Step 1. Prepare SVN repo with CRLF type newlines.
rem The pre-1.4 flag is to prevent an error during git clone.
svnadmin create --pre-1.4-compatible svnrepo
svn checkout file:///C:/code/svnrepo svnworking
cd svnworking
echo "First line" > file.txt
echo "Second line" >> file.txt
echo "Third line" >> file.txt
rem NOTE: At this point file.txt has CRLF newlines
svn add file.txt
svn commit -m "Add file.txt"
rem NOTE: At this point file.txt still has CRLF newlines
cd ..
rem Step 2. Clone the svn repo into git and inspect work copy newline type
git svn clone file:///C:/code/svnrepo gitrepo
rem The following outputs true on my machine
git config --get core.autocrlf
cd gitrepo
rem The following also outputs true on my machine
git config --get core.autocrlf
git svn fetch
rem NOTE: At this point file.txt (git working dir copy) has CRLF newlines
rem Step 3. Disable autocrlf to inspect repo's inner newline type
rem Use the following and my editor to set core.autocrlf to false:
git config --edit --local
rem This now prints false:
git config --get core.autocrlf
git checkout .
rem NOTE: At this point file.txt (git working dir copy) still has CRLF newlines
del file.txt
git checkout .
rem NOTE: Even after explicitly deleting the old one and checking out again,
rem file.txt still has CRLF newlines
如果在我的git svn pull期间发生了git newline转换,相反,那么我希望file.txt在所有这些结尾处都只有LF换行。
这是一个完整性检查,上面的第3步实际上实现了一个有效的测试,即repo是否只有LF换行:
rem We'll a git repo with core.autocrlf on, then switch it off to
rem pull out a file
rem The following outputs true
git config --get core.autocrlf
git init gitcrtest
cd gitcrtest
rem The following still outputs true
git config --get core.autocrlf
echo "First line" > file.txt
echo "Second line" >> file.txt
echo "Third line" >> file.txt
git add file.txt
git commit -m "Add file.txt"
rem NOTE: At this point file.txt (git working dir copy) has CRLF newlines
rem Use the following to set core.autocrlf to false
git config --edit --local
git checkout .
rem NOTE: Now file.txt (git working dir copy) has LF-only newlines
总结:基于以上所述,似乎当git-svn从svn中提取时,即使启用了autocrlf,svn提交也会被添加到git commit graph而不进行任何crlf转换。也就是说,无论你的文件在你的svn repo中有什么类型的换行符,它们也会在你的git clone中有。 (但您的git 工作副本可能有不同的换行符类型。)
请注意,这与“git help attributes”中对行结束规范化的讨论非常一致;规范化是指从将repo从repo中提取到工作目录(例如checkout或merge)的命令或者将工作目录中的东西移动到index / repo中的命令(例如add或commit)。 “Git svn fetch”似乎没有做到这两件事,所以当时没有行结束标准化是有意义的。我对dcommit的作用更加模糊,所以我不确定是否期望当时的行尾标准化。
请注意,如果在您的repo / machine上设置了SVN的svn:eol-style属性,则会产生额外的皱纹。我认为 SVN默认是不在其结束时进行行尾转换,但我不是百分百肯定。
更新:有关换行符的实际svn-> git迁移视角,另请参阅Tim Abell's description。 git-svn没有将CRLF换行符转换为仅含LF的换行符,如果git的自动行结束标准化保持不变,则会产生非理想的结果。解决方案是在git中标准化行结尾或禁用行结束标准化。