git p4提交:补丁不适用

时间:2013-03-20 13:50:27

标签: git perforce git-p4

最近我一直在使用git-p4遇到问题。

我目前的工作流程是:

git checkout -b some_feature
# do some work and commit to some_feature branch
git checkout master
git merge --no-ff some_feature
git p4 rebase
git p4 submit

并非总是如此,但偶尔执行git p4 submit时,更改实际上并不适用,而是我看到:

error: some_file.extension: patch does not apply

进行一些研究,我尝试在master上进行硬重置并在没有--no-ff标志的情况下再次合并,但这似乎没有帮助。

非常感谢任何想法。

2 个答案:

答案 0 :(得分:9)

我今天遇到了这个问题。在我的情况下,问题是因为我的文本编辑器(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/'

然后,我通过在 .gitattributes 中添加以下行,将utf8-autobom过滤器应用于违规文件:

*.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"。

过滤器通过运行clean命令删除提交时的BOM,并通过运行smudge命令在结帐时添加BOM。这会将BOM保留在工作树文件中,但会阻止BOM提交给Git或提交给Perforce。

(有关cleansmudge的详细信息,请参阅gitattributes documentation。)

诊断问题

我认为错误信息很有趣:

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 ++显示编码为&#34; UTF-8-BOM&#34;在我的Git工作树中,&#34; UTF-8&#34;在我的Perforce工作区中。 (Linux和Cygwin用户:使用file <path-to-file>命令显示有关文件编码的信息。)

谷歌搜索&#34; UTF-8-BOM&#34;让我走上了正确的道路。

注意

安装此过滤器后,某些Git操作会变慢。

提示

如果您在工作树中不需要BOM,则可以删除过滤器的smudge部分。这将加速一些Git操作(如git checkout)。删除smudge行后,过滤器定义为:

[filter "utf8-autobom"]
        clean = sed -b -e '1!b' -e 's/^\\xEF\\xBB\\xBF//'

答案 1 :(得分:5)

我有同样的问题,我认为根本原因是行结尾。您可以尝试运行dos2unix之类的东西来修复它,或者设置此配置:

git config --global core.autocrlf true

有时,文件模式可能会导致问题。此配置可以修复它(如果您不关心文件模式):

git config core.filemode false