Git:显示两个提交之间的文件总大小差异?

是否有可能显示两个提交之间的文件总大小差异? 就像是:

$ git file-size-diff 7f3219 bad418 # I wish this worked :) -1234 bytes 

我试过了:

 $ git diff --patch-with-stat 

这就显示了差异中的每个二进制文件的文件大小差异 – 但不是文本文件,而不是文件总大小的差异。

有任何想法吗?

git cat-file -s会输出git中一个对象的大小。 git diff-tree可以告诉你一棵树与另一棵树之间的区别。

把它放在一个名为git-file-size-diff的脚本中,你可以调用git file-size-diff <tree-ish> <tree-ish> 。 我们可以尝试如下的东西:

 #!/bin/bash USAGE='[--cached] [<rev-list-options>...] Show file size changes between two commits or the index and a commit.' . "$(git --exec-path)/git-sh-setup" args=$(git rev-parse --sq "$@") [ -n "$args" ] || usage cmd="diff-tree -r" [[ $args =~ "--cached" ]] && cmd="diff-index" eval "git $cmd $args" | { total=0 while read ABCDMP do case $M in M) bytes=$(( $(git cat-file -s $D) - $(git cat-file -s $C) )) ;; A) bytes=$(git cat-file -s $D) ;; D) bytes=-$(git cat-file -s $C) ;; *) echo >&2 warning: unhandled mode $M in \"$A $B $C $D $M $P\" continue ;; esac total=$(( $total + $bytes )) printf '%d\t%s\n' $bytes "$P" done echo total $total } 

在使用中,如下所示:

 $ git file-size-diff HEAD~850..HEAD~845 -234 Documentation/RelNotes/1.7.7.txt 112 Documentation/git.txt -4 GIT-VERSION-GEN 43 builtin/grep.c 42 diff-lib.c 594 git-rebase--interactive.sh 381 t/t3404-rebase-interactive.sh 114 t/test-lib.sh 743 tree-walk.c 28 tree-walk.h 67 unpack-trees.c 28 unpack-trees.h total 1914 

通过使用git-rev-parse它应该接受指定提交范围的所有常用方法。

编辑:更新logging累计总数。 请注意,bash在子shell中读取时运行,因此额外的大括号可以避免在子shell退出时丢失总数。

编辑:增加支持比较索引与另一个树 – ish通过使用 – --cached参数来调用git diff-index而不是git diff-tree 。 例如:

 $ git file-size-diff --cached master -570 Makefile -134 git-gui.sh -1 lib/browser.tcl 931 lib/commit.tcl 18 lib/index.tcl total 244 

你可以输出

 git show some-ref:some-path-to-file | wc -c git show some-other-ref:some-path-to-file | wc -c 

并比较这两个数字。

我做了一个bash脚本来比较分支/提交等实际文件/内容的大小。 它可以在https://github.com/matthiaskrgr/gitdiffbinstatfind,也检测文件重命名。;

扩展在matthiaskrgr的答案 , https://github.com/matthiaskrgr/gitdiffbinstat可以像其他脚本一样使用:;

 gitdiffbinstat.sh HEAD..HEAD~4 

伊莫它真的很好,比这里发布的任何东西都快。 示例输出:

 $ gitdiffbinstat.sh HEAD~6..HEAD~7 HEAD~6..HEAD~7 704a8b56161d8c69bfaf0c3e6be27a68f27453a6..40a8563d082143d81e622c675de1ea46db706f22 Recursively getting stat for path "./c/data/gitrepo" from repo root...... 105 files changed in total 3 text files changed, 16 insertions(+), 16 deletions(-) => [±0 lines] 102 binary files changed 40374331 b (38 Mb) -> 39000258 b (37 Mb) => [-1374073 b (-1 Mb)] 0 binary files added, 3 binary files removed, 99 binary files modified => [-3 files] 0 b added in new files, 777588 b (759 kb) removed => [-777588 b (-759 kb)] file modifications: 39596743 b (37 Mb) -> 39000258 b (37 Mb) => [-596485 b (-582 kb)] / ==> [-1374073 b (-1 Mb)] 

输出目录是时髦的./c/data … as / c实际上是filesytem根目录。

对脚本的评论:git-file-size-diff,由patthoytsbuild议。 脚本是非常有用的,但是,我发现了两个问题:

  1. 当某人更改文件的权限时,git会在case语句中返回另一个types:

     T) echo >&2 "Skipping change of type" continue ;; 
  2. 如果sha-1值不再存在(由于某种原因),脚本崩溃。 在获取文件大小之前,您需要validationsha:

    $(git cat-file -e $D) if [ "$?" = 1 ]; then continue; fi

完整的case语句将如下所示:

 case $M in M) $(git cat-file -e $D) if [ "$?" = 1 ]; then continue; fi $(git cat-file -e $C) if [ "$?" = 1 ]; then continue; fi bytes=$(( $(git cat-file -s $D) - $(git cat-file -s $C) )) ;; A) $(git cat-file -e $D) if [ "$?" = 1 ]; then continue; fi bytes=$(git cat-file -s $D) ;; D) $(git cat-file -e $C) if [ "$?" = 1 ]; then continue; fi bytes=-$(git cat-file -s $C) ;; T) echo >&2 "Skipping change of type" continue ;; *) echo >&2 warning: unhandled mode $M in \"$A $B $C $D $M $P\" continue ;; esac 
Interesting Posts