我已经使用 Git 好几年了,一直想知道为什么git diff
在修改文件的名称前加上a/
和b/
. 我预计最终会偶然发现一个有用的用例,但直到现在它总是很烦人,而且从来没有帮助过。
到底有什么好处呢?为什么默认启用此功能?在什么情况下有用?
如diff 手册页中所述,表示区分源和目标的前缀a/
。b/
实际上,您有以下选择:
--no-prefix
不要显示任何源或目标前缀。
--src-prefix=<prefix>
显示给定的源前缀而不是“a/”。
--dst-prefix=<prefix>
显示给定的目的地前缀而不是“b/”
如果您觉得它没有用,您可以使用以下命令将其关闭:
git config --global diff.noprefix true
这些目录前缀基本上是为了兼容性,并被选为合理的默认值。解释如下。
在 git (和其他VCS)之前,为多个文件创建补丁的工作流程可能如下所示:
asdf
在目录中有一个项目的源代码asdf-source.latest
。asdf-source.new
,最好是硬链接里面的文件)。asdf-source.new
,尝试编译代码,测试它等。diff -r asdf-source.latest asdf-source.new >new_feature.patch
。输出也随时间演变。除此之外,git 默认使用“统一”输出,可以使用 diff 的-u
参数获取。现在您可以看到补丁包含使用目录名称更改文件的路径。
然后,应用您的补丁的人(或构建脚本等)将使用patch
而不是使用git apply
or git am
。为了让命令找到正确的文件,必须使用 patch 的-pN
选项从路径中删除目录名(N 显示要删除的目录名和分隔符的数量)。在上述情况下,使用的命令可能是patch -p1 <new_feature.patch
. 这使得补丁创建者可以使用他/她自己的目录名称。
如果您遇到使用大量补丁(通常用于Linux 发行版中的稳定软件包版本的后向移植补丁)修补某个项目的脚本,则补丁的格式可能会有所不同。该patch
命令能够正确检测这些格式,但路径有点困难(要删除多少目录)。一些问题:
patch
文件可能很危险(因为它可能会找到不同的文件)。因此,让每个人都发送可以应用的补丁patch -p1
似乎是最明智的做法。
创建 git 时,它采用了合理的默认值(与大多数项目的提交指南兼容,主要是内核)用于此类选项。多亏了这一点,您可以使用 git 并将格式正确的补丁发送给使用patch
它的人,反之亦然(git 也能够处理diff
-created 补丁)。将“a”和“b”作为前缀尤其可以节省空间(和一小部分带宽),同时保持一切正常。
您可以设置git config diff.mnemonicprefix true
以便 git 根据您要比较的内容使用不同的前缀(有关详细信息,请参阅git help config
)。
如果要手动添加git diff --no-prefix
到.gitconfig中,只需添加以下内容:
[diff]
noprefix = true
就是区分源头和目的地。您还可以将其更改为更有意义:
--src-前缀=
<prefix>
Show the given source prefix instead of "a/".
--dst-前缀=
<prefix>
Show the given destination prefix instead of "b/".