git:补丁不适用


289

我有一个名为my_pcc_branch.patch的补丁。

当我尝试应用它时,出现以下消息:

$ git apply --check my_pcc_branch.patch
warning: src/main/java/.../AbstractedPanel.java has type 100644, expected 100755
error: patch failed: src/main/java/.../AbstractedPanel.java:13
error: src/main/java/.../AbstractedPanel.java: patch does not apply

这是什么意思?

我该如何解决这个问题?


周围有任何AbstractedPanel.java.rej文件吗?通常,这意味着线路bot在源代码和补丁程序中都发生了更改(这里的第13行似乎受到了影响)。
鲁迪

不,我没有找到任何* .rej文件。
Dmitrii Pisarenko

不知道为什么接受的答案会解决它(所以我怀疑这是一个红鲱鱼),但是并不has type 100644, expected 100755意味着某个地方的chmod权限不匹配吗?
鲁芬

Answers:


322

git apply --reject --whitespace=fix mychanges.patch 为我工作。

说明

--reject如果无法确定如何应用补丁,该选项将指示git不失败,但可以应用单个大块,而是可以应用它并.rej为无法大块的创建块拒绝文件()。Wiggle可以“应用[这些]被拒绝的补丁并执行逐字比较”。

此外,--whitespace=fix还会警告空白错误并尝试修复它们,而不是拒绝应用其他适用的块。

这两个选项一起使修补程序的应用程序更能抵抗故障,但是在结果方面需要额外注意。

有关整个文档,请参阅https://git-scm.com/docs/git-apply


8
这实际上对我来说更好,因为它不能完全修改我的文件
Wayne Werner 2014年

10
这很棒。只是拒绝它无法解决的问题,然后可以手动修改被拒绝的文件。
丹尼斯2014年

1
patch -p1 <mychanges.patch#逐块应用更改。如果更改失败,则会创建一个<sourcefile> .orig和<sourcefile> .rej补丁,您可以手动应用更改。我猜git apply --reject做同样的事,--whitespace = fix更好。
gaoithe 2014年

7
.rej当无法自动检测到如何应用补丁时,此命令将创建文件。您可以使用摆动来解决此类问题。
goodniceweb '16

14
这个答案没有任何解释,特别是在什么情况下会起作用。人民,您真的必须对答案质量有更高的要求,所以这不是一个论坛。
奥利弗

318

建议使用以下命令行参数从msysgit@googlegroups.com邮件列表中的Johannes Sixt:

git apply --ignore-space-change --ignore-whitespace mychanges.patch

这解决了我的问题。


25
谁能帮我解释一下为什么行得通吗?另一个答案对我不起作用,我遇到的问题与问问者所描述的完全相同。文件属性与忽略空格有什么关系?
skrebbel

1
使用Windows Powershell已成功应用git diff制作的补丁,如下所示:git diff HEAD..613fee-myfile.xml | git apply --ignore-space-change --ignore-whitespace,但是如果有人遇到相同的问题,首先将diff输出保存为文件是行不通的
tjb 2012年

2
也可以尝试-C1切换为Apply(应用),这样可以减少被认为很重要的添加内容的上下文。
阿米尔·阿里·阿克巴里

2
@ EricWalker,CR / LF的git magic不一定是一件坏事。另一种选择是,更改集的一半由每个被触摸的文件中的每一行组成,从一行到另一行更改,而实际更改则埋在中间。
jwg

3
这有时会有所帮助。但是有时,我仍然会收到“补丁不适用”的消息,即使该补丁应该没有问题也可以应用。
Thomas Levesque

118

当一切都失败了,尝试git apply--3way选项

git apply --3way patchFile.patch

--3way
如果补丁不能很好地应用,如果该补丁记录了它应该应用于的Blob的标识,并且我们可以在本地使用这些Blob,则可以退回3路合并,方法是将冲突标记保留在文件中供用户解析的工作树。此选项暗含--index选项,并且与--reject和--cached选项不兼容。

典型的失败案例会尽可能多地应用补丁,并且会给您带来冲突,因此您通常无法这样做。大概比reject其他步骤容易一步。


2
这是对我有用的答案。我正在修补的文件没有反映出我生成补丁的更改(因为在创建补丁后删除了更改。)
Christia

3
不错的一般解决方案。3way diff看起来并不像通常那样,因此对此感到有些困惑,但是从没有那么少,这使我能够解决冲突并获得应用补丁的能力。
steinybot '18年

8
我认为这--3way应该是默认行为。如果修补失败,请至少告诉我什么失败,以便我可以手动修复它。git apply只是失败而没有报告失败的原因。我什至找不到*.rejhg生成的文件。
Pavan Manjunath '18年

4
绝对是最好的解决方案。让用户解决自己的矛盾!
Mosh Feu

56

此命令将应用补丁而不解决它,从而留下错误的文件为 *.rej

git apply --reject --whitespace=fix mypath.patch

您只需要解决它们。解决后,运行:

git -am resolved

7
解决方法*.rej-我所能找到的就是在源文件中手动进行更改并删除这些.rej文件。还有其他方法吗?
coding_idiot

1
@coding_idiot像往常一样,只需检查.rej文件,将它们与冲突的文件进行比较,最后将固定文件添加到索引中(使用“ git add FIXED_FILES”)
Ivan Voroshilin

2
@coding_idiot,您可以使用摆动来解决它。例如:wiggle --replace path/to/file path/to/file.rej。此命令会将更改从.rej文件应用于原始文件。它还会创建原始文件的副本,例如path/to/file.porig。请检查文档以获取有关wiggle的更多信息
goodniceweb '16

22

尝试使用此处建议的解决方案: https //www.drupal.org/node/1129120

patch -p1 < example.patch

这帮助了我。


3
我知道您不应该这样做,但是非常感谢!节省了我几个小时。我收到“补丁不适用”和各种错误。
sudo rm -rf斜线

@ sudorm-rfslash,为什么我们不应该这样做,但是为什么要这么做呢?
黑色

git: 'patch' is not a git command.git version 2.21.1 (Apple Git-122.3)
Sridhar Sarnobat

16

当您混合使用UNIX和Windows git客户端时会发生这种情况,因为Windows并不真正具有“ x”位的概念,因此rw-r--r--msys POSIX层将“在Windows下对(0644)文件的检出”提升为rwx-r-xr-x(0755) 。git认为模式差异与文件中的文本差异基本相同,因此您的补丁不会直接应用。我认为您唯一的好选择是设置core.filemodefalse(使用git-config)。

这是一个msysgit问题,其中包含一些相关信息:http : //code.google.com/p/msysgit/issues/detail? id=164 (已路由至archive.org 2013年12月3日的副本)


2
我试图运行命令“ git config core.filemode false”,但没有帮助-我仍然收到相同的消息。
Dmitrii Pisarenko

假设树中没有未提交的更改,请尝试git reset --hard HEAD强制git重新启用有效的新选项来检出文件。
本杰克逊

刚尝试执行“ git reset --hard HEAD”。它成功完成了(我看到了消息“ HEAD is at at ...”),但是“ git apply”的问题仍然存在。
Dmitrii Pisarenko

7

就我而言,我很愚蠢,一开始就错误地创建了补丁文件,实际上是在以错误的方式进行区分。我最终得到了完全相同的错误消息。

如果你在掌握并做 git diff branch-name > branch-name.patch,这会尝试删除您想要发生的所有添加,反之亦然(对于git而言,这是不可能完成的,因为显然,从未删除过的添加操作无法删除)。

因此,请确保您签出您的分支并执行 git diff master > branch-name.patch


3

警告:此命令可以永久删除旧的丢失的提交。尝试进行复制之前,请复制整个存储库。

我找到了这个链接

我不知道为什么会这样,但是我尝试了很多解决方法,这是唯一对我有用的方法。简而言之,运行以下三个命令:

git fsck --full
git reflog expire --expire=now --all
git gc --prune=now

3
这是一个非常危险的命令,可以从reflog中永久删除旧的丢失的提交。如果您的存储库处于不稳定状态,请不要应用此功能。
美国东部时间

0

我在这里未完全指出我所寻找的内容,我是为了其他可能会搜索相似内容的人而写。我遇到了一个问题(存在于旧仓库中),该文件已从仓库中删除。当我应用补丁时,由于找不到要应用的文件,补丁失败。(所以我的情况是git补丁无法删除文件)'#git apply --reject'确实给出了一个观点,但并没有完全解决这个问题。我无法使用摆动,因为它在构建服务器中不可用。就我而言,我通过从尝试应用的补丁文件中删除了“已从存储库中删除的文件”的条目来解决了这个问题,因此我应用了所有其他更改而没有出现问题(使用三向合并,避免了空格错误),然后手动将删除的文件内容合并到其移动位置。


0

我的问题是,我先运行git diff,然后又运行git reset --hard HEAD,然后意识到我想撤消操作,所以我尝试将输出从复制git diff到文件中并使用git apply,但是出现了“补丁不适用”的错误。切换patch并尝试使用它后,我意识到由于某种原因重复了diff的大部分,并且删除了重复的patch(大概也是git apply)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.