Git: показать общую разницу в размере файла между двумя коммитами?

Можно ли показать общую разницу в размере файла между двумя коммитами? Что-то вроде:

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

Я пробовал:

$ git diff --patch-with-stat

И это показывает разницу в размере файла для каждого двоичного файла в diff - но не для текстовых файлов, а не общую разницу в размере файла.

Есть идеи?

66 голосов | спросил Mathias Bynens 1 J0000006Europe/Moscow 2012, 09:48:08

5 ответов


0

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.'

. "$(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, он должен принять все обычные способы указания диапазонов фиксации.

РЕДАКТИРОВАТЬ: обновлено для записи совокупного итога. Обратите внимание, что bash выполняет чтение while в подоболочке, а следовательно, дополнительные фигурные скобки, чтобы избежать потери итогового значения при выходе из подоболочки.

РЕДАКТИРОВАТЬ: добавлена ​​поддержка сравнения индекса с другим древовидным списком с помощью аргумента --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
ответил patthoyts 1 J0000006Europe/Moscow 2012, 12:54:13
0

Вы можете передать вывод

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

и сравните 2 числа.

ответил Adam Dymitruk 1 J0000006Europe/Moscow 2012, 10:18:40
0

Я создал bash-скрипт для сравнения веток /коммитов и т. д. по фактическому размеру файла /контента. Его можно найти по адресу https://github.com/matthiaskrgr/gitdiffbinstat , а также обнаруживает переименования файлов.

ответил matthiaskrgr 29 SatEurope/Moscow2012-12-29T05:41:11+04:00Europe/Moscow12bEurope/MoscowSat, 29 Dec 2012 05:41:11 +0400 2012, 05:41:11
0

Расширение ответа 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 на самом деле является корнем файловой системы.

ответил guest 12 PMpTue, 12 Apr 2016 22:17:13 +030017Tuesday 2016, 22:17:13
0

Комментарий к сценарию: git-file-size-diff, предложенный patthoyts. Сценарий очень полезен, однако я обнаружил две проблемы:

  1. Когда кто-то меняет права доступа к файлу, git возвращает другой тип в выражении case:

    T) echo >&2 "Skipping change of type"
    continue ;;
    
  2. Если значение sha-1 больше не существует (по какой-то причине), сценарий вылетает. Вам нужно проверить sha перед получением размера файла:

    $(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
ответил Richard Nilsson 22 J0000006Europe/Moscow 2017, 12:40:06

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132