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