行结束(CRLF)处理的git行为(.gitattributes)

时间:2014-11-26 08:18:47

标签: git

我正在为Windows和Linux环境处理C ++ / C存储库。事实上,Windows和Linux上的编辑器可以接受CR / LF或LF结尾的文本文件(甚至是混合模式)。问题是,用户可以使用其本机行结束格式(CR / LF或仅LF)创建新的.cpp,.h文件。 .gitattributes的最佳设置是什么?

为了详细描述问题,我有一个假设,并希望满足以下要求:

  

假设:如果收银台收到CR / LF或LF结束,我不在乎   因为现代编辑可以在Windows或Windows上处理这两种风格   未* X。

     

要求1.如果两个版本的文件仅在其行中有所不同   结尾样式,系统(意思是git客户端,git数据库等等。)   应视为同一版本。因此git diff应该显示no   差异,git merge不需要做任何事......等等。

     

要求2.工作目录中的文件应保持原样。   甚至一些文件可能是DOS风格的,还有一些文件   Unix风格。 (例如,在Windows上,某些文件由VIM编辑   在cygwin下,它有Unix风格,有些使用原生窗口   编辑器,导致DOS风格)。即在工作目录中,   文件'由于任何git,结尾风格不得更改   事务(提交,合并等......)[哦,我可以在合并时接受   发生,文件可能会被更改。]

另外,我发现了这个bug?在git中:(参见以下交易)

bash (master) $ git status
# On branch master nothing to commit (working directory clean)

bash (master) $ file a.c
a.c: C source, ASCII text, with CRLF line terminators

bash (master) $ dos2unix a.c
dos2unix: converting file a.c to Unix format ...

bash (master) $ git status
# On branch 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:   a.c
# no changes added to commit (use "git add" and/or "git commit -a")

bash (master) $ git add a.c
bash (master) $ git status
# On branch master
nothing to commit (working directory clean)

正如您在事务中看到的那样,当行结束样式发生更改时,git status没有意识到更改仅仅是行结尾,并报告a.c的修改。虽然在git add a.c之后,状态已得到纠正。我的.gitattributes强制所有.c和.h仅使用lf

bash (master) $ cat .gitattributes
*    text=auto

*.c  text eol=lf
*.C  text eol=lf
*.cpp  text eol=lf
*.CPP  text eol=lf
*.h  text eol=lf
*.H  text eol=lf
*.hpp  text eol=lf
*.HPP  text eol=lf

*.pro  text eol=crlf

有人能告诉我如何避免它,还是一个错误? (或者只是一个原样行为,而不是一个错误,因为要求git status感知行结束更改需要diff这是否代价高昂?)?

我已阅读this link,但如果工作目录中的文件将被更改,则它不会回答我。我搜索了很多链接,发现了一些像Linux或Windows这样的纯系统的建议,但任何人都可以在同一系统上找到组合系统的建议,比如Windows + Cygwin吗?

1 个答案:

答案 0 :(得分:2)

试着只回答这部分问题:

  

git diff对于仅以行尾格式...

不同的文件应该没有区别
  1. diff命令有--strip-trailing-cr选项忽略LF与CRLF的区别
  2. git允许外部diff命令。因此我们制作一个difficr(diff-ignore-cr)命令:

    $ cat difficr
    #! /bin/sh
    diff --strip-trailing-cr "$2" "$5"
    
  3. $2$5是因为那些是实际的文件args。 请参阅主git中的GIT_EXTERNAL_DIFF man-page

    并设置git config:

        $  git config --global diff.external "/path/to/difficr"
    

    现在您应该发现git diff忽略LF与CRLF的区别。

    [至少我的实验证明了这样做]