获取每次提交的git存储库的准确总行数

时间:2017-12-23 16:27:36

标签: git

我正在尝试创建一个脚本,用于收集每次提交的git存储库的总行数。

你可以运行

git ls-files | xargs wc -l

在git存储库中,它返回总行数。在我的例子中,它返回前三个提交的以下摘要:

0 total
8356 total
170931 total

但是,签出并为每次提交运行此命令都太慢了,所以我决定使用

git log --shortstat --reverse --pretty=oneline

返回每次提交中完成的insertionsdeletions。问题是这些数字与上一个命令不匹配。相反,我得到以下差异(=>之后的所有内容都是我的计算,也不包括“x files changed”前缀:

[Nothing as this is the first commit] => 0 total
8357 insertions(+)                    => 8357 total
142972 insertions(+)                  => 151329 total

所以,我想知道的是,如果没有第一个命令,我可以快速获得准确的行数。有问题的存储库已有近10年的历史,所以我不确定这是否与差异有关。

更新: Git忽略了添加到文件末尾的空行,但仅凭它不能解释这一点,因为差异远远大于文件数。

1 个答案:

答案 0 :(得分:5)

差异也可以用二进制文件来解释。 diffstat不计算"行"在二进制文件中,而wc -l将。这些二进制文件的wc -l输出结果可能不太准确。

然后必须小心xargs wc -l调用,因为它无法正确解释打印文件名中的特殊字符(例如空格)。要避免该问题,请使用-z的{​​{1}}标志,这将导致文件名由0字节而不是换行符分隔,然后使用git ls-files参数-0所以它希望文件名为0字节分隔:

xargs

然后,不能保证$ git ls-files -z | xargs -0 wc -l 可以将所有文件名都放在xargs的一次调用中,这意味着它可能需要多次调用wc。这将导致多个摘要在与其他输出混合时可能很容易被遗漏。为"总计"行应该使这更明显:

wc -l

如果我理解正确你总是想要在每次提交时整个存储库的行总数,而不仅仅是每个提交中更改行的计数,那么从git中获取该数据的方法就更简单了:

$ git ls-files -z | xargs -0 wc -l | grep total

这使用$ git diff-tree --shortstat 4b825dc642cb6eb9a060e54bf8d69288fbee4904.. 来比较半魔法"空树"当前头部(即第一次提交之前的状态)。因此,它总结了所有提交的所有统计信息,并且无需手动汇总数字。

作为参考,"空树" hash是使用git:

将空字符串作为树对象进行散列时得到的
diff-tree