行尾 (CR/LF) 处理 (.gitattribute) 上的 git 行为



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

要描述的问题就是细节,我有一个假设,并希望满足以下要求:

假设:我不在乎结帐是否以CR/LF或LF结尾 样式,因为现代编辑器可以在 Windows 或 Un*x.

要求 1.如果文件的两个版本仅在其行中不同 结尾样式,系统(指git客户端,git数据库等) 应将其视为同一版本。 因此 git diff 应该显示没有 不同,git 合并不需要做任何事情...等。。

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

另外,我在 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

我已经阅读了此链接,但它没有回答我工作目录中的文件是否会更改。 我已经搜索了很多链接,并找到了一些关于Linux或Windows等纯系统的建议,但是任何人都可以对组合系统提出建议,例如同一系统上的Windows + Cygwin?

试图只回答问题的这一部分:

git diff应该对仅在行尾样式不同的文件显示没有区别......

  1. diff 命令有一个忽略 LF 与 CRLF 区别的--strip-trailing-cr选项。
  2. git 允许外部差异命令。因此,我们为此制作了一个difficr(diff-ignore-cr)命令:

    $ cat difficr
    #! /bin/sh
    diff --strip-trailing-cr "$2" "$5"
    

$2$5是因为这些是实际的文件参数。查看主 git 中的GIT_EXTERNAL_DIFF手册页。

并设置 git 配置:

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

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

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

最新更新