On Wed, Dec 13, 2023 at 01:28:56PM +0100, René Scharfe wrote: > Add test_object_size and its helpers test_loose_object_size and > test_packed_object_size, which allow determining the size of a Git > object using only the low-level Git commands rev-parse and show-index. > > Use it in t6300 to replace the bare-bones function test_object_file_size > as a motivating example. There it provides the expected output of the > high-level Git command for-each-ref. This adds a packed-object function, but I doubt anybody actually calls it. If we're going to do that, it's probably worth adding some tests for "cat-file --batch-check" or similar. At which point I wonder if rather than having a function for a single object, we are better off just testing the result of: git cat-file --batch-all-objects --unordered --batch-check='%(objectsize:disk)' against a single post-processed "show-index" invocation. > So how about this? I'm a bit nervous about all the rules about output > descriptors and error propagation and whatnot in the test library, but > this implementation seems simple enough and might be useful in more than > one test. No idea how to add support for alternate object directories, > but I doubt we'll ever need it. I'm not sure that we need to do anything special with output redirection. Shouldn't these functions just send errors to stderr as usual? If they are run inside a test_expect block, that goes to descriptor 4 (which is either /dev/null or the original stderr, depending on whether "-v" was used). > +test_loose_object_size () { > + test "$#" -ne 1 && BUG "1 param" > + local path=$(test_oid_to_path "$1") > + test_file_size "$(git rev-parse --git-path "objects/$path")" 2>&4 > +} OK. We lose the exit code from "rev-parse" but that is probably OK for our purposes. > +test_packed_object_size () { > + test "$#" -ne 2 && BUG "2 params" > + local oid=$1 idx=$2 packsize rawsz end > + > + packsize=$(test_file_size "${idx%.idx}.pack") > + rawsz=$(test_oid rawsz) > + end=$(($packsize - $rawsz)) OK, this $end is the magic required for the final entry. Makes sense. > + git show-index <"$idx" | > + awk -v oid="$oid" -v end="$end" ' > + $2 == oid {start = $1} > + {offsets[$1] = 1} > + END { > + if (!start || start >= end) > + exit 1 > + for (o in offsets) > + if (start < o && o < end) > + end = o > + print end - start > + } > + ' && return 0 I was confused at first, because I didn't see any sorting happening. But if I understand correctly, you're just looking for the smallest "end" that comes after the start of the object we're looking for. Which I think works. -Peff