Git: показать общую разницу в размере файла между двумя коммитами?
Можно ли показать общую разницу в размере файла между двумя коммитами? Что-то вроде:
$ git file-size-diff 7f3219 bad418 # I wish this worked :)
-1234 bytes
Ive попробовал:
$ git diff --patch-with-stat
И это показывает разницу в размере файла для каждого двоичного файла в diff, но не для текстовых файлов, а не для разницы в размере файла.
Любые идеи?
Ответы
Ответ 1
git cat-file -s
выведет размер в байтах объекта в git. git diff-tree
может рассказать вам о различиях между одним деревом и другим.
Объединение этого элемента в script, называемый 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 "[email protected]")
[ -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
, он должен принять все обычные способы указания диапазонов фиксации.
EDIT: обновлено, чтобы записать совокупную сумму. Обратите внимание, что bash запускает чтение, прочитанное в подоболочке, и, следовательно, дополнительные фигурные скобки, чтобы не потерять общее число при выходе из подоболочки.
EDIT: добавлена поддержка сравнения индекса с другим древовидным, используя аргумент --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
Ответ 2
Вы можете выполнить вывод из
git show some-ref:some-path-to-file | wc -c
git show some-other-ref:some-path-to-file | wc -c
и сравните 2 числа.
Ответ 3
Я сделал bash script для сравнения ветвей/коммитов и т.д. по фактическому размеру файла/содержимого.
Его можно найти в https://github.com/matthiaskrgr/gitdiffbinstat, а также обнаруживать переименования файлов.
Ответ 4
Расширение на ответ 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... поскольку/c на самом деле является корнем filesytem.
Ответ 5
Комментарий к script: git -file-size-diff, предложенный patthoyts. script очень полезен, однако я нашел две проблемы:
-
Когда кто-то меняет разрешения на файл, git возвращает другой аргумент в выражении case:
T) echo >&2 "Skipping change of type"
continue ;;
-
Если значение sha-1 больше не существует (по какой-то причине), сбой script. Прежде чем получить размер файла, вам необходимо проверить вау,
$(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