From: Jeff King Date: Mon, 22 Sep 2025 20:05:10 GMT Subject: Re: Could Git be smarter about object reuse? Message-ID: <20250922200510.GC2205919@coredump.intra.peff.net> In-Reply-To: <2RWL_muy24EPDZ9wWFx-WZfu4Br_F2LenvcVJbKewfSVYipYM3qmeEIgV-6o4EbL39ZjMXtLHbVFOCPcBdHHVAU-0BrgBtuQ9BdRjS_2niE=@calamity.inc> On Mon, Sep 22, 2025 at 10:49:07AM +0000, Sainan wrote: > > The receiver sends a list of commits it has > > This alone is not enough because if I'm amending a commit, it doesn't > have the new commit(s), but it does have the previous commit(s), so > the fact of blobs/trees being reusable is missed. Pushing doesn't dig into every possible blob/tree within each commit to look for duplicates. Doing that is very expensive in the most general case (you'd have to walk the entire object graph to check if some old commit mentions the blob you are about to send). So there are some heuristics about how much to dig. We can simulate this case in a single repo like this: git init # or any big file; we want it to be obvious when it is sent dd if=/dev/urandom bs=1M count=10 >rand.bin git add rand.bin # now make one commit git commit -m one one=$(git rev-parse HEAD) # and an amended one with the same tree git commit --amend -m two two=$(git rev-parse HEAD) If we pushed $one to a server, and then tried to push $two the server will tell us it has $one already. And push will feed this to pack-objects: echo ^$one >input echo $two >>input And now we can run that same pack-objects locally to see the output: $ git pack-objects --stdout --revs --thin --no-progress