Git:显示两次提交之间的总文件大小差异?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10845051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git: show total file size difference between two commits?
提问by Mathias Bynens
Is it possible to show the total file size difference between two commits? Something like:
是否可以显示两次提交之间的总文件大小差异?就像是:
$ git file-size-diff 7f3219 bad418 # I wish this worked :)
-1234 bytes
I've tried:
我试过了:
$ git diff --patch-with-stat
And that shows the file size difference for each binaryfile in the diff — but not for text files, and not the total file size difference.
这显示了差异中每个二进制文件的文件大小差异 - 但不是文本文件,也不是总文件大小差异。
Any ideas?
有任何想法吗?
回答by patthoyts
git cat-file -s
will output the size in bytes of an object in git. git diff-tree
can tell you the differences between one tree and another.
git cat-file -s
将在 git 中输出对象的大小(以字节为单位)。git diff-tree
可以告诉你一棵树和另一棵树之间的区别。
Putting this together into a script called git-file-size-diff
located somewhere on your PATH will give you the ability to call git file-size-diff <tree-ish> <tree-ish>
. We can try something like the following:
将它们放在一个名为git-file-size-diff
PATH 某处的脚本中将使您能够调用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 A B C D M P
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
}
In use this looks like the following:
在使用中,这看起来像下面这样:
$ 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
By using git-rev-parse
it should accept all the usual ways of specifying commit ranges.
通过使用git-rev-parse
它应该接受所有指定提交范围的常用方法。
EDIT: updated to record the cumulative total. Note that bash runs the while read in a subshell, hence the additional curly braces to avoid losing the total when the subshell exits.
编辑:更新以记录累计总数。请注意,bash 在子shell 中运行while read,因此额外的花括号以避免在子shell 退出时丢失总数。
EDIT: added support for comparing the index against another tree-ish by using a --cached
argument to call git diff-index
instead of git diff-tree
. eg:
编辑:通过使用--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
回答by Adam Dymitruk
You can pipe the out put of
你可以通过管道输出
git show some-ref:some-path-to-file | wc -c
git show some-other-ref:some-path-to-file | wc -c
and compare the 2 numbers.
并比较这两个数字。
回答by matthiaskrgr
I made a bash script to compare branches/commits etc by actual file/content size. It can be found at https://github.com/matthiaskrgr/gitdiffbinstatand also detects file renames.
我制作了一个 bash 脚本来按实际文件/内容大小比较分支/提交等。它可以在https://github.com/matthiaskrgr/gitdiffbinstat上找到,还可以检测文件重命名。
回答by guest
Expanding on matthiaskrgr's answer, https://github.com/matthiaskrgr/gitdiffbinstatcan be used like the other scripts:
扩展matthiaskrgr 的答案,https://github.com/matthiaskrgr/gitdiffbinstat可以像其他脚本一样使用:
gitdiffbinstat.sh HEAD..HEAD~4
Imo it really works well, much faster than anything else posted here. Sample output:
我真的很管用,比这里发布的其他任何东西都要快得多。示例输出:
$ 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)]
The output directory is funky with ./c/data... as /c is actually the filesytem root.
输出目录很时髦,带有 ./c/data... 因为 /c 实际上是文件系统根目录。
回答by Richard Nilsson
A comment to the script: git-file-size-diff, suggested by patthoyts. The script is very useful, however, I have found two issues:
对脚本的注释:git-file-size-diff,由 patthoyts 建议。该脚本非常有用,但是,我发现了两个问题:
When someone change permissions on the file, git returns a another type in the case statement:
T) echo >&2 "Skipping change of type" continue ;;
If a sha-1 value doesn't exist anymore (for some reason), the script crashes. You need to validate the sha before getting the file size:
$(git cat-file -e $D) if [ "$?" = 1 ]; then continue; fi
当有人更改文件的权限时,git 在 case 语句中返回另一种类型:
T) echo >&2 "Skipping change of type" continue ;;
如果 sha-1 值不再存在(出于某种原因),脚本将崩溃。您需要在获取文件大小之前验证 sha:
$(git cat-file -e $D) if [ "$?" = 1 ]; then continue; fi
The complete case statement will then look like this:
完整的 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