是否可以显示两个提交之间文件总大小的差异?像这样:
$ git file-size-diff 7f3219 bad418 # I wish this worked :)
-1234 bytes
我尝试过:
$ git diff --patch-with-stat
这显示了在差异中每个二进制文件的文件大小差异,但不适用于文本文件,也不是总文件大小差异。
有什么想法吗?
是否可以显示两个提交之间文件总大小的差异?像这样:
$ 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
的脚本,并将其放置在您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.'
SUBDIRECTORY_OK=1
. "$(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
}
实际使用时,它看起来像下面这样:
$ 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
,它应该接受指定提交范围的所有常规方式。--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存储库的子目录中运行。
HEAD~850
是什么?我能否直接使用提交ID代替? - mr5git rev-parse
,因此请参阅 git-rev-parse 文档中的"Specifying Revisions"部分以获取完整详细信息。(https://git-scm.com/docs/git-rev-parse) - patthoytsgit show some-ref:some-path-to-file | wc -c
git show some-other-ref:some-path-to-file | wc -c
比较这两个数字。
cat-file -s
而不是show
,则可以跳过| wc -c
。 - neu242gdbytes () { echo "$(git cat-file -s $1:$3) -> $(git cat-file -s $2:$3)" }
这使得很容易看到文件大小自上次提交以来的变化,例如:gdbytes @~ @ index.html
- webninjasome-ref:
部分,您是否可以获取工作目录中的文件大小? - 40detectives针对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)]
对于脚本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
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
filesizediffs() {
git diff-tree "$@" \
| awk '$1":"$2 ~ /:[10]0....:[10]0/ {
print $3?$3:empty,substr($5,3)
print $4?$4:empty,substr($5,3)
}' FS='[ ]' empty=`git hash-object -w --stdin <&-` \
| git cat-file --batch-check=$'%(objectsize)\t%(rest)' \
| awk '!seen[$2]++ { first[$2]=$1 }
$1!=first[$2] { print $1-first[$2],$2; total+=$1-first[$2] }
END { print "total size difference "total }' FS=$'\t' OFS=$'\t'
}
filesizediffs @
git archive <COMMIT> | wc -c
报告的大小将是提交中所有数据的字节数加上一些tar元数据。由于tar
本身(git archive
的默认设置)不进行压缩,所以报告的数字在某种程度上是可比较的。
如果您的目的是找到添加了1GB日志文件的提交,这种方法完全足够。