为什么我必须使用%(objecttype)和%(rest)来过滤blob

时间:2015-02-19 05:51:34

标签: git

我正在使用git 2.3.0,并尝试查找所有blob ID。

$ git rev-list --objects --all | git cat-file --batch-check='%(objecttype)' | grep blob | wc -l
0
$ git rev-list --objects --all | git cat-file --batch-check='%(rest)' | grep blob | wc -l
0
$ git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(rest)'  | grep blob | wc -l
138189

为什么只有最后一个输出非零?

(如果你碰巧知道获得所有blob id的更好方法,请告诉我。)

1 个答案:

答案 0 :(得分:1)

来自文档:

  

如果提供--batch--batch-check,则会显示cat-file   来自stdin的对象,每行一个,以及有关的打印信息   他们。默认情况下,整行被视为对象,如   如果它被送到 git-rev-parse (1)。

让我们看看一些示例git rev-list --objects --all输出:

$ git rev-list --objects --all | head -3 | vis -l
d1eae6908f5327c4c1a607cab1c449e71a08c7d7\$
f557ce992dfd61ee7e660eeabb638b99e19bd603\$
ea4daf67a352fa86362e19bb02fd0501a74d26fa\$

(这些看起来很不错,它们都是有效的对象ID,但是......)

git rev-list --objects --all | tail -10 | head -3 | vis -l
997343e133b42a08059584766e2737632c9c044e read-tree.c\$
2b5bfdf7798569e0b59b16eb9602d5fa572d6038 \$
74a0a234dd346fff51c773aa57d82fc4b83a8557 cat-file.c\$

啊哈,这些看起来像是有效的对象ID,或者更确切地说,它们不仅仅是一个ID存在。这个输出没有很好地记录(我通过测试发现它),但在git rev-list手册页中暗示 -at:

  

请注意[如果--use-bitmap-index实际上正在使用位图,]在遍历--objects时,树和blob将不会打印其关联路径。

尽管如此,如果我们在这些上运行git cat-file --batch-check(没有任何格式):

$ (git rev-list --objects --all | head -3;
   git rev-list --objects --all | tail | head -3) |
  git cat-file --batch-check
d1eae6908f5327c4c1a607cab1c449e71a08c7d7 commit 253
f557ce992dfd61ee7e660eeabb638b99e19bd603 commit 245
ea4daf67a352fa86362e19bb02fd0501a74d26fa commit 239
997343e133b42a08059584766e2737632c9c044e read-tree.c missing
2b5bfdf7798569e0b59b16eb9602d5fa572d6038  missing
74a0a234dd346fff51c773aa57d82fc4b83a8557 cat-file.c missing

在我的情况下(git 2.2.0而不是2.3.0),使用wc -l生成的数字与git rev-list --all的输出行数相同,因为它会计算这些错误行。所以我无法解释您的特定输出 - 但回到使用%(rest)git cat-file文档:

  

如果在输出字符串中使用此原子[rest],则输入行将被拆分              第一个空白边界。之前的所有人物              空格被认为是对象名称;之后的人物              第一次运行空格(即"休息")              输出代替%(rest)原子。

所以:

$ (git rev-list --objects --all | head -3;
   git rev-list --objects --all | tail | head -3) |
  git cat-file --batch-check='%(objecttype) %(rest)'
commit 
commit 
commit 
blob read-tree.c
tree 
blob cat-file.c

如果您的管道中有grep blob或类似物,那么然后我可以解释您的结果:所有实际的blob都会导致<sha1> <filename> missing,因此会被丢弃。 [编辑:我在你的问题编辑中看到你确实有这样一个grep。请注意,名为&#34; blob&#34;的blob将是双重匹配,但这可能是好的。 :-) 编辑2 :第二个想法,提防一棵树上写着&#34; blob&#34;嵌入其中,将被计算:使用grep '^blob'之类的东西是安全的。]

(顺便提一下,--batch--batch-check允许全范围的gitrevisions语法,但是一个40个字符的SHA-1后跟一个空格无效,无论之后发生了什么空间。)