Tutorial :How to see the file size history of a single file in a git repository?


Is there anyway to see how a file's size has changed through time in a git repository? I want to see how my main.js file (which is the combination of several files and minified) has grown and shrunk over time.


You could create a script that uses the output from git show --pretty=raw <commit> to obtain the tree, then uses git ls-tree -r -l to obtain the blob you are looking for, including the file size.

In case you have ruby and the grit gem installed, here's a little script I threw together:

require 'grit'    if ARGV.size < 1    puts 'usage: file-size FILE'    puts 'run from within the git repo root'    exit  end    filename = ARGV[0].to_s    repo = Grit::Repo.new('.')  commits = repo.log('master', filename)  commits.each do |commit|    blob = commit.tree/filename    puts "#{commit} #{blob.size} bytes"  end  

Example usage (filename of script is file-size.rb), will show you the history for somedir/somefile:

myproject$ ruby file-size.rb somedir/somefile  


You can use either git ls-tree -r -l <revision> <path> to get the blob size at given revision, e.g.

  $ git ls-tree -r -l v1.6.0 gitweb/README  100644 blob 825162a0b6dce8c354de67a30abfbad94d29fdde   16067    gitweb/README  

The blob size in this example is '16067'. The disadvantage of this solution is that git ls-tree can process only one revision at once.

You can use instead git cat-file --batch-check < <list-of-objects> instead, feeding it blob identifiers. If location of file didn't change through history (file was not moved), you can use git rev-list <starting-point> -- <path> to get list of revisions touching given path, translate them into names of blobs using <revision>:<path> extended SHA-1 syntax (see git-rev-parse manpage), and feed it to git cat-file. Example:

  $ git rev-list -5 v1.6.0 -- gitweb/README |     sed -e 's/$/:gitweb\/README/g' |    git cat-file --batch-check  825162a0b6dce8c354de67a30abfbad94d29fdde blob 16067  6908036402ffe56c8b0cdcebdfb3dfacf84fb6f1 blob 16011  356ab7b327eb0df99c0773d68375e155dbcea0be blob 14248  8f7ea367bae72ea3ce25b10b968554f9b842fffe blob 13853  8dfe335f73c223fa0da8cd21db6227283adb95ba blob 13801  


Create a file called .gitattributes and add the following line:

main.js -diff  

This turns off line-based diffs for main.js. Now run the following command:

git log --stat main.js  

The log will include lines like

main.js | Bin 4316 -> 4360 bytes  

After you're done, you should probably delete .gitattributes. I don't know what other changes in git's behavior may be caused by the -diff attribute.

Tested with git versions and

Source: ewall's answer and https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html#_marking_files_as_binary


In case this is of use for someone, this script will show the size of a given file in different commits:

git log <file_name> | grep "^commit" | cut -f2 -d" " | while read hash; do     echo -n "$hash -- "     git show $hash:<file_path_off_of_git_root_without_leading_slash> | wc -c  done  


While commands like git log <filename>, git whatchanged, etc. can show the history pertaining to that file, I don't see anywhere in either the built-in or custom pretty formats an option that shows size (sadly, the --log-size option is only for the log messages!).

However, you can get a rough idea of the size by seeing the total number of lines added and removed in each commit. You can sort of visualize it with the command git log --stat <filename>, which uses plus and minus signs. Or use git log --numstat <filename> to collect the number of lines added or removed in each commit and use the numbers in some other visualization.


On Windows I am using the following command:

cmd /c "@echo off & for /l %N in (1 1 30) do git ls-tree -r -l HEAD~%N "C:\path\to\file.txt"  

It will show size of each of latest 30 versions.

If somebody can convert that to Linux command you are welcome... ))

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »