我今天遇到了这个问题。就我而言,问题是因为我的文本编辑器 (Visual Studio) 正在向它接触的每个文件添加一个Unicode BOM 。同时,Perforce 服务器设置为从每个文件中去除 Unicode BOM,防止 Unicode BOM 出现在 Perforce 中。这最终导致我git p4 submit
失败并显示以下消息:
error: patch failed: path/to/file.csproj:1
error: path/to/file.csproj: patch does not apply
最终解决方案
我在~/.gitconfig文件中添加了以下过滤器定义:
[filter "utf8-autobom"]
clean = sed -b -e '1!b' -e 's/^\\xEF\\xBB\\xBF//'
smudge = sed -b -e '1!b' -e 's/\\(^\\|^\\xEF\\xBB\\xBF\\)/\\xEF\\xBB\\xBF/'
然后我utf8-autobom
通过在.gitattributes中添加以下行将过滤器应用于有问题的文件:
*.csproj filter=utf8-autobom
然后我强迫 Git 将过滤器应用到它的索引:
rm .git/index
git reset
然后我将编辑后的文件提交给 Git,并像往常一样将我的提交提交给 Perforce:
git add .
git commit --amend
git p4 submit
这个怎么运作
过滤器定义基于以下sed
命令,其中“abc”是相应 Unicode BOM 字节序列的占位符:
# Remove 'abc' from beginning of file, if present
sed -b -e '1!b' -e 's/^abc//'
# Add 'abc' to beginning of file, if not present
sed -b -e '1!b' -e 's/\(^\|^abc\)/abc/'
对于 UTF-8 BOM,我们使用字节序列EF BB BF
而不是“abc”。
过滤器通过运行命令在提交时删除 BOM clean
,并通过运行命令在结帐时添加 BOM smudge
。这会将 BOM 保留在工作树文件中,但会阻止 BOM 提交给 Git,或提交给 Perforce。
(有关和的详细信息,请参阅gitattributes 文档。)clean
smudge
诊断问题
我认为错误信息很有趣:
error: patch failed: path/to/file.csproj:1
error: path/to/file.csproj: patch does not apply
它说补丁在第 1 行失败,即使我的提交没有编辑文件的第 1 行。
为了看看发生了什么,我跑了git diff p4/master HEAD
。差异表明我的提交<U+FEFF>
在文件开头添加了一个奇怪的字符。我怀疑它与文件编码有关,所以我使用 Notepad++ 在我的 Git 工作树中打开文件。然后我在我的 Perforce 工作区中打开了相应的文件。Notepad++ 在我的 Git 工作树中显示编码为“UTF-8-BOM”,在我的 Perforce 工作区中显示为“UTF-8”。(Linux 和 Cygwin 用户:使用该file <path-to-file>
命令显示有关文件编码的信息。)
谷歌搜索“UTF-8-BOM”让我走上了正确的道路。
注意
安装此过滤器后,某些 Git 操作会变慢。
小费
smudge
如果您的工作树中不需要 BOM,则可以删除过滤器的部分。这将加快一些 Git 操作(如git checkout
)。删除该smudge
行后,过滤器定义为:
[filter "utf8-autobom"]
clean = sed -b -e '1!b' -e 's/^\\xEF\\xBB\\xBF//'