如何在git存储库中找到N个最大的文件?

时间:2012-02-26 19:50:17

标签: git

我想在我的存储库中找到10个最大的文件。我想出的脚本如下:

REP_HOME_DIR=<top level git directory>
max_huge_files=10

cd ${REP_HOME_DIR}
git verify-pack -v ${REP_HOME_DIR}/.git/objects/pack/pack-*.idx | \
  grep blob | \
  sort -r -k 3 -n | \
  head -${max_huge_files} | \
  awk '{ system("printf \"%-80s \" `git rev-list --objects --all | grep " $1 " | cut -d\" \" -f2`"); printf "Size:%5d MB Size in pack file:%5d MB\n", $3/1048576,  $4/1048576; }'
cd -

是否有更好/更优雅的方式来做同样的事情?

“文件”是指已经检入存储库的文件。

10 个答案:

答案 0 :(得分:44)

我找到了另一种方法:

git ls-tree -r -t -l --full-name HEAD | sort -n -k 4 | tail -n 10

引自:SO: git find fat commit

答案 1 :(得分:14)

怎么样

git ls-files | xargs ls -l | sort -nrk5 | head -n 10

git ls-files: List all the files in the repo
xargs ls -l: perform ls -l on all the files returned in git ls-files
sort -nrk5: Numerically reverse sort the lines based on 5th column
head -n 10: Print the top 10 lines

答案 2 :(得分:9)

此bash“one-liner”显示存储库中的10个最大blob,从最小到最大排序。与其他答案相比,此包括存储库跟踪的所有文件,即使是任何分支提示中都没有的文件。

非常快,易于复制&amp;粘贴,只需要标准的GNU实用程序。

git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| awk '/^blob/ {print substr($0,6)}' \
| sort --numeric-sort --key=2 \
| tail \
| cut --complement --characters=13-40 \
| numfmt --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest

前四行实现了核心功能,第五行限制了结果数量,而后两行提供了良好的人类可读输出,如下所示:

...
0d99bb931299  530KiB path/to/some-image.jpg
2ba44098e28f   12MiB path/to/hires-image.png
bd1741ddce0d   63MiB path/to/some-video-1080p.mp4

有关更多信息,包括更适合脚本处理的进一步过滤用例和输出格式,请参阅我的original answer类似问题。

答案 3 :(得分:3)

对raphinesse的答案的改进,按大小排序,最大的第一个:

git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| awk '/^blob/ {print substr($0,6)}' \
| sort --numeric-sort --key=2 --reverse \
| head \
| cut --complement --characters=13-40 \
| numfmt --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest

答案 4 :(得分:1)

您也可以使用du - 示例:du -ah objects | sort -n -r | head -n 10。 du获取对象的大小,sort然后使用head选择前10名。

答案 5 :(得分:1)

为完成操作,这是我找到的方法:

    Sub GenAPISKey()

  Dim webServiceURL As String
  Dim actionType As String
  Dim targetWord As String
  Dim actionType2 As String
  Dim targetWord2 As String
  Dim UserID As String
  Dim Password As String

  webServiceURL = "https://website.com/api/v1/Login"
  actionType = "Accept"
  targetWord = "application/json"
  actionType2 = "Content-Type"
  targetWord2 = "application/json"
  UserID = "ID"
  Password = "PW"


  With CreateObject("Microsoft.XMLHTTP")
    .Open "POST", webServiceURL, False
    .SetRequestHeader actionType, targetWord
    .SetRequestHeader actionType2, targetWord2
    .SetCredentials "UserID", "Password", 0

    .Send
    If .Status = 200 Then
      Debug.Print .responseText

    Else
      MsgBox .Status & ": " & .StatusText
    End If
  End With

End Sub

可选的ls -lSh `git ls-files` | head 以易于阅读的格式打印尺寸。

答案 6 :(得分:1)

在Windows上,我从@ pix64的答案开始(谢谢!),并对其进行了修改,以处理路径中带有空格的文件,并输出对象而不是字符串:

git rev-list --objects --all |
 git cat-file --batch-check='%(objecttype)|%(objectname)|%(objectsize)|%(rest)' |
 Where-Object {$_ -like "blob*"} |
 % { $tokens = $_ -split "\|"; [pscustomobject]@{ Hash = $tokens[1]; Size = [int]($tokens[2]); Name = $tokens[3] } } |
 Sort-Object -Property Size -Descending |
 Select-Object -First 50

更好的是,如果您要以良好的文件大小单位输出文件大小,则可以从此处将DisplayInBytes函数添加到您的环境https://stackoverflow.com/a/40887001/892770,然后将上面的内容通过管道传递给:

Format-Table Hash, Name, @{Name="Size";Expression={ DisplayInBytes($_.Size) }}

这将为您提供如下输出:

Hash                                     Name                                        Size
----                                     ----                                        ----
f51371aa843279a1efe45ff14f3dc3ec5f6b2322 types/react-native-snackbar-component/react 95.8 MB
84f3d727f6b8f99ab4698da51f9e507ae4cd8879 .ntvs_analysis.dat                          94.5 MB
17d734397dcd35fdbd715d29ef35860ecade88cd fhir/fhir-tests.ts                          11.5 KB
4c6a027cdbce093fd6ae15e65576cc8d81cec46c fhir/fhir-tests.ts                          11.4 KB

最后,如果您想获得所有最大的文件类型,可以使用以下方法实现:

git rev-list --objects --all |
 git cat-file --batch-check='%(objecttype)|%(objectname)|%(objectsize)|%(rest)' |
 Where-Object {$_ -like "blob*"} |
 % { $tokens = $_ -split "\|"; [pscustomobject]@{ Size = [int]($tokens[2]); Extension = [System.IO.Path]::GetExtension($tokens[3]) } } |
 Group-Object -Property Extension |
 % { [pscustomobject]@{ Name = $_.Name; Size = ($_.Group | Measure-Object Size -Sum).Sum } } |
 Sort-Object -Property Size -Descending |
 select -First 20 -Property Name, @{Name="Size";Expression={ DisplayInBytes($_.Size) }}

答案 7 :(得分:0)

您可以使用find查找大于给定阈值的文件,然后将其传递给git ls-files以排除未跟踪的文件(例如构建输出):

find * -type f -size +100M -print0 | xargs -0 git ls-files

根据需要调整100M(100兆字节),直到获得结果。

小警告:这不会搜索顶级&#34;隐藏&#34;文件和文件夹(即名称以.开头的文件和文件夹)。这是因为我使用了find *而不是find来避免搜索.git数据库。

我无法让sort -n解决方案正常工作(在Git Bash下的Windows上)。我猜测它是由于xargs批量参数时的缩进差异,而xargs -0似乎是自动解决Windows&#39;命令行长度限制为32767。

答案 8 :(得分:0)

无法发表评论。 ypid的答案已修改为powershell

git ls-tree -r -l --abbrev --full-name HEAD | Sort-Object {[int]($_ -split "\s+")[3]} | Select-Object -last 10

答案 9 :(得分:0)

为整个回购历史添加我的 5 美分(在排除意外提交的大 blob 之前很有用):

git rev-list --all | while read rev ; do git ls-tree -rl --full-name $rev ; done | sort -k4 -nr | uniq

示例输出(来自 github 的 dte 存储库)显示历史记录中有一个屏幕截图可能会被删除以使整个存储库更小:

100644 blob 3147cb8d0780442f70765a005f1a114442f24e9b   67942    Documentation/screenshot.png
100644 blob 36ea7701a6d58185800e22c39cac78d979f4375a   62575    Documentation/screenshot.png
100644 blob c0cd355f06a093cd762339b76f0e726edf22fca1   49046    src/command.c
100644 blob 76d20c2e4a80cd3f417d15c130ee6968e99d6d7f   48601    src/command.c
100644 blob c476fbf2fda71ebd4b337e62fb76922d18aeb1f3   48588    src/command.c
100644 blob 24465d1fab54e48817780338f8206baf47e98091   48451    src/command.c
100644 blob 74494b6020b2eff223dfaeed39bbfca414f2b359   48429    src/command.c
100644 blob fb8f13abe39ca8ff0e98aa65f95c336c9253b487   47838    src/command.c
100644 blob c2ce190eb428c3aeb12d40cf902af2a433324dee   47835    src/command.c
...

...但是这个精确的 repo 没问题,没有发现超大的 blob。

编辑:如何找到与对象一起使用的提交(添加供我自己参考,哈哈):

git log --all --find-object=3147cb8d07