Show commit size in git log

Cyker picture Cyker · Nov 19, 2016 · Viewed 25.8k times · Source

How can I get commit size shown in the output of git log?

You may understand commit size as the diff between its parents and itself, or anything reasonable that tells you how big the commit is.

git log has a --log-size option but its the size of the log message, not the commit itself.

Answer

Schwern picture Schwern · Nov 19, 2016

The "size" of a commit can mean different things. If you mean how much disk storage it takes up... that's very tricky to tell in Git and probably unproductive. Whereas something like SVN stores commits as deltas, when you change a file in Git it stores a new copy of the file as an object in a graph database. One object can be shared in many commits. While this might sound inefficient, Git has many clever ways to use disk space shockingly efficiently.

If you mean how many lines did it change, that's easy. You can use various flags to get how many files and lines changed, most of them have the word "stat" in them. For example, git log --shortstat will tell you how many files changed, and how many lines were inserted and deleted. Here's an example.

commit e3d1909c875ea0c1a64246d735affa039ad11aa0 (origin/master, origin/HEAD)
Author: Michael G. Schwern <[email protected]>
Date:   Thu Aug 11 13:04:24 2016 -0700

    Add default Travis and AppVeyor configs.

    The AppVeyor one is set up for Dist::Zilla, the hardest of the bunch.

 2 files changed, 60 insertions(+)

If you want an idea of the disk storage that commit represents, you need to get the IDs of the new files (blob objects) the commit created, then check their size. You can see them in a git log -p.

commit 0f28d9a96bc92d802b57900ce4a06db71cbaef6d
Author: Michael G. Schwern <[email protected]>
Date:   Wed Aug 10 09:13:40 2016 -0700

    Remove my name from the gitconfig.

    Now it can be used by anyone. Git will prompt for the user info.

diff --git a/.gitconfig b/.gitconfig
index 1d539bd..538440f 100644
--- a/.gitconfig
+++ b/.gitconfig
@@ -1,18 +1,10 @@
-# If you use this file, remember to change the [user] and [sendemail] sections.
-
...and so on...

index 1d539bd..538440f 100644 indicates this replaced blob object (file) 1d539bd with 538440f and uses permissions 0644. If you run git cat-file -s 538440f it tells me the object is 4356 bytes. That's it's uncompressed size. On disk it's just 1849 bytes.

$ ls -l .git/objects/53/8440f84014584432fa5bf09d761926b3d70dbe 
-r--r--r-- 1 schwern staff 1849 Aug 10 09:14 .git/objects/53/8440f84014584432fa5bf09d761926b3d70dbe

After I git gc even the object file is gone. Now everything is in a pack file using less than 10K.

$ tree -h .git/objects/
.git/objects/
├── [ 102]  info
│   └── [  54]  packs
└── [ 136]  pack
    ├── [1.9K]  pack-d5b7110001ed35cce1aa0a380db762f39505b1c0.idx
    └── [7.8K]  pack-d5b7110001ed35cce1aa0a380db762f39505b1c0.pack

This answer shows how to get the blobs from a commit in a more automated fashion.