34

我对 Git 本身通过core.autocrlf, core.eol+ gitattributes 处理行尾的方式非常满意(Tim 的帖子很棒)。

我有一个autocrlf设置为true. 因此,所有文本文件都存储在 repo 中,LF并以CRLF. 这个 repo 是从 SVN repo 克隆的,我们仍然使用它来推送/拉入(SVN repo 是我们的中心,用于触发 CI 等的祝福 repo)。

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

谁能解释git-svn在这种情况下会发生什么?

4

1 回答 1

16

我也对这个很感兴趣。假设您有一个通过 git svn clone 创建的 repo,我认为您可以将其分解为三个不同的问题:

  1. 在将提交从 svn 移动到 git repo 时,是否会在 git svn fetch 时发生任何 git 换行规范化/更改?
  2. git 提交时是否会发生任何 git 换行规范化/更改[即在正常的本地 git 提交到带有 svn 遥控器的 repo 期间]?合并/变基时间怎么样?
  3. 在 git svn dcommit 时间,在推送/重播/git 对 svn 提交的任何内容时,是否会发生任何 git 换行规范化/更改?

我很想听听这些问题在理论上应该是正确的,但现在我做了一个小实验,似乎表明至少在案例 #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 换行符转换,那么我希望 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 提交图中而没有任何 crlf 转换。也就是说,无论您的文件在您的 svn 存储库中具有何种类型的换行符,它们也将在您的 git clone 中具有。(但您的 git工作副本可能有不同的换行符类型。)

请注意,这与“git help attributes”中对行尾规范化的讨论非常一致;规范化表现为将东西从 repo 拉到工作目录的命令(例如 checkout 或 merge)或将东西从工作目录移动到 index/repo 的命令(例如 add 或 commit)。“Git svn fetch”似乎没有做任何这些事情,所以当时不会发生行尾标准化是有道理的。我对 dcommit 的作用比较模糊,所以我不确定当时是否期望行尾标准化。

请注意,如果在您的存储库/机器上设置了 SVN 的 svn:eol-style 属性,则会出现额外的问题。我认为SVN 默认是进行行尾转换,但我不是 100% 确定。

更新:有关换行符的真实 svn->git 迁移观点,另请参见Tim Abell 的描述。git-svn 不会将 CRLF 换行符转换为仅 LF 换行符,如果 git 的自动行尾标准化保持打开状态,则结果不理想。解决方案是规范化 git 中的行尾或禁用行尾规范化。

于 2012-03-29T04:29:23.757 回答