有没有办法比较所有分支上的文件?

时间:2020-08-19 08:47:05

标签: git git-diff

我知道我可以使用git diff来检查某个文件在两个指定分支之间的差异。
可以在一个命令中为所有分支完成此操作吗?
它还会包括已删除的分支吗?

1 个答案:

答案 0 :(得分:1)

可以在一个命令中为所有分支完成此操作吗?

否。

它还会包括已删除的分支吗?

否。

重要的是要意识到,从某种意义上说,Git确实没有分支。 (尽管如此,它确实有其他含义。)Git的名称是分支名称。尽管它们确实很重要,但它们并不像人们最初想象的那么重要。

Git真正涉及的是提交。它与文件无关,尽管提交包含文件。尽管分支名称标识特定的提交,但与分支名称无关。 Git与 commits 有关。当您运行git diff br1 br2时,是在告诉Git对两个特定的 commits 进行比较。

每个提交都存储Git知道的(或者更确切地说,在您或其他人进行该提交时)知道的所有文件的完整快照。这是每次提交的主要数据。每个提交还存储一些元数据或有关提交本身的信息,例如谁(姓名和电子邮件地址)进行了提交,何时(日期和时间戳记)以及为什么(它们的日志消息)。提交)。

商品已编号,但数字是外观随机的哈希ID,而不是简单的计数数字。哈希ID实际上完全是 non 随机的,因为它们是提交内数据和元数据的加密校验和。 Git通过其哈希ID查找提交:在存储库中有一个很大的对象数据库,对象由这些哈希ID编号。 (提交是此对象数据库中的四种对象类型之一。)

因为哈希ID 校验和,所以任何提交的任何部分都无法更改。您通常将 new 提交添加到存储库。 (可以放弃 ,但只能在特定条件下使用。)

每个提交都将其直接前一个提交的哈希ID(有时是哈希ID,复数)存储为元数据的一部分。这样,Git可以从(某个分支的) last 提交开始并向后工作,一次提交一次:

... <-F <-G <-H

这里H代表某些提交链的 last 提交的哈希ID。在Git可以从对象数据库中读取的提交H中,有较早提交G的哈希ID。这样,Git可以在对象数据库中找到G;在该对象内部,有较早提交F的哈希ID。这样,Git可以找到具有另一个哈希ID的F,依此类推。这是Git存储库中的历史记录。

但是这给Git带来了问题。如何快速轻松地找到 last 提交的哈希ID?例如,在上面,Git将在哪里找到哈希ID H

分支名称解决了此问题。每个名称都具有一(1)个哈希ID,根据定义,哈希ID是链中的 last 提交。因此,如果master拥有哈希ID H,我们将:

...--F--G--H   <-- master

如果存在另一个分支名称,则该另一个分支名称将保留某个提交的哈希ID-可能是H,可能是GF,或者可能是{{1之后的一些提交}}。也许H拥有某个提交develop的哈希ID,其提交为I

G

现在,名称...--F--G--H <-- master \ I <-- develop 和名称master各自选择了一个特定的提交。

您可以运行develop并为其提供原始哈希ID;或者您可以运行它并为其指定分支名称。当给它命名分支名称时,Git只是查找名称并找到哈希ID,然后对两个哈希ID运行diff。

所以:

有没有一种方法可以比较所有分支上的文件?

是:列举所有有趣的提交,然后以您喜欢的任何方式运行git diff。例如:

git diff

将以简写形式{git for-each-ref --format='%(refname:short)' refs/heads master等(而不是其全名develop,{{1 }}等。

要将提交C1中的特定文件的快照与提交C2中的快照进行比较,可以使用:

refs/heads/master

refs/heads/develop之后的 pathspec 参数将差异限制为仅一个文件。 (git diff C1 C2 -- path/to/file 本身在这里是可选的;出于习惯使用它通常是一个好主意,以避免在更复杂的--使用中产生歧义。)

如果要比较(例如)名称为--的提交中的快照与名称为git diff所标识的提交中的快照:

master

将完成这项工作。因此,如果您想一次将develop中的提交与每个分支中的提交进行比较:

git diff master develop -- path/to/file
例如,

可以解决问题。如上所示,填写master

请注意,git for-each-ref ... | while read branch; do git diff master $branch -- path/to/file done 将打印for-each-ref,因此您将运行一个for-each-ref,它将从字面上比较master的小费提交。文件将匹配,这意味着git diff master master -- path/to/file将不打印任何内容,但这 有点浪费。如果您不喜欢这种浪费,请添加代码以测试master是否为git diff,如果是,则跳过$branch步骤(但请注意,此测试本身还会添加一些计算工作,对于每个 other 名称,这都是很浪费的:TANSTAAFL 1 )。


1 没有免费的午餐

相关问题