“一棵树”是什么意思?

时间:2019-01-11 03:25:56

标签: git

git diff的联机帮助页上说

  

NAME

     

git-diff-显示提交,提交和工作树等之间的更改

     

说明

     

显示工作树与索引或一棵树之间的变化,显示索引与一棵树之间的变化,   在两棵树之间进行更改,在两个 blob对象之间进行更改或在磁盘上的两个文件之间进行更改。

“工作树”是指工作目录吗?

“一棵树”在这里是什么意思?它与提交对象或树对象相同吗? (从字面上看,我认为它意味着一个树对象。但是我想通过将“ DESCRIPTION”部分与“ NAME”部分进行比较,它可能意味着一个提交对象。)

如何将“一棵树”指定为git diff的命令行参数?

如果我也想问一问,如何将“ blob对象”指定为git diff的命令行参数?

谢谢。

2 个答案:

答案 0 :(得分:2)

当前工作目录位于您的Shell认为所在的位置。当前工作树以.git仓库从目录开始。如果显示工作目录,您可能会认为它在移动时会移动-不会。

就从git repo引用树而言,我在文档中没有看到该术语。我记得唯一看到的树是工作树。

但是要完成您要完成的任务,我通常使用特定提交日志行中的签名。如果是当前提交,则说“ HEAD”或您的分支名称都可以。如果是另一个分支的负责人,则可以命名该分支。如果已标记,则标记名称有效。之前的提交还有HEAD ^ 1。

答案 1 :(得分:1)

tree 一词在Git中相当重载(嗯,在一般的计算中)。

工作树工作树(或此拼写的其他变体)是指您从事工作的地方。在这里,文件具有正常的日常格式,并且可读且(在OS愿意的情况下)可写。 (在Unix系统上,如果您chmod -w文件,则将无法编写它们。但这不是Git的错。)

Git中的树对象是一种内部数据结构,用于记录目录树或子树。每个文件或子目录包含一个条目(对于子模块,该子模块包含一个 gitlink 条目)。每个条目都列出文件的可执行模式位,以一种奇怪的编码的是或否标志 1 加上文件名和Blob哈希ID。对于子树,该条目列出目录的名称和子树对象的哈希ID。然后,Git可以递归地遍历子树对象,以根据需要查找更多文件和更多子树。每个文件条目都为Git内部 blob 对象提供一个哈希ID,该对象是文件数据的冻结(只读)压缩副本。

每个提交都保存一(1)个内部Git树对象哈希ID。该树对象包含提交所包含的快照,因此,提交的快照实际上就是这些树之一,其中包含文件和子树的条目。由于每个提交都只有一棵树,因此Git可以将提交说明符转换为树对象:

$ git rev-parse master
3c31a203fbeedb4d746889dc77cbafc395fc6e92
$ git rev-parse master^{tree}
5c4b695f5d5606976f5b72e1a901ed17db30a359

在这种情况下,由master标识的 commit 是第一个大的丑陋哈希,但此提交用于保存内部的 tree 对象文件是第二个。

因此,工作树包含具有真实数据的真实文件,而Git tree对象允许Git查找提交的所有冻结文件,只要您提供与某个提交对应的树对象。 git diff命令需要比较两件事。这两件事既可以是两个单独的文件(这是一种退化的情况),也可以是两个文件的。比较两棵树时,无论它们是树对象还是充满文件的工作树,git diff都会:

  • 比较每棵树中的文件名称
  • 如果它们匹配,则Git假定它们是“同一文件”,并将比较文件的内容。
  • 如果没有具有匹配的名称,则可以选择尝试按内容匹配文件。
  • 如果其他所有方法均失败,请告诉您已删除了一些文件,并添加了一些文件。删除文件的内容全部删除;添加文件的内容是全新的。

这仍然只是一个概述,因为git diff不仅可以做这些事情,但是这些是基础。

还有一个非常重要的皱纹:git diff可以检查索引并将其视为一棵树。该索引保存从某处获取的文件的副本。最初,某处是您git checkout编辑的任何提交。但是,您可以git add将文件从工作树复制到索引中,从而替换提交中存在的版本。您可以git add来自工作树中从未提交的文件,因此是索引的新文件。而且,无论是否有git rm,您都可以--cached个文件来提取索引中 个文件。

由于Git会在您运行git commit时根据索引中的内容构建一个 new 提交,因此将索引内容与某些内容(提交中的冻结树或工作树-确实是非常有用的东西。


1 实际的树条目存储(模式,路径,哈希)三倍。 mode是字符串:100755代表可执行文件,100644代表不可执行文件,40000代表子树,120000代表符号链接,160000代表gitlink。这些原本是Linux的stat st_mode字段,例如,Git允许100664的{​​{1}}为rw-rw-r--,但事实证明这是一个错误,因此普通树仅使用以下字段之一:有限子集。 Git仍支持100664,因为可能有些Git存储库仍具有此类条目,但是除非找到真正的旧存储库,否则您将找不到100664。散列始终是gitlink条目的blob散列 except ,其中散列是子模块中所需的提交散列。