Git – 如何列出数据库中的所有对象

有没有更好的方式来获取存储库中的所有对象的SHA1的原始列表比做ls .git/objects/??/\*cat .git/objects/pack/*.idx | git show-index cat .git/objects/pack/*.idx | git show-index

我知道git rev-list --all但是只列出了被.git / refs引用的提交对象,而且我正在寻找所有包括由git-hash-object,git-mktree等创build的未引用对象。

马克的答案适用于我,经过一些修改:

  • --git-dir代替--show-cdup来支持裸回购
  • 没有包装时避免错误
  • 使用perl是因为OS X Mountain Lion的BSD风格的sed不支持-r
 #!/bin/sh set -e cd "$(git rev-parse --git-dir)" # Find all the objects that are in packs: find objects/pack -name 'pack-*.idx' | while read p ; do git show-index < $p | cut -f 2 -d ' ' done # And now find all loose objects: find objects/ \ | egrep '[0-9a-f]{38}' \ | perl -pe 's:^.*([0-9a-f][0-9a-f])/([0-9a-f]{38}):\1\2:' \ ; 

尝试

  git rev-list --objects --all 

编辑 Josh提出了一个很好的观点:

  git rev-list --objects -g --no-walk --all 

列出从ref-logs可达的对象。

要查看无法访问的所有对象,请执行以下操作:

  git rev-list --objects --no-walk \ $(git fsck --unreachable | grep '^unreachable commit' | cut -d' ' -f3) 

把它放在一起,要真正得到rev-list --objects的输出格式的所有对象,你需要类似的东西

 { git rev-list --objects --all git rev-list --objects -g --no-walk --all git rev-list --objects --no-walk \ $(git fsck --unreachable | grep '^unreachable commit' | cut -d' ' -f3) } | sort | uniq 

要以稍微更有用的方式(通过tree / blobs的path,首先提交)对输出进行sorting,请使用额外的| sort -k2 | sort -k2将分组所有不同的斑点(修订)为相同的path。

我不知道一个明显更好的方法,而不仅仅是查看所有的松散对象文件和所有包文件的索引。 git仓库的格式非常稳定,使用这种方法,你不必依赖具有正确的选项git fsck ,它被归类为瓷器。 我认为这种方法也是更快的。 以下脚本显示了存储库中的所有对象:

 #!/bin/sh set -e cd "$(git rev-parse --show-cdup)" # Find all the objects that are in packs: for p in .git/objects/pack/pack-*.idx do git show-index < $p | cut -f 2 -d ' ' done # And now find all loose objects: find .git/objects/ | egrep '[0-9a-f]{38}' | \ sed -r 's,^.*([0-9a-f][0-9a-f])/([0-9a-f]{38}),\1\2,' 

(我的原始版本的脚本是基于这个有用的脚本来find你的包文件中最大的对象 ,但我切换到使用git show-index ,如你的问题所build议的。)

我已经把这个脚本变成了GitHub的要点 。

另一个有用的选项是使用git verify-pack -v <packfile>

verify-pack -v列出数据库中的所有对象及其对象types。

从马克和威尔基尔的答案中,这是一个更正确,更简单,更快速的剧本演绎。

  • 它使用rev-parse --git-path来查找objects目录,即使在更复杂的Git存储库设置中(例如,在多工作树情况下也是如此)。

  • 它避免了findgrepperlsed所有不必要的使用。

  • 如果作品优雅,即使你没有松散的对象或没有包(或者,如果你倾向于在一个新的存储库上运行)。

  • 但是,它确实需要一个来自这个千年的Bash(2.02或更新,特别是extglob位)。

分享和享受。

 #!/bin/bash set -e shopt -s nullglob extglob cd "`git rev-parse --git-path objects`" # packed objects for p in pack/pack-*([0-9a-f]).idx ; do git show-index < $p | cut -f 2 -d ' ' done # loose objects for o in [0-9a-f][0-9a-f]/*([0-9a-f]) ; do echo ${o/\/} done 
Interesting Posts