Git: show total file size difference between two commits?

后端 未结 5 465
心在旅途
心在旅途 2020-12-04 08:05

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 b         


        
相关标签:
5条回答
  • 2020-12-04 08:34

    Expanding on matthiaskrgr's answer, https://github.com/matthiaskrgr/gitdiffbinstat can be used like the other scripts:

    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.

    0 讨论(0)
  • 2020-12-04 08:40

    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.

    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:

    #!/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.

    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.

    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:

    $ 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
    
    0 讨论(0)
  • 2020-12-04 08:44

    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.

    0 讨论(0)
  • 2020-12-04 08:44

    I made a bash script to compare branches/commits etc by actual file/content size. It can be found at https://github.com/matthiaskrgr/gitdiffbinstat and also detects file renames.

    0 讨论(0)
  • 2020-12-04 08:54

    A comment to the script: git-file-size-diff, suggested by patthoyts. The script is very useful, however, I have found two issues:

    1. When someone change permissions on the file, git returns a another type in the case statement:

      T) echo >&2 "Skipping change of type"
      continue ;;
      
    2. 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

    The complete case statement will then look like this:

    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
    
    0 讨论(0)
提交回复
热议问题