| 
 | 1 | +#!/bin/sh  | 
 | 2 | + | 
 | 3 | +test_description='verify that push respects `pack.usePathWalk`'  | 
 | 4 | + | 
 | 5 | +TEST_PASSES_SANITIZE_LEAK=true  | 
 | 6 | +. ./test-lib.sh  | 
 | 7 | +. "$TEST_DIRECTORY"/lib-pack.sh  | 
 | 8 | + | 
 | 9 | +test_expect_success 'setup bare repository and clone' '  | 
 | 10 | +	git init --bare -b main bare.git &&  | 
 | 11 | +	git --git-dir=bare.git config receive.unpackLimit 0 &&  | 
 | 12 | +	git --git-dir bare.git commit-tree -m initial $EMPTY_TREE >head_oid &&  | 
 | 13 | +	git --git-dir bare.git update-ref refs/heads/main $(cat head_oid) &&  | 
 | 14 | +	git clone --bare bare.git clone.git  | 
 | 15 | +'  | 
 | 16 | +test_expect_success 'avoid reusing deltified objects' '  | 
 | 17 | +	# construct two commits, one containing a file with the hex digits  | 
 | 18 | +	# repeated 16 times, the next reducing that to 8 times. The crucial  | 
 | 19 | +	# part is that the blob of the second commit is deltified _really_  | 
 | 20 | +	# badly and it is therefore easy to detect if a `git push` reused that  | 
 | 21 | +	# delta.  | 
 | 22 | +	x="0123456789abcdef" &&  | 
 | 23 | +	printf "$x$x$x$x$x$x$x$x" >x128 &&  | 
 | 24 | +	printf "$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x" >x256 &&  | 
 | 25 | +
  | 
 | 26 | +	pack=clone.git/objects/pack/pack-tmp.pack &&  | 
 | 27 | +	pack_header 2 >$pack &&  | 
 | 28 | +
  | 
 | 29 | +	# add x256 as a non-deltified object, using an uncompressed zlib stream  | 
 | 30 | +	# for simplicity  | 
 | 31 | +	# 060 = OBJ_BLOB << 4, 0200 = size larger than 15,  | 
 | 32 | +	# 0 = lower 4 bits of size, 020 = bits 5-9 of size (size = 256)  | 
 | 33 | +	printf "\260\020" >>$pack &&  | 
 | 34 | +	# Uncompressed zlib stream always starts with 0170 1 1, followed  | 
 | 35 | +	# by two bytes encoding the size, little endian, then two bytes with  | 
 | 36 | +	# the bitwise-complement of that size, then the payload, and then the  | 
 | 37 | +	# Adler32 checksum. For some reason, the checksum is in big-endian  | 
 | 38 | +	# format.  | 
 | 39 | +	printf "\170\001\001\0\001\377\376" >>$pack &&  | 
 | 40 | +	cat x256 >>$pack &&  | 
 | 41 | +	# Manually-computed Adler32 checksum: 0xd7ae4621  | 
 | 42 | +	printf "\327\256\106\041" >>$pack &&  | 
 | 43 | +
  | 
 | 44 | +	# add x128 as a very badly deltified object  | 
 | 45 | +	# 0120 = OBJ_OFS_DELTA << 4, 0200 = total size larger than 15,  | 
 | 46 | +	# 4 = lower 4 bits of size, 030 = bits 5-9 of size  | 
 | 47 | +	# (size = 128 * 3 + 2 + 2)  | 
 | 48 | +	printf "\344\030" >>$pack &&  | 
 | 49 | +	# 0415 = size (i.e. the relative negative offset) of the previous  | 
 | 50 | +	# object (x256, used as base object)  | 
 | 51 | +	# encoded as 0200 | ((0415 >> 7) - 1), 0415 & 0177  | 
 | 52 | +	printf "\201\015" >>$pack &&  | 
 | 53 | +	# Uncompressed zlib stream, as before, size = 2 + 2 + 128 * 3 (i.e.  | 
 | 54 | +	# 0604)  | 
 | 55 | +	printf "\170\001\001\204\001\173\376" >>$pack &&  | 
 | 56 | +	# base object size = 0400 (encoded as 0200 | (0400 & 0177),  | 
 | 57 | +	# 0400 >> 7)  | 
 | 58 | +	printf "\200\002" >>$pack &&  | 
 | 59 | +	# object size = 0200 (encoded as 0200 | (0200 & 0177), 0200 >> 7  | 
 | 60 | +	printf "\200\001" >>$pack &&  | 
 | 61 | +	# massively badly-deltified object: copy every single byte individually  | 
 | 62 | +	# 0200 = copy, 1 = use 1 byte to encode the offset (counter),  | 
 | 63 | +	# 020 = use 1 byte to encode the size (1)  | 
 | 64 | +	printf "$(printf "\\\\221\\\\%03o\\\\001" $(test_seq 0 127))" >>$pack &&  | 
 | 65 | +	# Manually-computed Adler32 checksum: 0x99c369c4  | 
 | 66 | +	printf "\231\303\151\304" >>$pack &&  | 
 | 67 | +
  | 
 | 68 | +	pack_trailer $pack &&  | 
 | 69 | +	git index-pack -v $pack &&  | 
 | 70 | +
  | 
 | 71 | +	oid256=$(git hash-object x256) &&  | 
 | 72 | +	printf "100755 blob $oid256\thex\n" >tree &&  | 
 | 73 | +	tree_oid="$(git --git-dir=clone.git mktree <tree)" &&  | 
 | 74 | +	commit_oid=$(git --git-dir=clone.git commit-tree \  | 
 | 75 | +		-p $(git --git-dir=clone.git rev-parse main) \  | 
 | 76 | +		-m 256 $tree_oid) &&  | 
 | 77 | +
  | 
 | 78 | +	oid128=$(git hash-object x128) &&  | 
 | 79 | +	printf "100755 blob $oid128\thex\n" >tree &&  | 
 | 80 | +	tree_oid="$(git --git-dir=clone.git mktree <tree)" &&  | 
 | 81 | +	commit_oid=$(git --git-dir=clone.git commit-tree \  | 
 | 82 | +		-p $commit_oid \  | 
 | 83 | +		-m 128 $tree_oid) &&  | 
 | 84 | +
  | 
 | 85 | +	# Verify that the on-disk size of the delta object is suboptimal in the  | 
 | 86 | +	# clone (see below why 18 bytes or smaller is the optimal size):  | 
 | 87 | +	git index-pack --verify-stat clone.git/objects/pack/pack-*.pack >verify &&  | 
 | 88 | +	size="$(sed -n "s/^$oid128 blob *\([^ ]*\).*/\1/p" <verify)" &&  | 
 | 89 | +	test $size -gt 18 &&  | 
 | 90 | +
  | 
 | 91 | +	git --git-dir=clone.git update-ref refs/heads/main $commit_oid &&  | 
 | 92 | +	git --git-dir=clone.git -c pack.usePathWalk=true push origin main &&  | 
 | 93 | +	git index-pack --verify-stat bare.git/objects/pack/pack-*.pack >verify &&  | 
 | 94 | +	size="$(sed -n "s/^$oid128 blob *\([^ ]*\).*/\1/p" <verify)" &&  | 
 | 95 | +	# The on-disk size of the delta object should be smaller than, or equal  | 
 | 96 | +	# to, 18 bytes, as that would be the size if storing the payload  | 
 | 97 | +	# uncompressed:  | 
 | 98 | +	#   3 bytes: 0170 01 01  | 
 | 99 | +	# + 2 bytes: zlib stream size  | 
 | 100 | +	# + 2 bytes: but-wise complement of the zlib stream size  | 
 | 101 | +	# + 7 bytes: payload  | 
 | 102 | +	#   (= 2 bytes for the size of tbe base object  | 
 | 103 | +	#    + 2 bytes for the size of the delta command  | 
 | 104 | +	#    + 3 bytes for the copy command)  | 
 | 105 | +	# + 2 + 2 bytes: Adler32 checksum  | 
 | 106 | +	test $size -le 18  | 
 | 107 | +'  | 
 | 108 | + | 
 | 109 | +test_done  | 
0 commit comments