git - 当 /usr/bin/patch 成功时,为什么 git apply 失败?
问题描述
解决方案
(一个执行摘要 TL;DR:补丁不是提交;格式补丁用于提交。旧patch
命令是关于补丁的,git apply
介于转换工具和只是一部分之间git am
。)
这里有几个关键问题:
从您的
patch
输出来看,补丁的某些部分似乎已经应用,而有些则没有。该patch
命令将询问是否对每个大块使用反转选项,但git apply
要求反转适用于每个大块,或不应用大块。所以它不会做补丁在这里做的事情。鉴于某些补丁因此不会应用,
git apply
需要选择--reject
应用其余补丁。该patch
命令假定等效(总是愿意创建一个.rej
文件)。(在您的情况下,让补丁取消应用一半的差异并应用另一半来解决这个问题。)patch
假设默认模糊因子为 2;您的几个补丁适用于模糊。patch
模糊因子是允许忽略的上下文行数。默认情况下,git apply
要求所有上下文行匹配:这相当于-F 0
inpatch
。git patch
您可以在使用-C
参数时获得模糊因子的效果。
所以,如果你跑了git apply -C 1 --reject
,这个补丁很可能会被拒绝。patch
除非您对每次逆转说不,否则结果将与您得到的结果不匹配。
(旁注:--recount
实际上是用于编辑的补丁,而不是用于上下文搜索调整。)
关于格式补丁
我也发生了一个类似的重要问题:生成的补丁
format-patch
甚至没有应用patch
,所以我做了git diff master..BRANCH > adhoc.patch
并且它有效!
这既不足为奇(因为它发生了),也值得密切关注(当它确实发生时),因为这意味着你没有得到你希望得到的东西。仔细看看,看看是什么,然后用它来决定如何得到你想要的——不管最后可能是什么。
所做的是git format-patch
将一些普通的提交——即一些单父提交——或一些这样的提交系列,转换为包含足够信息来重构每个提交的电子邮件文本文件。1 (该git am
命令进行重建。稍后重建这些提交,例如,从邮箱格式输入文件,通常会保留原始作者,但会产生不同的提交者。)
什么git diff
是任意两个任意提交2并比较它们并生成一个补丁,如果应用该补丁,则将左侧提交给出的快照转换为右侧提交给出的快照。在这里,两个提交分别是 的master
和 的BRANCH
。双点语法 ,git diff master..BRANCH
逐渐被弃用,取而代之的是git diff master BRANCH
语法,但两者的含义完全相同。
请注意,可能没有一组提交会由单个git format-patch
命令发出,该命令会将master
快照提示转换为快照提示BRANCH
。例如,假设我们有以下提交:
I--J--K <-- master
/
...--G--H
\
L--M--N <-- BRANCH
该git format-patch
命令可以一次性格式化L-M-N
补丁(生成三个可通过电子邮件发送的重建文件),但这些需要应用于提交H
以重现匹配L
、M
和N
. 或者,git format-patch
可以一次性格式化I-J-K
补丁;但是这些也需要应用于 commit H
,而不是 commit K
,以便产生 commit K
。
如果您拥有的是与 commit 匹配的快照(不是 Git 存储库,只是一个快照)K
,您可以将三个补丁转换H
为K
并反转它们以在本地获取另外三个快照,它们相当于J
, I
, 然后H
; 然后,您可以在正常的向前方向上添加产生 、 和 finally 的L
三个M
补丁N
。
但是,正如我们从上图中所看到的,没有任何提交可以让我们一步一步从 commitK
到 commit N
。为了获得一个让我们一步到位的补丁,我们必须直接区分提交。这样的补丁不能重新创建之前的任何提交:如果我们只有与 相关的快照,并且我们应用此补丁,我们将获得与 相关的快照,但我们不知道是什么样的,例如。K
N
K
N
H
如果某个补丁(或某些格式补丁输出)的接收者具有适当的 Git 存储库,他们可以应用格式补丁输出,只要他们具有所需的基本提交,并获得等效的提交(尽管具有不同的提交者信息)。例如,这对于仔细审查特别有帮助。但是,如果接收者没有必要的提交——甚至可能根本没有 Git 存储库——那么format-patch
结果就没有那么有用了,无论如何,一个简单的一次性git diff
补丁可能是最好的。详细信息因收件人而异。
1--stdout
format-patch 命令还可以生成适合直接馈送到的单个输出流 ( ) git am
,但现在它更适用于生成一个包含可发送电子邮件的文件的目录,适合馈送到git send-email
. 这适用于各种 Linux 组、Git 项目本身等使用的电子邮件补丁方法。
2该git diff
命令可以采用其他不一定是提交的输入,但在这种情况下 ( master..BRANCH
),我们获得了比较两个提交的模式。
推荐阅读
- php - imagesx() 期望参数 1 是资源,给定字符串
- javascript - 在 javascript 中计算 SHA1 哈希,UTF-16 字符串的问题
- powershell - Powershell通过映射网络驱动器删除sharepoint在线库中的所有文件扩展名
- terraform - Terraform:“for”表达式结束后的额外字符
- expo - 无法连接到 TCP 端口:尝试在 WSL2 中的 Android 模拟器上打开 Expo 应用程序时连接被拒绝
- javascript - iframe 不显示 PDF
- html - 我想为随机文本生成器创建最简单的 HTML 代码
- awk - 使用 grep 或 awk 搜索列并存储在变量中
- python - 如何在 Pytorch 中使用 Wasserstein 距离自定义损失函数?
- angular - Angular 库 ng-packagr 不会用相对路径替换 tsconfig 路径