我有一些资产元数据提交引入了数千个文件(数百兆字节的小文件)。此后几次,整个元数据已被替换或删除。
知道其中一些过去的提交不再与存储库的当前状态相关。
如何找到按引入的文件数排序的提交列表?
答案 0 :(得分:3)
对于任何特定的SHA,您可以获得添加此文件的文件数量,这将打印出来并仅使用添加文件的A的diff过滤器计算添加的文件。
numFiles=$(git diff --name-status --diff-filter=A ${sha}^! | wc -l)
如果您将其包装在一个简单的脚本中,您可以打印出一个带有相关文件的SHA列表,您可以通过管道进行排序。指定START和END SHA以限制结果。
#!/bin/sh
for sha in $(git rev-list ${START_SHA}..${END_SHA})
do
numFiles=$(git diff --name-status --diff-filter=A ${sha}^! | wc -l)
echo "${numFiles} ${sha}"
done
答案 1 :(得分:1)
从根本上说,每次提交都是(或者#34;有")存储的树,它独立于每个其他提交,因此要获得通过提交添加的文件"你必须比较(即差异)提交与其他提交。
对于许多/大多数提交,可以轻松选择其他提交:使用提交的(单个)父提交。对于合并提交(那些有两个或更多父母的人),答案不太明显,我也不知道你会为这些做什么。
对于根提交(没有父提交的提交),您仍然可以通过对git' s "well known, if poorly advertised, empty tree"进行区分来获取相对于空树添加的文件数。或者,您可以选择完全忽略root提交(这简化了您的任务)。
没有一个git命令会在这里为你做所有事情,但很容易将一个脚本或管道放在一起来完成这个任务。要知道的主要事情是您将使用git rev-list
生成所有候选提交ID:
git rev-list --min-parents=1 --max-parents=1 HEAD
例如,将为您提供一个列表,其中列出了每个可以从HEAD
到达的具有1个父项的提交(即,既不是合并提交也不是根提交)。由您来决定这是否是您要检查的提交。
如果是的话,我们现在处于相当不错的状态,因为我们可以简单git diff
针对其(单个)父母进行每次此类提交:
git rev-list --min-parents=1 --max-parents=1 HEAD | \
while read sha1; do \
...
done
现在的诀窍是让git diff
给我们添加的文件数量,也许可以从另一个命令获得一点帮助。这非常简单,因为git diff
具有--name-status
和--name-only
选项,还有--diff-filter
选项。使用--name-status
会得到如下输出:
$ git diff --name-status 0df0541bf13723658d31b8d1376b505b710e63c6^ \
0df0541bf13723658d31b8d1376b505b710e63c6
A Documentation/RelNotes/2.4.5.txt
M Documentation/git.txt
M GIT-VERSION-GEN
M RelNotes
添加--diff-filter=A
会删除除A
dded文件以外的所有文件,之后我们真的不需要--name-status
(也不会伤害它),因为只有名称,{ {1}},会告诉我们在比较这两个提交时添加了哪些文件:
--name-only
通过$ git diff --name-only --diff-filter=A \
0df0541bf13723658d31b8d1376b505b710e63c6^ \
0df0541bf13723658d31b8d1376b505b710e63c6
Documentation/RelNotes/2.4.5.txt
运行此输出得到一个行数,这也是一个文件计数,因为每个文件名都在它自己的行上。 1
所以,现在我们有一个看起来像这样的脚本(我现在将反斜杠留出来):
wc -l
然后,可以将此脚本的输出传递给git rev-list --min-parents=1 --max-parents=1 HEAD |
while read sha1; do
echo $(git diff --name-only --diff-filter=A ${sha1}^ ${sha1} | wc -l) $sha1
done
。
您可能希望稍微调整一下,具体取决于您需要对合并执行的操作。您可能还希望在sort -rn
命令上击败重命名检测(或者可能不是,它确实取决于您如何使用它)。
1 无论如何,忽略将换行符嵌入文件名的可能性。如果你想要一个非常通用的工具,你应该考虑这种可能性,但你可以根据自己的情况忽略它。