git 申请 --reject 与 git 申请 --3way
git apply --reject vs git apply --3way
我们有数百个存储库,并定期从上游接收补丁。作业使用 git apply --check <patch>
应用这些补丁。如果没有错误,将使用 git apply <patch>
应用补丁并提交更改。如果有任何错误,补丁将被标记为 conflict
。然后将错误和冲突的补丁交付给我们的存储库维护人员。他们使用 git apply --reject <patch>
应用补丁并解决冲突。
按照我之前的理解,git apply --reject
是靠谱的。然而,一位维护者报告说补丁的应用方式完全错误。一些新行被插入到意外函数中的一个块中,而该函数恰好具有相同的上下文。还有其他一些错误的块。
例如补丁中的chunk是
@@ -1757,9 +1757,9 @@ def FunctionAAA()
print('hi')
}
+ print('hello world')
print('good day')
return True
但是在应用的文件中,chunk是
@@ -1927,9 +1997,9 @@ def FunctionBBB() ---> in another function
print('hi')
}
+ print('hello world')
print('good day')
return True
维护者很可能没有注意到错位的行,这会导致构建错误或更糟糕的隐藏错误。我让维护者尝试 git apply --3way <patch>
并且补丁按预期应用,尽管仍然存在冲突。
我认为 git apply --reject
和 git apply --3way
表现不同是因为它们使用不同的算法。从结果来看,我想我们需要采用git apply --3way
。但我也担心 --3way
在某些情况下可能会意外工作。
为什么 git apply --reject
以看似错误的方式工作,而不是将块视为冲突?在我们的情况下哪个更好?有没有更好的解决方案来应用补丁?谢谢。
git version 2.31.1
ubuntu 4.15.0-76-generic
TL;DR:如果可能的话,您确实想要 --3way
。
这里有一些历史。 git apply
命令最初至少部分是 Larry Wall's historical patch
command. This patch command always operates in --reject
mode (see the documentation: (POSIX), (non-POSIX)) 的或多或少的克隆。当运行处于这种模式时,它从不进行三向合并。
另一方面,补丁有缺陷:应用于上下文匹配的 模糊因子 允许插入指示的更改,即使上下文实际上不匹配。 (Git 的 apply
没有模糊。)上下文匹配可能会出错,就像你的情况一样,找到一个类似的 looking 函数,但不是正确的功能。三向合并通过三个输入避免了这些问题:
- 合并基地,或共同起点;
- 您的 文件版本;和
- 他们的 文件版本。
Git 可以使用 Git 补丁中的 Index:
行构建其中两个版本,其中包含文件基本版本的 blob 哈希 ID。 Git 只是使用哈希 ID 在存储库中找到正确的 blob 对象。如果该对象存在,那就是他们在 diff 中作为“之前”副本拥有的文件,因此 Git 可以提取该对象,完全按照它出现的方式应用补丁,并生成文件的“他们的”版本. Git 现在可以对三个文件进行正常的三向合并。
--3way
选项在两种情况下失败:
如果没有 Index:
行给出合并基础版本,Git 就无法知道文件的哪个副本是上下文差异
如果有一个有效的索引行,但您的存储库中没有该对象,Git 无法构建文件的基础副本和他们的副本。
在这些情况下,唯一可用的选项是回退:尝试找到正确的上下文(并希望很多并在需要时使用 --reject
)。
我们有数百个存储库,并定期从上游接收补丁。作业使用 git apply --check <patch>
应用这些补丁。如果没有错误,将使用 git apply <patch>
应用补丁并提交更改。如果有任何错误,补丁将被标记为 conflict
。然后将错误和冲突的补丁交付给我们的存储库维护人员。他们使用 git apply --reject <patch>
应用补丁并解决冲突。
按照我之前的理解,git apply --reject
是靠谱的。然而,一位维护者报告说补丁的应用方式完全错误。一些新行被插入到意外函数中的一个块中,而该函数恰好具有相同的上下文。还有其他一些错误的块。
例如补丁中的chunk是
@@ -1757,9 +1757,9 @@ def FunctionAAA()
print('hi')
}
+ print('hello world')
print('good day')
return True
但是在应用的文件中,chunk是
@@ -1927,9 +1997,9 @@ def FunctionBBB() ---> in another function
print('hi')
}
+ print('hello world')
print('good day')
return True
维护者很可能没有注意到错位的行,这会导致构建错误或更糟糕的隐藏错误。我让维护者尝试 git apply --3way <patch>
并且补丁按预期应用,尽管仍然存在冲突。
我认为 git apply --reject
和 git apply --3way
表现不同是因为它们使用不同的算法。从结果来看,我想我们需要采用git apply --3way
。但我也担心 --3way
在某些情况下可能会意外工作。
为什么 git apply --reject
以看似错误的方式工作,而不是将块视为冲突?在我们的情况下哪个更好?有没有更好的解决方案来应用补丁?谢谢。
git version 2.31.1
ubuntu 4.15.0-76-generic
TL;DR:如果可能的话,您确实想要 --3way
。
这里有一些历史。 git apply
命令最初至少部分是 Larry Wall's historical patch
command. This patch command always operates in --reject
mode (see the documentation: (POSIX), (non-POSIX)) 的或多或少的克隆。当运行处于这种模式时,它从不进行三向合并。
另一方面,补丁有缺陷:应用于上下文匹配的 模糊因子 允许插入指示的更改,即使上下文实际上不匹配。 (Git 的 apply
没有模糊。)上下文匹配可能会出错,就像你的情况一样,找到一个类似的 looking 函数,但不是正确的功能。三向合并通过三个输入避免了这些问题:
- 合并基地,或共同起点;
- 您的 文件版本;和
- 他们的 文件版本。
Git 可以使用 Git 补丁中的 Index:
行构建其中两个版本,其中包含文件基本版本的 blob 哈希 ID。 Git 只是使用哈希 ID 在存储库中找到正确的 blob 对象。如果该对象存在,那就是他们在 diff 中作为“之前”副本拥有的文件,因此 Git 可以提取该对象,完全按照它出现的方式应用补丁,并生成文件的“他们的”版本. Git 现在可以对三个文件进行正常的三向合并。
--3way
选项在两种情况下失败:
如果没有
Index:
行给出合并基础版本,Git 就无法知道文件的哪个副本是上下文差异如果有一个有效的索引行,但您的存储库中没有该对象,Git 无法构建文件的基础副本和他们的副本。
在这些情况下,唯一可用的选项是回退:尝试找到正确的上下文(并希望很多并在需要时使用 --reject
)。