git p4 提交:补丁不适用

8

最近我在使用 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

经过一些研究,我尝试在主分支上执行硬重置并再次合并,但没有使用 --no-ff 标志,但似乎这并没有帮助。

非常感谢您的任何想法。


这两个对你有用吗? https://dev59.com/gV_Va4cB1Zd3GeqPW8gG https://dev59.com/B3DYa4cB1Zd3GeqPEtMF - Philip
3个回答

10

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

诊断问题

我认为错误消息很有意思:

error: patch failed: path/to/file.csproj:1
error: path/to/file.csproj: patch does not apply

即使我的提交没有编辑文件的第一行,但它说补丁在第一行失败了。

为了看清发生了什么,我运行了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 操作将变慢。

提示

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

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

6

我曾经遇到过这个问题,我认为根本原因是换行符的问题。你可以尝试运行类似于dos2unix的命令来解决它,或者设置以下配置:

git config --global core.autocrlf true

有时,文件模式也会引起问题。这个配置可以解决它(如果你不关心文件模式):

有时,文件模式也可能出现问题。如果您不关心文件模式,那么此配置可以解决该问题:

git config core.filemode false

2
jlapolla2016 answer 中:

然后我应用了 utf8-autobom 过滤器

在 Git 2.37(2022 年第三季度)中,可能不再需要使用这样的过滤器。

查看提交fbe5f6b(2022年4月4日),作者为Tao Klerks(TaoK
(由Junio C Hamano -- gitster --提交804ec03中合并,2022年5月20日)

git-p4:从P4导入到Git时保留UTF8 BOM

签署者:Tao Klerks

Perforce有一个文件类型“utf8”,它表示带有显式BOM的文本文件。 没有BOM的“utf8编码”文件被存储为常规文件类型“text”。 “utf8”文件类型在除了一种重要方式之外的所有方面都像文本一样:它在内部存储时没有前导的3个BOM字节。 历史上,git-p4将(在Perforce中作为类型“utf8”存储的)带BOM的utf8文件与常规文本文件一样导入,因此丢失了BOM。 在大多数情况下,这个问题对功能影响不大,因为大多数系统认为BOM是可选和多余的,但这确实是一个正确性失败,并且可能会导致实际问题,例如当BOM明确包含在测试文件中时,例如在文件编码测试套件中。 修复从p4导入更改时处理带有BOM的utf8文件的方法,并引入一个检查其是否正常工作的测试。
这意味着:
类型 utf8 明确表示带有 BOM 的 utf8。这些文件与普通文本文件一样进行流传输,但在流中没有 BOM。因此,为了准确地将这些文件导入 git,我们需要在写入前明确地重新添加 BOM。在这种情况下,'contents' 是一组字节,因此创建 BOM 前缀作为 b'' 文字即可。因此,执行“p4 submit -d 'add utf8 test files'”后跟“git p4 clone --dest='$git' //depot@all”应该在 Git 存储库中提供带有保留 BOM 的 utf-8 文件。
此外,还有 Git 2.37(2022 年第三季度):
请参见提交 f7b5ff6(由Tao Klerks (TaoK于 2022 年 4 月 30 日提交)。
(由Junio C Hamano -- gitster --合并到提交 3af1df0中,于 2022 年 5 月 20 日)git-p4:改进编码处理以支持不一致的编码」 「签署者:Tao Klerks」
`git-p4`旨在在python2.7和python3下正确运行,但其对导入用户输入文本的功能行为在这些环境中存在差异:在python2下,`git-p4`“天真地”将Perforce字节流写入git元数据(并且不在提交上设置“编码”头),这意味着任何非utf-8字节序列最终都会在git中创建无效编码的提交元数据。在python3下,`git-p4`尝试将Perforce字节流解码为utf-8数据,并在遇到非utf-8数据时失败(并显示一个无用的错误)。Perforce客户端(特别是`p4v`)鼓励用户使用操作系统本地编码输入更改列表描述(和用户全名),并将生成的字节流未经修改地存储到服务器上,以便不同的客户端可能会创建互相难以理解的消息。在许多Perforce环境中,最常见的不一致性可能是utf-8(在Linux中很典型)与cp-1252(在Windows中很典型)。使`changelist-description-`和`user-fullname-handling`代码在Python运行时上不受影响,引入三种可通过配置选择的“策略”:'passthrough',在Python2下以前的行为;'strict',在Python3下以前的行为;'fallback',偏爱utf-8,但在utf-8解码失败时支持第二个编码,并在第二个编码解码失败时转义高位字节。将Python2的默认行为保持不变('legacy'策略),但将Python3的默认策略切换为“fallback”,默认回退编码为“cp1252”。
"git p4"现在在其手册页面中包含了:

git-p4.metadataDecodingStrategy

Perforce将changelist描述和用户全名的编码保存为客户端在特定操作系统上存储的方式。p4v客户端使用本地编码,因此不同的用户可能会以不同的编码方式存储相同仓库中的changelist描述或用户全名。

Git可以容忍提交消息和作者名称中的不一致/不正确的编码,但希望它们以utf-8指定。git-p4可以在处理Perforce中的编码不确定性时使用三种不同的解码策略:

  • 'passthrough'只是将原始字节从Perforce传递到git,当Perforce数据被编码为除utf-8以外的任何内容时,会创建可用但错误编码的数据。
  • 'strict'期望Perforce数据以utf-8编码,并在这不成立时导入失败。
  • 'fallback'尝试将数据解释为utf-8,否则回退到使用次要编码(默认情况下是常见的Windows编码'cp-1252'),如果使用回退编码进行解码也失败,则转义上限范围字节。

在python2下,默认策略是“passthrough”出于历史原因,在python3下,默认策略是“fallback”。当选择“strict”并且解码失败时,错误消息将提出更改此配置参数作为解决方法。如果将此选项传递到请求中,则会将其持久化到生成的新git repo中。

git-p4.metadataFallbackEncoding

指定使用“fallback”策略(请参见git-p4.metadataDecodingStrategy)解码Perforce作者名称和changelist描述时要使用的备用编码。
仅当解码为utf-8失败时,才会使用回退编码。

此选项默认为常见的Windows编码cp1252。
如果将此选项传递到请求中,则会将其持久化到生成的新git repo中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接