git am error:"补丁不适用"

nan*_*qcz 70 git

我试图使用git将几个提交从一个项目移动到第二个类似的提交.

所以我创建了一个包含5个提交的补丁:

git format-patch 4af51 --stdout > changes.patch
Run Code Online (Sandbox Code Playgroud)

然后将补丁移动到第二个项目的文件夹并想要应用补丁:

git am changes.patch 
Run Code Online (Sandbox Code Playgroud)

...但它给了我错误:

Applying: Fixed products ordering in order summary.
error: patch failed: index.php:17
error: index.php: patch does not apply
Patch failed at 0001 Fixed products ordering in order summary.
The copy of the patch that failed is found in:
   c:/.../project2/.git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Run Code Online (Sandbox Code Playgroud)

所以我打开了index.php,但没有改变.我假设有一些>>>>>>>标记等,比如在解决合并冲突时,但文件中没有标记冲突.git status还给了我一个空的变更文件列表(只有changes.patch那里).所以我跑git am --continue,但出现另一个错误:

Applying: Fixed products ordering in order summary.
No changes - did you forget to use 'git add'?
If there is nothing left to stage, chances are that something else
already introduced the same changes; you might want to skip this patch.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort". 
Run Code Online (Sandbox Code Playgroud)

我使用的是Windows 7和最新的git版本"1.9.4.msysgit.1"

PS经过几个小时的谷歌搜索,我找到了一些解决方案,但没有什么对我有用:


git am -3 changes.patch 
Run Code Online (Sandbox Code Playgroud)

给出了奇怪的"sha1信息"错误:

Applying: Fixed products ordering in order summary.
fatal: sha1 information is lacking or useless (index.php).
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge.
Patch failed at 0001 Fixed products ordering in order summary.
The copy of the patch that failed is found in:
   c:/.../project2/.git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort". 
Run Code Online (Sandbox Code Playgroud)
git am changes.patch --ignore-whitespace --no-scissors --ignore-space-change
Run Code Online (Sandbox Code Playgroud)

如上所述给出第一个错误:"错误:补丁失败:index.php:17",但没有index.php添加冲突标记.

tor*_*rek 95

什么是补丁?

补丁比一系列指令更多(见下文):"在这里添加","删除那里","将第三件事改为第四件".这就是 git告诉你的原因:

The copy of the patch that failed is found in:
c:/.../project2/.git/rebase-apply/patch
Run Code Online (Sandbox Code Playgroud)

您可以在您喜欢的查看器或编辑器中打开该补丁,在您喜欢的编辑器中打开要更改的文件,并使用您所知道的(并且git没有)"手动应用"补丁来弄清楚如何 "添加"这里要做的是"当要更改的文件现在看起来很少或什么都不像他们之前更改时所做的那样,将这些更改作为补丁传递给您.

再来一点

三向合并引入了比简单的"一系列指令"更多的"信息":它告诉你文件的原始版本是什么.如果您的存储库具有原始版本,那么您的git可以将对文件所做的操作与修补程序对文件所做的操作进行比较.

如上所述,如果您请求三向合并,git无法在其他存储库中找到"原始版本",因此它甚至无法尝试三向合并.因此,您没有获得冲突标记,您必须手动执行补丁程序.

运用 --reject

当您必须手动应用补丁时,git仍然可以自动应用大部分补丁,只留下几个部分,能够推断代码(或者需要修补的任何东西) .添加--rejecttell git来做到这一点,并将补丁的"不适用"部分留在拒绝文件中. 如果使用此选项,则仍必须手动应用每个失败的补丁,并弄清楚如何处理被拒绝的部分.

完成所需的更改后,您可以git add修改文件并使用它git am --continue来告诉git提交更改并转到下一个修补程序.

如果无事可做怎么办?

由于我们没有你的代码,我无法判断是否是这种情况,但有时候,你最终会找到一些补丁来说明相当于的事情,例如"修复第42行的单词拼写"当那里的拼写已经修好了.

在这种特殊情况下,你看过补丁和当前的代码,应该对自己说:"啊哈,这个补丁应该完全被跳过!" 那是当你使用已打印的其他建议git时:

If you prefer to skip this patch, run "git am --skip" instead.
Run Code Online (Sandbox Code Playgroud)

如果你运行git am --skip,git将跳过该补丁,这样如果邮箱中有五个补丁,它最终只会添加四个提交,而不是五个(如果你跳过两次,则为三个而不是五个,依此类推).

  • 谢谢你的回答.`git am changes.patch --reject`对我来说是最好的,因为它提供了"冲突标记"的替代方法(在.rej文件中找到).然后`git add`,`git am --continue`,一切正常:-) (8认同)
  • @EdRandall:如果您使用`git am`或`git apply -3`*和*您的存储库中有该文件的基本版本,Git应该能够进行三向合并(可能存在合并冲突,课程).请注意,在生成修补程序时,您可能需要发送修补程序的人使用`--full-index`. (3认同)
  • 是的,谢谢.令我惊讶的是,'git am`没有(比如`patch`)尝试应用*do*apply的更改. (2认同)

Mik*_*ton 8

这种错误可能是由 LF 与 CRLF 行结尾不匹配引起的,例如,当您查看补丁文件时,您绝对确定它应该能够应用,但事实并非如此。

为了测试这一点,如果您有一个仅适用于一个文件的补丁,您可以尝试仅在该文件上运行“unix2dos”或“dos2unix”(两者都尝试,以查看哪一个导致文件更改;您可以获取这些适用于 Windows 和 Unix 的实用程序),然后将该更改作为测试提交提交,然后再次尝试应用补丁。如果这有效,那就是问题所在。

NBgit am默认情况下将补丁应用为 LF(即使补丁文件包含 CRLF),因此如果要将 CRLF 补丁应用于 CRLF 文件,则必须使用git am --keep-cr,按照此答案


Pin*_*yni 7

我遇到了这个错误,能够通过使用来克服它: patch -p1 < example.patch

我从这里获取的: https: //www.drupal.org/node/1129120


wul*_*pro 6

git format-patch也有-B国旗。

手册页中的描述还有很多不足之处,但用简单的语言来说,这是格式补丁在完全重写文件之前将遵守的阈值(通过一次删除所有旧内容,然后插入一次一切都是新的)。

当手动编辑太麻烦并且来源比我的目的地更权威时,这对我来说非常有用。

一个例子:

git format-patch -B10% --stdout my_tag_name > big_patch.patch
git am -3 -i < big_patch.patch
Run Code Online (Sandbox Code Playgroud)


srs*_*srs 6

我有同样的问题。我用过

git format-patch <commit_hash>
Run Code Online (Sandbox Code Playgroud)

创建补丁。我的主要问题是补丁由于某些冲突而失败,但我在文件内容中看不到任何合并冲突。我曾经git am --3way <patch_file_path>应用过补丁。

应用补丁的正确命令应该是:

git am --3way --ignore-space-change <patch_file_path>
Run Code Online (Sandbox Code Playgroud)

如果执行上述命令进行补丁,如果补丁应用失败会产生合并冲突。然后您可以修复文件中的冲突,就像解决git merge 的合并冲突一样

  • 这是代码部分的拼写错误。感谢您指出。如果您遵循完整答案,您可能已经注意到,在文本部分中以粗体提到了 --3Way。根据问题,应用补丁后没有显示合并冲突。我遇到了同样的问题,我仅使用该命令解决了它。 (2认同)
  • 我不知道到底为什么,但“--ignore-space-change”选项使我的补丁文件起作用。 (2认同)