Git diff 的/a/b 前缀的原因是什么

我已经使用 Git 好几年了,一直想知道为什么 git diff在修改过的文件名前面加上 a/b/的前缀。我希望最终能偶然发现一个有用的用例,但直到现在,它总是令人讨厌,而且从来没有帮助。

它有什么好处? 为什么默认启用它? 在哪些情况下它有用?

22461 次浏览

正如在 Diff 手册中提到的,a/b/代表前缀来区分源和目的地。

事实上,你可以选择:

--no-prefix

不要显示任何源或目标前缀。

--src-prefix=<prefix>

显示给定的源前缀,而不是“ a/”。

--dst-prefix=<prefix>

显示给定的目标前缀,而不是“ b/”


美国佬 Suave 在 评论中补充道:

他说:

git diff --src-prefix="SRC " --dst-prefix="DST "

使双击选择和粘贴工作。

这是为了区分来源和目的地,你也可以把它变得更有意义:

—— src-prefix = <prefix>

Show the given source prefix instead of "a/".

—— dst-prefix = <prefix>

Show the given destination prefix instead of "b/".

Http://git-scm.com/docs/git-diff

如果你觉得它没用,你可以关掉它:

git config --global diff.noprefix true

这些目录前缀基本上是为了兼容性而选择的,并作为合理的默认值。

走之前

在 git (和其他 VCS)之前,为多个文件创建补丁程序的工作流可以是:

  • 假设在目录 asdf-source.latest中有一个项目 asdf的源代码。
  • 将目录复制到一个新的目录(例如,asdf-source.new,最好是 硬连接中的文件)。
  • 现在您可以在 asdf-source.new中进行所有更改,尝试编译代码,测试代码,等等。
  • 完成后,使用例如 diff -r asdf-source.latest asdf-source.new >new_feature.patch创建一个补丁。输出也随着时间的推移而发生变化。除此之外,git 默认使用“统一”输出,这可以使用 diff 的 -u参数获得。

现在您可以看到修补程序使用目录名指向已更改的文件。

应用补丁的人(或构建脚本等等)将使用 patch,而不是使用 git applygit am。为了让命令找到正确的文件,必须使用补丁的 -pN选项从路径中删除目录名(N 显示要删除的目录名和分隔符的数量)。在上面的例子中,使用的命令可以是 patch -p1 <new_feature.patch。这使得修补程序创建者可以使用他/她自己的目录名。

如果您遇到使用大量补丁修补某个项目的脚本(例如,通常用于 Linux 发行版中稳定包版本的 后移补丁) ,那么补丁的格式可能会有所不同。 patch命令能够正确地检测这些格式,但是对于路径(要删除多少个目录)则有点困难。 有些问题:

  • 强制开发人员使用0个目录并不太好。
  • patch查找文件可能是危险的(因为它可能会找到不同的文件)。

因此,让每个人都发送可以用 patch -p1应用的补丁似乎是最明智的选择。

回去工作

在创建 git 时,它为这些选项采用了合理的默认值(这与大多数项目的提交准则(主要是内核)兼容。由于这一点,你能够使用 git,并发送一个正确格式的补丁给使用 patch应用它的人,反之亦然(git 也能够处理由 diff创建的补丁)。特别是以“ a”和“ b”作为前缀可以节省空间(和一小部分带宽) ,同时保持一切正常运行。

您可以设置 git config diff.mnemonicprefix true,以便 git 根据所比较的内容使用不同的前缀(有关更多细节,请参见 git help config)。

如果要手动将 git diff --no-prefix添加到 。 gitconfig,只需添加以下内容:

[diff]
noprefix = true