Git/Diff 补丁技术说明
我正在尝试使用 git format-patch 从一个存储库创建补丁并将其应用到另一个存储库。令我惊讶的是,即使这两个文件非常不同,它仍然有效。有人可以解释一下 git 到底如何处理应用补丁的技术吗?显然它不仅仅使用行号,所以如果有人能指出我正确的方向那就太棒了。
I was experimenting using git format-patch to create patches from one repo and applying it to another repo. To my surprise it worked even though those two files were extremely diff. Can someone explain the technicals on how exactly git handles applying a patch? Obviously it doesn't just use line numbers, so if someone can point me in the right direction that would be awesome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有两种主要方式可以将补丁应用于修改的文件:
上下文行(前面有一个空格而不是
+ 或
-
)是统一差异的一部分Git 的 diff 格式主要基于 格式。它们是额外的行,在“原始”和“修改的”源文件中相同,但围绕修改的区域。这些上下文行(以及预修改行(即删除/更改的行))由应用差异的程序使用,以查找应应用每个差异“块”的位置,即使目标“目标”文件已插入或删除正常目标位置之前的行(正常位置由行号指定,由于插入/删除的行,行号在“目标”文件(相对于“原始”文件)中已有效更改)。Git 的 diff 格式还包括每个修改文件的特殊“索引”行,指示“原始”和“修改”文件的对象 ID(即缩写的 SHA-1 哈希值)。如果目标存储库的对象存储中有“原始”文件,则它可以使用它来精确重建“修改”文件的内容,然后执行 文件的三个版本之间的三向合并:“原始”、“修改”(两个源文件)和“目标”(目标)文件)。这是由 git am -3 使用的,可以帮助自动解决补丁和“目标”文件之间的一些冲突。
There are two main ways patches can be applied to modified files:
The context lines (preceded by a single space instead of a
+
or-
) are a part of the unified diff format upon which Git’s diff format is largely based. They are extra lines that are identical in the “original” and “modified” source files but that that surround the modified regions. These context lines (along with the pre-modification lines (i.e. deleted/changed lines)) are used by the program that applies the diff to find where each diff “hunk” should be applied even if the destination “target” file has already inserted or removed lines before the normal target location (the normal location is specified by line numbers, which have effectively changed in the “target” file (with respect to the “original” file) because of the inserted/removed lines).Git’s diff format also includes a special “index” line for each modified file that indicate the object ids (i.e. abbreviated SHA-1 hashes) for the “original” and “modified” files. If the destination repository has the “original” file in its object store, it can use it to exactly reconstruct the content of the “modified” file and then perform a three-way merge between the three versions of the file: “original”, “modified” (both source files) and “target” (the destination file). This is used by
git am -3
and can help automatically resolve some conflicts between the patch and the “target” file.