Git 提交时是否生成所有树对象?

Git 提交时是否生成所有树对象?,git,Git,我想知道: 提交时是否生成所有树对象(可能是管道中的commit tree) 那么,为什么树对象(尤其是目录)不是在添加到索引时生成的,而blob是 我发现当我将文件添加到索引中时,会产生blob git init mkdir测试dir echo“File1”>test dir/test.txt git计数对象 #0个对象,0千字节 git add test dir/test.txt git计数对象 #1个对象,4千字节 git ls文件-s #100644 03f128cf48cb203d93

我想知道:

  • 提交时是否生成所有树对象(可能是管道中的
    commit tree
  • 那么,为什么树对象(尤其是目录)不是在添加到索引时生成的,而blob是
  • 我发现当我将文件添加到索引中时,会产生blob

    git init
    mkdir测试dir
    echo“File1”>test dir/test.txt
    git计数对象
    #0个对象,0千字节
    git add test dir/test.txt
    git计数对象
    #1个对象,4千字节
    git ls文件-s
    #100644 03f128cf48cb203d938805e9f3e13b808d1773e9 0测试目录/test.txt
    
    但在提交之前,我无法找到
    testdir
    的树对象

    git提交-m“我的第一次提交”
    #[master(root提交)48448a5]我的第一次提交
    #1个文件已更改,1个插入(+)
    #创建模式100644测试目录/test.txt
    git计数对象
    #4个对象,16千字节
    git版本列表--所有--对象
    #48448a5c6d04cbcd6ab25b64c4bbab9dec5fcf94
    #5f618720e3fc14d396086feb6ee1d869fbbf2e21
    #3BDFE0BEC6B514084883E5E55FC0EDD9BB52B32测试目录
    #03f128cf48cb203d938805e9f3e13b808d1773e9测试目录/test.txt
    git cat文件-t3bdfe0
    #树
    git cat文件-p3bdfe0
    #100644 blob 03f128cf48cb203d938805e9f3e13b808d1773e9 test.txt
    

    现在我得到了
    testdir
    目录的树对象。

    树对象是通过
    git-write-tree
    构建的。也就是说,
    git commit
    由几个子命令组成(请参见下面的注释):

    git写树
    git提交树
    git更新参考
    
    第一个命令不带参数,它将索引(使用
    gitls文件--stage
    查看其内容)转换为一系列树对象。顶级树对象的哈希ID将打印到其标准输出

    第二个命令需要参数:
    -p
    用于每个父提交散列ID,
    -m
    -F
    用于提供提交日志消息,以及由
    git write tree
    打印的树散列ID。它生成提交对象的哈希ID作为其标准输出

    最后一个命令还需要参数:当前分支的全名(例如,
    refs/heads/master
    ),或者如果
    HEAD
    当前与任何分支分离,则名称
    HEAD
    ,以及第二个命令生成的提交散列ID。它更新给定的ref以保存给定的散列ID。如果ref是分支名称或
    ,则散列ID应该是提交的ID

    笔记 最初,
    gitcommit
    是一个小的shell脚本,它只运行这三个命令(使用适当的shell胶水)。当时,
    git commit
    没有现在那么多的选项、标志和模式


    最终,
    git commit
    变成了一个单一的C程序。它现在在内部完成所有这些部分。它还处理锁定、运行预提交挂钩以及其他类似的事情;在shell脚本中使用三个单独的命令无法正确完成这些操作。但是,这三个单独的命令仍然保留,因此,如果您愿意,您可以使用它们来构建自己的脚本。

    感谢您的详细解释:)。所以我可以得出这样的结论:索引不包含任何树对象,只包含blob,并且所有需要的(如果没有相同的)树对象都是在
    write tree
    stage时生成的。我说得对吗?没错。请注意,blob和tree对象都可以重用:如果数据与某个现有对象100%匹配,您将获得现有对象的哈希ID,并且没有新对象进入对象数据库;您只需重新使用现有对象。
    git write-tree
    git commit-tree <parents> <message> <tree-hash-ID>
    git update-ref <full-ref> <commit-hash-ID>