Git查找臃肿提交

59

是否可以获取有关每个提交中更改浪费了多少空间的信息,以便我可以找到添加了大文件或许多文件的提交。这一切都是为了尝试减少git仓库的大小(通过变基和可能的过滤提交)。


1
考虑定期运行 git gc,可能作为 git gc --aggressive 运行。 - Hasturkun
git gc(以及 git gc --prune);--aggresive 可能会导致更糟糕的结果(但通常不会),并且通常不值得这样做。 - Jakub Narębski
这个答案更好:https://dev59.com/_2gv5IYBdhLWcg3wHNDG#10847242 - akostadinov
7个回答

28
你可以这样做:
git ls-tree -r -t -l --full-name HEAD | sort -n -k 4

这将显示最大的文件在底部(第四列是文件(blob)大小)。

如果您需要查看不同的分支,您需要将HEAD更改为这些分支名称。或者,将其放入循环中,遍历您感兴趣的分支、标签或修订版本。


18

抱歉没有及时回复,我的回答是:

git rev-list --all --pretty=format:'%H%n%an%n%s'    # get all commits
git diff-tree -r -c -M -C --no-commit-id #{sha}     # get new blobs for each commit
git cat-file --batch-check << blob ids              # get size of each blob

1
如果我正确理解您的脚本,它仅考虑在特定提交中添加的文件。它不会检测到在提交中文件大幅增长的情况。 - kynan
@kynan:你说得对,因为这是OP请求的内容(也是我需要的)。但是很容易更改脚本以检测修改后的文件:基本上只需要在grep调用中将“A”替换为“M”。这将报告修改后的总文件大小(而不是添加/删除的字节数)。我很乐意在GitHub上接受拉取请求,使脚本更加通用。 - sschuberth
7
链接已损坏,脚本现在位于这里 - Luke
1
--diff-filter 可以代替不可靠的 grep,但在我看来,这个答案更好:https://dev59.com/_2gv5IYBdhLWcg3wHNDG#10847242。 - akostadinov

11
这里提供的所有解决方案都关注于文件大小,但原始问题所问的是提交大小。在我看来,在我的情况下,找到提交大小更为重要(因为我想要摆脱单次提交引入的许多小型二进制文件,这些文件如果按单个文件计算,尽管规模小,但合起来占用了很大的空间)。
一个关注提交大小的解决方案是在这里提供的,它是这个Perl脚本:
#!/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);
  }
  my $revn = substr($rev, 0, 40);
#  if ($tot > 1000000) {
    print "$tot $revn " . `git show --pretty="format:" --name-only $revn | wc -l`  ;
#  }
}

我这样命名:

./git-commit-sizes.pl | sort -n -k 1

2
#!/bin/bash
COMMITSHA=$1

CURRENTSIZE=$(git ls-tree -lrt $COMMITSHA | grep blob | sed -E "s/.{53} *([0-9]*).*/\1/g" | paste -sd+ - | bc)
PREVSIZE=$(git ls-tree -lrt $COMMITSHA^ | grep blob | sed -E "s/.{53} *([0-9]*).*/\1/g" | paste -sd+ - | bc)
echo "$CURRENTSIZE - $PREVSIZE" | bc

我建议使用git format-patch来获取提交大小(邮件头部会有一些额外的大小,但实际上如果您需要快速提交,它并不是太大 - 获取精确大小并不是很重要,+- 1K将是良好的准确度)。 - Stas Dashkovsky

2

git fat find N 其中N表示字节数,将返回历史记录中所有大于N字节的文件。

关于git-fat的更多信息,请访问这里:https://github.com/cyaninc/git-fat


糟糕。我在GitHub桌面版自带的Git Shell for Windows上尝试了一下,但命令无法运行,出现了错误。 - DucRP
@DucRP 我认为你需要在你的电脑上安装git fat。 - mvoelcker

2

1

git cat-file -s <object> 其中 <object> 可以是提交、blob、tree 或标签。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接