git-svn如何处理行结尾?

时间:2012-03-28 14:27:12

标签: git-svn newline eol core.autocrlf

我很高兴Git本身如何通过core.autocrlfcore.eol + gitattributes(Tim's post is excellent)处理行结尾。

我有一个将autocrlf设置为true的Windows Git仓库。因此,所有文本文件都作为LF存储在repo中,并作为CRLF存在于工作目录中。这个仓库是从一个SVN仓库中克隆出来的,我们仍然使用这个仓库从/拉到(SVN仓库是我们用于触发CI等的中央,受祝福的仓库)。

但我不知道git-svn在推/拉操作期间如何处理行结尾。

有人可以解释git-svn在这个例子中做了什么吗?

1 个答案:

答案 0 :(得分:15)

我也对此感兴趣。假设你有一个通过git svn clone创建的repo,我想你可以将它分解为三个不同的问题:

  1. 在将提交从svn移动到git repo时,是否会在git svn获取时发生任何git换行符规范化/更改?
  2. git提交时是否发生任何git换行符规范化/更改[即在正常的本地git提交到svn遥控器的仓库]?合并/变基时间怎么样?
  3. 在git svn dcommit时间,在推送/重放/任何git提交svn时,是否会发生任何git换行符规范化/更改?
  4. 我很想听听这些问题在理论上应该是什么,但是现在我做了一个小实验,似乎表明至少在情况#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中标准化行结尾或禁用行结束标准化。