【问题标题】:why does git treat some cpp files as binary?为什么 git 将某些 cpp 文件视为二进制文件?
【发布时间】:2011-01-19 13:15:58
【问题描述】:

这是git log 的输出:

* 5a831fdb34f05edd62321d1193a96b8f96486d69      HEAD (HEAD, origin/work, work)
|  LIB/xxx.cpp                        |  Bin 592994 -> 593572 bytes
|  LIB/xxx.h                          |    5 +++++
|  LIB/bbb/xxx.h                      |    9 +++++++++
|  LIB/aaa/xxx.cpp                    |  Bin 321534 -> 321536 bytes
|  LIB/aaa/yyy.cpp                    |   31 +++++++------------------------
|  tests/aaa/xxx.cpp                  |   29 +++++++++++++++++++++++++++++
|  tests/test_xxx.vcproj              |    4 ++++
|  7 files changed, 54 insertions(+), 24 deletions(-)

为什么它把一些文件当作二进制文件,而另一些不是?这会带来严重的问题,因为 git 也不想自动合并它们。因此,几乎所有的合并/变基/拉取操作都变得很痛苦。

这里是 repo 配置:

[core]
  repositoryformatversion = 0
  filemode = false
  bare = false
  logallrefupdates = true
  symlinks = false
  ignorecase = true
  hideDotFiles = dotGitOnly
[remote "origin"]
  fetch = +refs/heads/*:refs/remotes/origin/*
  url = https://xxx/project.git
[branch "master"]
  remote = origin
  merge = refs/heads/master
[branch "work"]
  remote = origin
  merge = refs/heads/work
[svn-remote "svn"]
  url = xxxx
  fetch = :refs/remotes/git-svn

在主 .gitconfig 中也是 core.autocrlf = false。

编辑 我按照 cmets 中的建议将 core.autocrlf 设置为 true,但这似乎不会影响我之后的下一次合并(也许现在更改 autocrlf 为时已晚?还是与问题无关?):

> git merge work
warning: Cannot merge binary files: LIB/xxx.cpp (HEAD vs. work)

warning: Cannot merge binary files: LIB/aaa/xxx.cpp (HEAD vs. work)

Auto-merging LIB/xxx.cpp
CONFLICT (content): Merge conflict in LLIB/xxx.cpp
Auto-merging LIB/xxx.h
Auto-merging LIB/aaa/xxx.cpp
CONFLICT (content): Merge conflict in LIB/aaa/xxx.cpp
Automatic merge failed; fix conflicts and then commit the result.

现在 gits 还坚持要更改几个文件中的换行符(这是我不想要的)。

解决方案

感谢:

*.cpp -text crlf diff

需要-text 部分来防止 git 转换 lineends,即使 core.autocrlf 设置为 false。

【问题讨论】:

  • 那么为什么core.autocrlf=false?
  • 我的理解是,这使得 git 根本不转换任何行尾,即让我看到文件原样,这就是我所追求的。这不正确吗?
  • 不完全是。 autocrlf 设置为 true,git 使用 lineendings 转换来获取文件的内部表示。我建议将选项设置为 true - 或者至少尝试一下。

标签: git


【解决方案1】:

尝试将以下行添加到您的$repo/.git/info/attributes:

*.cpp crlf diff

您可以在gitattributes per-repo、per-user 和 per-system 中指定它。


基本清单

• 您的文件中是否真的有 CRLF 或 LF 行尾?
? 是的,CRLF — 将 core.autocrlf 设置为 true(至少对于这个 repo)。


• 文件是否包含有趣的非 ASCII 字符:变音符号、变音符号、表情符号、日本汉字、版权标志©、不可见的深奥空间等?..
? 如果是,最好确保所有内容都是encoded in UTF-8。使用代理对进行模糊测试并不好玩。


• 文件内容是否以 UTF-8 BOM 开头?
? 现在擦,没意义。


• 文件内容是否以 UTF16 BOM 开头?
?太糟糕了;在这一点上,我对你没有什么好的建议;对不起。请联系您的系统供应商。

【讨论】:

  • 基本上就是这样 - 我不太清楚为什么必须明确设置它
  • @stijn 因为您不应该在全局配置中将 core.autocrlf 设置为 false。这有效地禁用了对文本文件中行尾的“智能”检测,因此 git 无法将它们作为文本处理并退回到二进制文件。
  • 这也可能是编码问题,Git 最适合使用 utf-8,如果编码是 utf-16 之类的,Git 会认为它是二进制的,不管你在.gitattributes 中设置什么.
  • 虽然我不太清楚为什么必须明确设置它我猜你在文件顶部的某处有一个版权名称,这需要非 ASCII 字符.
【解决方案2】:

它将某些文件视为二进制文件,因为它们的文件编码错误。 如果您将这些文件转换为 UTF-8(或与普通文件相同的编码),它应该可以正常工作。要更改文件编码,请使用 notepad++ 或任何其他方式。

【讨论】:

    猜你喜欢
    • 2011-10-14
    • 2015-03-24
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    相关资源
    最近更新 更多