【问题标题】:How to get the tree hash for a given directory name?如何获取给定目录名称的树哈希?
【发布时间】:2022-04-08 03:51:01
【问题描述】:

我想在树对象上附加一个注释。但是,为了做到这一点,我首先需要知道树对象的哈希值。对于作为我的存储库一部分的给定目录名称,我如何获取其所属树对象的哈希以便为其附加注释?

通过阅读this answer 我知道我可以使用

git cat-file -p master^{tree}

要列出根树的内容,但我仍然需要 grep 目录名称的输出,并递归地跟踪嵌套的树对象以获取树对象的哈希值,以获取层次结构中更深的目录。

基本上,我正在寻找一个虚构的get-tree-hash.sh 脚本的实现。如果像这样调用

get-tree-hash.sh path/to/directory/in/my/git/repo

它应该输出

The hash for the "repo" tree inside "path/to/directory/in/my/git" is:
92a68a2f5560fa7080393b633e2afd1d5271deef

【问题讨论】:

    标签: git git-notes


    【解决方案1】:

    你可以这样做:

    git rev-parse HEAD:path/to/directory/in/my/git
    

    只打印散列。所以你不需要cutawk 来提取它。

    【讨论】:

    • 确实更好。有关此语法的详细信息记录在 here
    【解决方案2】:

    我自己想通了,

    git ls-tree HEAD -- path/to/directory/in/my/git | cut -d' ' -f3 | cut -f1
    

    做我想做的事。

    【讨论】:

    • 正如我在回答中提到的,您也可以使用ls-files -s
    • -s 在这方面有何帮助?我对分阶段的内容不感兴趣。
    • 同意,我先误会你了。
    • ... | awk '{print $3}' 不那么笨拙
    • 这个答案对我来说比 rev-parse 有用,因为它适用于绝对路径。
    【解决方案3】:

    代替

    git ls-tree HEAD -- path/to/directory/in/my/git | cut -d' ' -f3 | cut -f1
    

    您可以使用新的格式选项(仅限 Git 2.36+,2022 年第二季度):

    git ls-tree <tree-ish> --format='%x09'
    

    使用 Git 2.36(2022 年第二季度),“git ls-tree(man) 学习 --oid-only 选项,类似于“--name-only”和more generalized "--format" option

    commit 22184af(2022 年 3 月 23 日)Johannes Schindelin (dscho)
    请参阅commit 9c4d58fcommit 0f88783commit 455923ecommit e815171commit 132cedacommit 26f6d4dcommit 82e69b0commit 4e4566fcommit a53343e(2022 年 3 月 23 日)@987654。
    请参阅commit cab851ccommit 315f22ccommit f6b224dcommit 87af0ddcommit 889f783(2022 年 3 月 23 日)Teng Long (dyrone)
    (由 Junio C Hamano -- gitster -- 合并,commit 1041d58,202 年 4 月 4 日)

    ls-tree:引入“--format”选项

    签字人:Ævar Arnfjörð Bjarmason
    签字人:滕龙

    --format 选项添加到ls-tree
    它有一个现有的默认输出,然后有--long--name-only 选项来发出默认输出以及对象大小,或者只发出对象路径。

    而不是添加--type-only--object-only
    我们可以使用类似于“for-each-ref --format”的strbuf_expand() 来支持--format
    为方便起见,我们将来可能仍会添加此类选项。

    --format 实现比现有代码慢,但此更改不会导致任何性能下降。
    我们将保持现有的show_tree() 不变,并且仅在提供与现有模式对应的硬编码内置--format 不同的show_tree_fmt() 时运行show_tree_fmt()


    像“--long”这样的输出会慢得多,主要是因为我们需要分配各种与quote.c有关的事情,而不是直接将输出发送到标准输出。

    '--format' 的新选项来自Ævar Arnfjörð Bjarmasonn 的想法和建议,本次提交对原discussion on community 进行了修改。

    that thread 中,有一个"GIT_TEST_LS_TREE_FORMAT_BACKEND" 变量来确保我们有测试覆盖率来通过测试,否则这些测试将使用show_tree()show_tree_fmt(),因此格式化机制可以处理所有相同的情况非格式化选项。

    在随后的重卷中,我们似乎偏离了这些测试的目标。
    我们正在努力确保show_tree_fmt() 的正确性。
    我们无法判断我们是否在这里“命中了 [the] fast-path”,我们可以将其添加到 "test_ls_tree_format" 测试的内容中,而不是对其进行显式测试。

    以下是有关性能测试的统计数据:

    默认格式(打内建格式)

    "git ls-tree <tree-ish>" vs "--format='%(mode) %(type) %(object)%x09%(file)'"
    
    $hyperfine --warmup=10 "/opt/git/master/bin/git ls-tree -r HEAD"
    Benchmark 1: /opt/git/master/bin/git ls-tree -r HEAD
    Time (mean ± σ):     105.2 ms ±   3.3 ms    [User: 84.3 ms, System: 20.8 ms]
    Range (min … max):    99.2 ms … 113.2 ms    28 runs
    
    $hyperfine --warmup=10 "/opt/git/ls-tree-oid-only/bin/git ls-tree -r --format='%(mode) %(type) %(object)%x09%(file)'  HEAD"
    Benchmark 1: /opt/git/ls-tree-oid-only/bin/git ls-tree -r --format='%(mode) %(type) %(object)%x09%(file)'  HEAD
    Time (mean ± σ):     106.4 ms ±   2.7 ms    [User: 86.1 ms, System: 20.2 ms]
    Range (min … max):   100.2 ms … 110.5 ms    29 runs
    

    默认格式包括对象大小(按内置格式)

    "git ls-tree -l <tree-ish>" vs "--format='%(mode) %(type) %(object) %(size:padded)%x09%(file)'"
    
    $hyperfine --warmup=10 "/opt/git/master/bin/git ls-tree -r -l HEAD"
    Benchmark 1: /opt/git/master/bin/git ls-tree -r -l HEAD
    Time (mean ± σ):     335.1 ms ±   6.5 ms    [User: 304.6 ms, System: 30.4 ms]
    Range (min … max):   327.5 ms … 348.4 ms    10 runs
    
    $hyperfine --warmup=10 "/opt/git/ls-tree-oid-only/bin/git ls-tree -r --format='%(mode) %(type) %(object) %(size:padded)%x09%(file)'  HEAD"
    Benchmark 1: /opt/git/ls-tree-oid-only/bin/git ls-tree -r --format='%(mode) %(type) %(object) %(size:padded)%x09%(file)'  HEAD
    Time (mean ± σ):     337.2 ms ±   8.2 ms    [User: 309.2 ms, System: 27.9 ms]
    Range (min … max):   328.8 ms … 349.4 ms    10 runs
    

    git ls-tree 现在包含在其man page 中:

    --format=&lt;format&gt;

    从结果中插入%(fieldname) 的字符串 正在显示。

    它还将%% 插值到%,并且 %xx 其中xx 是十六进制数字插值到字符 十六进制代码xx;例如%00 插入到 \0 (NUL)、%09\t (TAB) 和 %0a\n (LF)。

    指定时,--format 不能与其他组合 格式更改选项,包括--long--name-only--object-only

    git ls-tree 现在包含在其man page 中:

    ls-tree 的输出格式由--format 决定 选项,或其他格式更改选项,例如 --name-only 等。 (参见上面的--format)。

    使用某些--format 指令等同于使用那些 选项,但调用完整的格式化机制可能比 使用适当的格式选项。

    如果--format 将精确映射到现有选项 ls-tree 将使用适当的更快路径。因此默认格式 相当于:

    %(objectmode) %(objecttype) %(objectname)%x09%(path)
    

    git ls-tree 现在包含在其man page 中:

    自定义格式:

    可以使用--format 选项以自定义格式打印, 它能够使用%(fieldname) 表示法插入不同的字段。 例如,如果您只关心“objectname”和“path”字段,您 可以使用特定的“--format”执行,例如

    git ls-tree --format='%(objectname) %(path)' <tree-ish>
    

    字段名称

    结构化字段中的各种值可用于插值 进入结果输出。对于每条输出线,以下内容 可以使用名称:

    objectmode

    对象的模式。

    objecttype

    对象的类型(blobtree)。

    objectname

    对象的名称。

    objectsize[:padded]

    对象的大小(如果是树,则为“-”)。 它还支持使用“%(size:padded)”填充大小的格式。

    path

    对象的路径名。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-14
      • 2020-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多