Git : 두 커밋 사이의 총 파일 크기 차이를 보여 주나요?


79

두 커밋 간의 총 파일 크기 차이를 표시 할 수 있습니까? 다음과 같은 것 :

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

난 노력 했어:

$ git diff --patch-with-stat

그리고 이것은 diff의 각 바이너리 파일에 대한 파일 크기 차이를 보여줍니다. 텍스트 파일이 아니라 전체 파일 크기 차이가 아닙니다.

어떤 아이디어?


3
여기에 특정 커밋의 3 선 당신 크기를 제공 bashscript입니다 stackoverflow.com/a/23985353/2062041
스타스 Dashkovsky

답변:


93

git cat-file -sgit에서 객체의 크기를 바이트 단위로 출력합니다. git diff-tree한 나무와 다른 나무의 차이점을 알려줄 수 있습니다.

이것을 git-file-size-diffPATH 어딘가에있는 라는 스크립트에 함께 넣으면 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
}

사용시 다음과 같이 보입니다.

$ 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는 하위 셸에서 읽는 동안을 실행하므로 하위 셸이 종료 될 때 합계를 잃지 않도록 추가 중괄호를 사용합니다.

편집 : 대신 --cached호출 할 인수를 사용하여 인덱스를 다른 tree-ish와 비교하기위한 지원이 추가되었습니다 . 예 :git diff-indexgit 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

+1 감사합니다! 이 것이 절대적 는 하단의 전체 크기 차이를 출력 할 경우에 적합합니다. 두 개의 ref 사이에 프로젝트 전체에서 추가 / 제거 된 바이트 수를보고 싶습니다 (파일 당뿐만 아니라 전체적으로도).
마티아스 Bynens

또 다른 질문 : git-sh-setup여기서 소싱하는 이유는 무엇입니까? 정의 된 함수를 사용하지 않는 것 같습니다 . 궁금해!
마티아스 Bynens

3
git 저장소가 아닌 디렉토리에서이 명령을 실행하면 합리적인 메시지를 생성하는 것과 같은 기본적인 검사를 수행합니다. 또한 일부 플랫폼 차이를 추상화하는 데 도움이 될 수 있습니다. 그래도 대부분 습관. git 스크립트를 작성할 때 먼저 git-sh-setup 파일을 가져 오십시오.
patthoyts

1
스크립트 주셔서 감사합니다! 요점 ( gist.github.com/cschell/9386715 ) 에 보관했습니다. 괜찮 으시길 바랍니다. 참을성이없는 사람들은 이제 다음과 같은 일을 할 수 있습니다curl -s https://gist.githubusercontent.com/cschell/9386715/raw/43996adb0f785a5afc17358be7a43ff7ee973215/git-file-size-diff | bash -s <tree-ish> <tree-ish>
csch

1
@ mr5 HEAD ~ 850은 HEAD 이전에 850 커밋입니다. 이는 커밋에 대한 또 다른 표기법 일 뿐이며 예, 특정 커밋 ID 나 태그 또는 커밋으로 해결 될 수있는 모든 것을 사용할 수 있습니다. 스크립트는 사용 git rev-parse하므로 자세한 내용은 git-rev-parse 문서의 "개정판 지정"매뉴얼 섹션을 참조하십시오. ( git-scm.com/docs/git-rev-parse )
patthoyts 2017-08-24

21

당신은 밖으로 파이프 할 수 있습니다

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

두 숫자를 비교합니다.


9
+1 버전 간 파일 크기 차이를 빠르게 확인할 때 유용합니다. 그러나 이것이 두 커밋 간의 전체 파일 차이를 얻는 데 어떻게 사용할 수 있습니까? 두 개의 ref 사이에 프로젝트 전체에서 추가 / 제거 된 바이트 수를보고 싶습니다.
마티아스 Bynens

1
당신은을 건너 뛸 수 있습니다 | wc -c당신이 사용하는 경우 cat-file -s대신show
neu242

@ neu242가 제안한 개선 사항을 사용하여이 bash 함수를 작성했습니다. gdbytes () { echo "$(git cat-file -s $1:$3) -> $(git cat-file -s $2:$3)" } 예를 들어 마지막 커밋 이후 파일 크기가 어떻게 변경되었는지 쉽게 확인할 수 있습니다.gdbytes @~ @ index.html
tknomad

경우 some-ref:부분이 생략되어, 당신은 작업 디렉토리에있는 파일 크기를 얻을 수 있습니까?
40detectives


3

matthiaskrgr의 답변을 확장 하면 https://github.com/matthiaskrgr/gitdiffbinstat 를 다른 스크립트와 같이 사용할 수 있습니다.

gitdiffbinstat.sh HEAD..HEAD~4

Imo는 여기에 게시 된 다른 어떤 것보다 훨씬 빠르게 잘 작동합니다. 샘플 출력 :

$ 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는 실제로 파일 시스템 루트이므로 출력 디렉토리는 ./c/data ...로 펑키합니다.


Matthias의 게시물에 대해 댓글을 달 필요가 없었습니다. 대신 그가 제공하지 않은 세부 정보를 사용하여 편집을 제안 할 수도있었습니다. 현재 기준에 따르면 그의 답변은 "링크 전용 답변"으로 간주되어 삭제되므로 이러한 종류의 세부 사항이 중요합니다.
Mogsdad

누가 내 대답을 마티아스에 포함시킬 수 있습니까?
게스트

원하는 경우 제안 된 편집을 직접 만들 수 있습니다. (제 경험상 리뷰어가 거부하는 경향이 있지만 편집 요약의 명확한 설명이 도움이 될 수 있습니다.)하지만 제가 당신에 대한 제 의견에서 명확하지 않았을 수도 있습니다 ... 당신의 대답은 독립적 인 대답입니다. , Matthias의 이전 답변에 대한 좋은 업데이트입니다. 댓글을 남기려고했다고 설명하는 텍스트를 포함 할 필요는 없습니다. 나는 Matthias에게 적절한 크레딧을주는 방식으로 답변을 편집했습니다. 더 많은 작업을 수행 할 필요가 없습니다.
Mogsdad 2014

2

스크립트에 대한 주석 : 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.