是否有一个 git 命令可以为每次提交输出:
git ls-tree -l -r <commit>
,但仅适用于创建的斑点)获取提交(每次提交全部并输出一行):
git rev-list --all --pretty=oneline
然后按空间分割提交,限制为 2,并获取每个提交 id 和消息
获取由提交创建的 blob(递归到子目录,显示合并提交,检测重命名和副本,不在第一行显示提交 id):
git diff-tree -r -c -M -C --no-commit-id <commit-sha>
对每一行进行一些解析并排除其中的一些 - 我们得到新 blob 的列表以及它们的提交路径
最后是获取斑点大小:
git cat-file --batch-check < <list-of-blob-shas>
还有一次进行一些解析
依靠
git rev-list
并不总是足够的,因为它
列出可通过以下父链接访问的提交 给定提交 [..]
(
git help rev-list
)
因此,它不会列出另一个分支上的提交,也不会列出任何分支都无法访问的提交(可能它们是由于某些
rebase
和/或分离头操作而创建的)。
类似地,
git log
仅跟随当前签出提交的父链接。同样,您看不到其他分支引用的提交或处于悬空状态的提交。
您确实可以使用如下命令获取所有提交:
for i in `(find .git/objects -type f |
sed 's@^.*objects/\(..\)/\(.\+\)$@\1\2@' ;
git verify-pack -v .git/objects/pack/*.idx |
grep commit |
cut -f1 -d' '; ) | sort -u`
do
git log -1 --pretty=format:'%H %P %ai %s%n' $i
done
为了简单起见,循环体为每个提交打印一行,其中包含其哈希值、父哈希值、日期和主题。请注意,要迭代all提交,您需要考虑打包和未打包的对象。
您可以通过从循环体调用
git diff-tree $i
(并在第五列中查找大写字母 A
)来打印引用的 blob(并且仅创建)。
您可以开箱即用,但尺寸除外。这个非常接近:
git log --name-status
基于 tig 的回答的一个解决方案:
#!/usr/bin/perl
foreach my $rev (`git rev-list --all --pretty=oneline`) {
my $tot = 0;
($sha = $rev) =~ s/\s.*$//;
foreach my $blob (`git diff-tree -r -c -M -C --no-commit-id $sha`) {
$blob = (split /\s/, $blob)[3];
next if $blob == "0000000000000000000000000000000000000000"; # Deleted
my $size = `echo $blob | git cat-file --batch-check`;
$size = (split /\s/, $size)[2];
$tot += int($size);
}
print "$tot $rev" if $tot > 1000000; # Show only if > 1MiB
}
也许不是最好的代码,但应该可以帮助你完成大部分任务。
搜索时另一个有用的命令
git fsck --lost-found
将显示悬空提交。我需要用它来找到一个我用不合时宜的重置擦除的提交 --hard
但不要相信我的话:
https://www.kernel.org/pub/software/scm/git/docs/git-fsck.html
您还可以通过以下方式获取所有提交(包括悬空的提交)的列表:
git log --walk-reflogs | grep -E -o '[0-9a-f]{40}'
将此行包含在 gitk 中新视图的设置中(在最后一个输入字段中,生成附加提交的命令),您将得到一棵树,其中还显示了项目的“被遗忘的历史记录”。