首页 文章

Git最好的CRLF(回车,换行)处理策略是什么?

提问于
浏览
558

我尝试使用CRLF结束行提交文件,但失败了 .

我花了整整一天的时间在我的Windows计算机上尝试不同的策略,几乎被迫停止尝试使用Git而是尝试Mercurial .

每个答案只能分享一个最佳实践 .

9 回答

  • 54

    在问了这个问题差不多四年后,我终于找到了 an answer that completely satisfies me

    请参阅 github:helpDealing with line endings指南中的详细信息 .

    Git允许您使用.gitattributes文件中的text属性直接设置repo的行结束属性 . 此文件将提交到repo并覆盖core.autocrlf设置,允许您确保所有用户的行为一致,无论其git设置如何 .

    因此

    这样做的好处是,您的行结束配置现在随您的存储库一起移动,您无需担心协作者是否具有正确的全局设置 .

    这是一个 .gitattributes 文件的示例

    # Auto detect text files and perform LF normalization
    *        text=auto
    
    *.cs     text diff=csharp
    *.java   text diff=java
    *.html   text diff=html
    *.css    text
    *.js     text
    *.sql    text
    
    *.csproj text merge=union
    *.sln    text merge=union eol=crlf
    
    *.docx   diff=astextplain
    *.DOCX   diff=astextplain
    
    # absolute paths are ok, as are globs
    /**/postinst* text eol=lf
    
    # paths that don't start with / are treated relative to the .gitattributes folder
    relative/path/*.txt text eol=lf
    

    对于最流行的编程语言,有一个方便的collection of ready to use .gitattributes files . 帮助你入门很有用 .

    一旦你创建或调整了 .gitattributes ,就应该执行一次性的line endings re-normalization .

    请注意,在应用程序中打开项目的Git仓库后,GitHub Desktop应用程序可以建议并创建 .gitattributes 文件 . 要尝试此操作,请单击齿轮图标(位于右上角)>存储库设置...>行结尾和属性 . 系统会要求您添加推荐的 .gitattributes ,如果您同意,该应用程序还将对存储库中的所有文件执行标准化 .

    最后,Mind the End of Your Line文章提供了更多背景知识,并解释了Git如何在手头的事情上发展 . 我认为这需要阅读 .

    您的团队中可能有用户使用EGit或JGit(Eclipse和TeamCity等工具使用它们)来提交更改 . 然后你运气不好,正如@gatinueta在这个答案的评论中解释的那样:

    如果您的团队中有人使用Egit或JGit,此设置将无法完全满足您,因为这些工具将忽略.gitattributes并愉快地签入CRLF文件https://bugs.eclipse.org/bugs/show_bug.cgi ?ID = 342372

    一个技巧可能是让他们在另一个客户端提交他们的更改,比如SourceTree . 然后我们的团队更喜欢Eclipse的EGit工具,用于许多用例 .

    谁说软件很简单? : - /

  • 2

    You almost always want autocrlf=input unless you really know what you are doing.

    下面的一些附加背景:

    如果您喜欢DOS结尾,那么它应该是core.autocrlf = true;如果您喜欢unix-newlines,那么它应该是core.autocrlf = input . 在这两种情况下,您的Git存储库将只有LF,这是正确的事情 . core.autocrlf = false的唯一参数是自动启发式可能会错误地将某些二进制文件检测为文本,然后您的磁贴将被损坏 . 因此,引入了core.safecrlf选项以警告用户是否发生了不可逆转的更改 . 事实上,有两种不可逆转的可能性 - 文本文件中的混合行尾,在这种规范化中是可取的,因此可以忽略此警告,或者(非常不可能)Git错误地将二进制文件检测为文本 . 然后你需要使用属性告诉Git这个文件是二进制文件 .

    以上段落最初是从gmane.org上的一个帖子中删除的,但后来它已经失效了 .

  • 4

    get consistent 关于混合环境中的行结尾的两种替代策略(Microsoft Linux Mac):

    A.全局所有存储库设置

    1) Convert all to one format

    find . -type f -not -path "./.git/*" -exec dos2unix {} \;
    git commit -a -m 'dos2unix conversion'
    

    2) Set core.autocrlf to input on Linux/UNIX or true on MS Windowns (repository or global)

    git config --global core.autocrlf input
    

    3)[可选]设置 core.safecrlftrue (停止)或 warn (唱歌:)以添加额外的保护比较,如果反向换行转换将导致相同的文件

    git config --global core.safecrlf true
    

    B.或每个存储库设置

    1) Convert all to one format

    find . -type f -not -path "./.git/*" -exec dos2unix {} \;
    git commit -a -m 'dos2unix conversion'
    

    2) add .gitattributes file to your repository

    echo "* text=auto" > .gitattributes
    git add .gitattributes
    git commit -m 'adding .gitattributes for unified line-ending'
    

    不要担心你的二进制文件--Git应该足够聪明 .


    More about safecrlf/autocrlf variables

  • 7

    我花了好几个小时来最好地使用 .gitattributes ,最终意识到,我不能指望它 .
    不幸的是,只要存在基于JGit的编辑器(无法正确处理 .gitattributes ),安全的解决方案就是在编辑器级别强制执行LF .

    使用以下 anti-CRLF 消毒剂 .

    --- Update ---

    即使您不想使用上述策略, the following command is your friend (Windows客户端上的 Note: 只能通过 git-bash 工作,并且只有在 ./configure 中使用 --with-libpcre 编译时才能在Linux客户端上工作) .

    # Print all files that have been committed with CRLF (more correctly that contain CR), so that you normalize them.
    git grep -I --files-with-matches --perl-regexp '\r' HEAD
    

    一个 painful example

    netbeans 8.2 (在Windows上),会错误地使用 CRLFs on repounless 提交所有文本文件 explicitly set core.autocrlf as global . 这与标准的git客户端行为相矛盾,并且在更新/合并时会导致很多问题 . 这是一些 files appear different (虽然他们不是) even when you revert .
    即使您已将正确的 .gitattributes 添加到项目中,也会发生netbeans中的相同行为 .

    在提交后使用上面的命令,至少可以帮助您及早发现您的git repo是否有行结束问题 .

  • 104

    尝试将 core.autocrlf 配置选项设置为 true . 另请查看 core.safecrlf 选项 .

    实际上听起来像 core.safecrlf 可能已经在您的存储库中设置了,因为(强调我的):

    如果core.autocrlf的当前设置不是这种情况,git将拒绝该文件 .

    如果是这种情况,那么您可能需要检查文本编辑器是否配置为一致地使用行结尾 . 如果文本文件包含LF和CRLF行结尾的混合,则可能会遇到问题 .

    最后,我觉得简单地“使用你给你的东西”并在Windows上使用LF终止线的建议将导致比它解决的更多问题 . Git有以上选项来尝试以合理的方式处理行结尾,因此使用它们是有意义的 .

  • 697

    在我的Visual Studio 2010项目中检出后,使用 core.autocrlf=false 阻止所有文件被标记为已更新 . 开发团队的另外两个成员也使用Windows系统,因此混合环境没有发挥作用,但存储库附带的默认设置始终将所有文件标记为克隆后立即更新 .

    我想最重要的是找到适用于您的环境的CRLF设置 . 特别是因为在Linux盒子上的许多其他存储库中设置 autocrlf = true 会产生更好的结果 .

    20年后,我们仍在处理操作系统之间的线路结束差异......很遗憾 .

  • 9

    这些是与Mac或Linux用户共享代码的Windows和Visual Studio用户的两个选项 . 有关扩展说明,请阅读gitattributes manual .

    * text = auto

    在你的repo的 .gitattributes 文件中添加:

    *   text=auto
    

    这将在repo中使用 LF 行结尾规范化所有文件 .

    根据您的操作系统( core.eol 设置),工作树中的文件将针对基于Unix的系统标准化为 LF 或针对Windows系统标准化为 CRLF .

    这是Microsoft .NET repos使用的配置 .

    例:

    Hello\r\nWorld
    

    将在回购中标准化为:

    Hello\nWorld
    

    在结帐时,Windows中的工作树将转换为:

    Hello\r\nWorld
    

    结帐时,Mac中的工作树将保留为:

    Hello\nWorld
    

    注意:如果您的repo已包含未规范化的文件,git status将在下次对其进行任何更改时将这些文件显示为已完全修改,并且其他用户稍后合并其更改可能会很麻烦 . 有关更多信息,请参阅更改行结尾后刷新存储库 .

    core.autocrlf = true

    如果 .gitattributes 文件中未指定 text ,则Git使用 core.autocrlf 配置变量来确定是否应转换文件 .

    对于Windows用户, git config --global core.autocrlf true 是一个很好的选择,因为:

    • 文件被归一化为 LF 行结尾 only when added 到回购 . 如果存储库中没有标准化的文件,则此设置不会触及它们 .

    • 所有文本文件都转换为工作目录中的 CRLF 行结尾 .

    这种方法的问题是:

    • 如果您是 autocrlf = input 的Windows用户,您将看到一堆带有 LF 行结尾的文件 . 对团队的其他成员而言并不存在危险,因为您的提交仍将使用 LF 行结尾进行标准化 .

    • 如果您是使用 core.autocrlf = false 的Windows用户,您将看到一堆带有 LF 行结尾的文件,您可以将带有 CRLF 行结尾的文件引入回购 .

    • 大多数Mac用户使用 autocrlf = input 并且可能获得带有 CRLF 文件结尾的文件,可能来自Windows用户 core.autocrlf = false .

  • 78

    不要转换行结尾 . 解释数据并不是VCS的工作 - 只需存储和版本化即可 . 无论如何,每个现代文本编辑器都可以读取两种行结尾 .

  • 11

    这只是一个 workaround 解决方案:

    在正常情况下,请使用随git一起提供的解决方案 . 这些在大多数情况下都很有效 . 如果您通过设置 .gitattributes 在Windows和基于Unix的系统上共享开发,则强制为LF .

    在我的案例中,有超过10名程序员在Windows中开发项目 . 该项目已通过CRLF和 there was no option to force to LF. 签到

    有些设置是在我的机器上内部写入的,对LF格式没有任何影响;因此,在每次小文件更改时,一些文件全局更改为LF .

    我的解决方案

    Windows-Machines: 让一切都按原样 . 什么都不关心,因为你是一个默认的Windows 'lone wolf'开发人员,你必须像这样处理:"There is no other system in the wide world, is it?"

    Unix-Machines

    • 将以下行添加到配置的 [alias] 部分 . 此命令列出所有已更改(即已修改/新)的文件:
    lc = "!f() { git status --porcelain \
                 | egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \
                 | cut -c 4- ; }; f "
    
    • 将所有 changed 文件转换为dos格式:
    unix2dos $(git lc)
    
    • 可选......

    • 为此操作创建一个git hook以自动执行此操作处理

    • 使用params并包含它并修改 grep 函数以仅匹配特定的文件名,例如:

    ... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
    
    • 使用其他快捷方式随意使其更方便:
    c2dos = "!f() { unix2dos $(git lc) ; }; f "
    

    ...并通过键入来解雇转换后的内容

    git c2dos
    

相关问题