如何查看git存储库中单个文件的文件大小历史记录?


How to see the file size history of a single file in a git repository?

是否总能在git仓库中查看文件大小随时间的变化?我想看看我的main.js文件(由多个文件和缩小文件组成的组合)如何随着时间增长和缩小。


您可以使用任一git ls-tree -r -l <revision> <path>来获取给定版本的Blob大小,例如

1
2
$ git ls-tree -r -l v1.6.0 gitweb/README
100644 blob 825162a0b6dce8c354de67a30abfbad94d29fdde   16067    gitweb/README

此示例中的斑点大小为" 16067"。此解决方案的缺点是git ls-tree一次只能处理一个修订。

您可以改为使用git cat-file --batch-check < <list-of-objects>,为其提供blob标识符。如果文件的位置在历史记录中没有发生变化(文件未移动),则可以使用git rev-list <starting-point> -- <path>获取涉及给定路径的修订列表,并使用<revision>:<path>扩展的SHA-1语法将其转换为blob的名称(请参见git -rev-parse联机帮助页),并将其提供给git cat-file。示例:

1
2
3
4
5
6
7
8
$ git rev-list -5 v1.6.0 -- gitweb/README |
  sed -e 's/$/:gitweb\\/README/g' |
  git cat-file --batch-check
825162a0b6dce8c354de67a30abfbad94d29fdde blob 16067
6908036402ffe56c8b0cdcebdfb3dfacf84fb6f1 blob 16011
356ab7b327eb0df99c0773d68375e155dbcea0be blob 14248
8f7ea367bae72ea3ce25b10b968554f9b842fffe blob 13853
8dfe335f73c223fa0da8cd21db6227283adb95ba blob 13801


创建一个名为.gitattributes的文件,并添加以下行:

1
main.js -diff

这将关闭main.js的基于行的差异。现在运行以下命令:

1
git log --stat main.js

日志中将包含诸如

1
main.js | Bin 4316 -> 4360 bytes

完成后,您可能应该删除.gitattributes。我不知道-diff属性可能导致git的行为发生其他变化。

使用git版本1.7.12.4和1.7.9.5测试。

来源:ewall的答案和https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html#_marking_files_as_binary


您可以创建一个脚本,该脚本使用git show --pretty=raw <commit>的输出来获取树,然后使用git ls-tree -r -l来获取您要查找的blob,包括文件大小。

如果您已安装了ruby和gritruby,则以下是我放在一起的一个小脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require 'grit'

if ARGV.size < 1
  puts 'usage: file-size FILE'
  puts 'run from within the git repo root'
  exit
end

filename = ARGV[0].to_s

repo = Grit::Repo.new('.')
commits = repo.log('master', filename)
commits.each do |commit|
  blob = commit.tree/filename
  puts"#{commit} #{blob.size} bytes"
end

用法示例(脚本的文件名是file-size.rb),将显示somedir / somefile的历史记录:

1
myproject$ ruby file-size.rb somedir/somefile


这是一个Bash函数,它将随着时间的推移以以下格式报告大小。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 LoC  Date                       Commit ID   Subject
 942  2019-08-31 18:09:34 +0200  35fc67c122  Declare some XML namespaces in replacement of OGCPrefixMapper, which has been removed from Apache SIS. https://issues.apache.org/jira/browse/SIS-126
 943  2019-08-09 16:52:29 +0200  e8438ab869  fix(GML): fix relative path resolving inside a jar
 934  2019-08-05 15:37:46 +0200  1e0c0b03c4  fix(GML): fix all test cases
 932  2019-07-30 15:54:53 +0200  fddea5db24  feat(GML): work on fallback for non-xsd Feature store
 932  2019-07-23 16:40:23 +0200  8d9a6a7dd0  feat(GML): improve support for custom XML mappings
 932  2019-06-26 15:18:43 +0200  43ea6e0bd7  feat(GML): add concurrency support for read/write operations
 932  2019-06-21 09:27:41 +0200  07a9993b4b  feat(GML): support group reference min/max occurs attributes
 932  2019-06-21 09:27:41 +0200  352a9104ae  feat(GML): fix resolving local files xsd paths
 919  2018-06-08 15:41:26 +0200  01ac7538e7  Merge branch 'master' into sis-migration
 919  2018-05-16 16:40:04 +0200  16fe7590c5  fix(JAXP): various fix for  WFS 2.0.0
 912  2018-04-11 10:09:22 +0200  bf3a38bdc4  chore(*): update JTS version 1.15.0
 912  2017-11-09 20:15:23 +0100  bc14dc4be1  fix(Client): fix minor problems on WFS querying
 901  2017-10-20 11:41:43 +0200  f686d7ff15  feat(Storage): add support for GML 2.1.2
 882  2017-05-16 23:07:31 +0200  f20c34c1e2  refactor(Feature): renamed the Geotk flavor of org.apache.sis.feature package as org.geotoolkit.feature.

这是函数:

1
2
3
4
5
6
7
8
git-log-size() {
    git rev-list HEAD --"$1" | while read cid; do
        git cat-file blob"$cid:$1" | wc -l | tr -d '\
'
        echo -n $'\\t'
        git log -1"--pretty=%ci%x09%h%x09%s" $cid
    done | column -t -s$'\\t'
}

它不是特别有效,但是可以完成工作。它使用一些非常通用的实用程序(wc,tr,column)。

大小以代码行(LoC)的形式报告,因为这是软件开发中的常用指标,如果您更喜欢其他方法,只需更改wc的" -l"选项即可。

这里是怎么称呼它:

1
git-log-size <path>


如果这对某人有用,则此脚本将以不同的提交显示给定文件的大小:

1
2
3
4
git log <file_name> | grep"^commit" | cut -f2 -d"" | while read hash; do
   echo -n"$hash --"
   git show $hash:<file_path_off_of_git_root_without_leading_slash> | wc -c
done

在Windows上,我使用以下命令:

1
cmd /c"@echo off & for /l %N in (1 1 30) do git ls-tree -r -l HEAD~%N"C:\\path\\to\\file.txt"

它将显示最新30个版本的大小。

如果有人可以将其转换为Linux命令,欢迎您...))


虽然git log <filename>git whatchanged等命令可以显示与该文件有关的历史记录,但我看不到内置或自定义漂亮格式的任何显示大小的选项(遗憾的是, --log-size选项仅用于日志消息!)。

但是,通过查看每次提交中添加和删除的总行数,您可以大致了解大小。您可以使用git log --stat <filename>命令对其进行可视化,该命令使用加号和减号。或者使用git log --numstat <filename>收集每次提交中添加或删除的行数,并在其他一些可视化中使用这些行数。


只需:
git log --stat /path/to/file

结果:
enter