t / t5317-pack-objects-filter-objects.shon commit list-objects: support for skipping tree traversal (8b10a20)
   1#!/bin/sh
   2
   3test_description='git pack-objects using object filtering'
   4
   5. ./test-lib.sh
   6
   7# Test blob:none filter.
   8
   9test_expect_success 'setup r1' '
  10        echo "{print \$1}" >print_1.awk &&
  11        echo "{print \$2}" >print_2.awk &&
  12
  13        git init r1 &&
  14        for n in 1 2 3 4 5
  15        do
  16                echo "This is file: $n" > r1/file.$n
  17                git -C r1 add file.$n
  18                git -C r1 commit -m "$n"
  19        done
  20'
  21
  22test_expect_success 'verify blob count in normal packfile' '
  23        git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \
  24                | awk -f print_2.awk \
  25                | sort >expected &&
  26        git -C r1 pack-objects --rev --stdout >all.pack <<-EOF &&
  27        HEAD
  28        EOF
  29        git -C r1 index-pack ../all.pack &&
  30        git -C r1 verify-pack -v ../all.pack \
  31                | grep blob \
  32                | awk -f print_1.awk \
  33                | sort >observed &&
  34        test_cmp observed expected
  35'
  36
  37test_expect_success 'verify blob:none packfile has no blobs' '
  38        git -C r1 pack-objects --rev --stdout --filter=blob:none >filter.pack <<-EOF &&
  39        HEAD
  40        EOF
  41        git -C r1 index-pack ../filter.pack &&
  42        git -C r1 verify-pack -v ../filter.pack \
  43                | grep blob \
  44                | awk -f print_1.awk \
  45                | sort >observed &&
  46        nr=$(wc -l <observed) &&
  47        test 0 -eq $nr
  48'
  49
  50test_expect_success 'verify normal and blob:none packfiles have same commits/trees' '
  51        git -C r1 verify-pack -v ../all.pack \
  52                | grep -E "commit|tree" \
  53                | awk -f print_1.awk \
  54                | sort >expected &&
  55        git -C r1 verify-pack -v ../filter.pack \
  56                | grep -E "commit|tree" \
  57                | awk -f print_1.awk \
  58                | sort >observed &&
  59        test_cmp observed expected
  60'
  61
  62test_expect_success 'get an error for missing tree object' '
  63        git init r5 &&
  64        echo foo >r5/foo &&
  65        git -C r5 add foo &&
  66        git -C r5 commit -m "foo" &&
  67        del=$(git -C r5 rev-parse HEAD^{tree} | sed "s|..|&/|") &&
  68        rm r5/.git/objects/$del &&
  69        test_must_fail git -C r5 pack-objects --rev --stdout 2>bad_tree <<-EOF &&
  70        HEAD
  71        EOF
  72        grep "bad tree object" bad_tree
  73'
  74
  75test_expect_success 'setup for tests of tree:0' '
  76        mkdir r1/subtree &&
  77        echo "This is a file in a subtree" >r1/subtree/file &&
  78        git -C r1 add subtree/file &&
  79        git -C r1 commit -m subtree
  80'
  81
  82test_expect_success 'verify tree:0 packfile has no blobs or trees' '
  83        git -C r1 pack-objects --rev --stdout --filter=tree:0 >commitsonly.pack <<-EOF &&
  84        HEAD
  85        EOF
  86        git -C r1 index-pack ../commitsonly.pack &&
  87        git -C r1 verify-pack -v ../commitsonly.pack >objs &&
  88        ! grep -E "tree|blob" objs
  89'
  90
  91test_expect_success 'grab tree directly when using tree:0' '
  92        # We should get the tree specified directly but not its blobs or subtrees.
  93        git -C r1 pack-objects --rev --stdout --filter=tree:0 >commitsonly.pack <<-EOF &&
  94        HEAD:
  95        EOF
  96        git -C r1 index-pack ../commitsonly.pack &&
  97        git -C r1 verify-pack -v ../commitsonly.pack >objs &&
  98        awk "/tree|blob/{print \$1}" objs >trees_and_blobs &&
  99        git -C r1 rev-parse HEAD: >expected &&
 100        test_cmp expected trees_and_blobs
 101'
 102
 103# Test blob:limit=<n>[kmg] filter.
 104# We boundary test around the size parameter.  The filter is strictly less than
 105# the value, so size 500 and 1000 should have the same results, but 1001 should
 106# filter more.
 107
 108test_expect_success 'setup r2' '
 109        git init r2 &&
 110        for n in 1000 10000
 111        do
 112                printf "%"$n"s" X > r2/large.$n
 113                git -C r2 add large.$n
 114                git -C r2 commit -m "$n"
 115        done
 116'
 117
 118test_expect_success 'verify blob count in normal packfile' '
 119        git -C r2 ls-files -s large.1000 large.10000 \
 120                | awk -f print_2.awk \
 121                | sort >expected &&
 122        git -C r2 pack-objects --rev --stdout >all.pack <<-EOF &&
 123        HEAD
 124        EOF
 125        git -C r2 index-pack ../all.pack &&
 126        git -C r2 verify-pack -v ../all.pack \
 127                | grep blob \
 128                | awk -f print_1.awk \
 129                | sort >observed &&
 130        test_cmp observed expected
 131'
 132
 133test_expect_success 'verify blob:limit=500 omits all blobs' '
 134        git -C r2 pack-objects --rev --stdout --filter=blob:limit=500 >filter.pack <<-EOF &&
 135        HEAD
 136        EOF
 137        git -C r2 index-pack ../filter.pack &&
 138        git -C r2 verify-pack -v ../filter.pack \
 139                | grep blob \
 140                | awk -f print_1.awk \
 141                | sort >observed &&
 142        nr=$(wc -l <observed) &&
 143        test 0 -eq $nr
 144'
 145
 146test_expect_success 'verify blob:limit=1000' '
 147        git -C r2 pack-objects --rev --stdout --filter=blob:limit=1000 >filter.pack <<-EOF &&
 148        HEAD
 149        EOF
 150        git -C r2 index-pack ../filter.pack &&
 151        git -C r2 verify-pack -v ../filter.pack \
 152                | grep blob \
 153                | awk -f print_1.awk \
 154                | sort >observed &&
 155        nr=$(wc -l <observed) &&
 156        test 0 -eq $nr
 157'
 158
 159test_expect_success 'verify blob:limit=1001' '
 160        git -C r2 ls-files -s large.1000 \
 161                | awk -f print_2.awk \
 162                | sort >expected &&
 163        git -C r2 pack-objects --rev --stdout --filter=blob:limit=1001 >filter.pack <<-EOF &&
 164        HEAD
 165        EOF
 166        git -C r2 index-pack ../filter.pack &&
 167        git -C r2 verify-pack -v ../filter.pack \
 168                | grep blob \
 169                | awk -f print_1.awk \
 170                | sort >observed &&
 171        test_cmp observed expected
 172'
 173
 174test_expect_success 'verify blob:limit=10001' '
 175        git -C r2 ls-files -s large.1000 large.10000 \
 176                | awk -f print_2.awk \
 177                | sort >expected &&
 178        git -C r2 pack-objects --rev --stdout --filter=blob:limit=10001 >filter.pack <<-EOF &&
 179        HEAD
 180        EOF
 181        git -C r2 index-pack ../filter.pack &&
 182        git -C r2 verify-pack -v ../filter.pack \
 183                | grep blob \
 184                | awk -f print_1.awk \
 185                | sort >observed &&
 186        test_cmp observed expected
 187'
 188
 189test_expect_success 'verify blob:limit=1k' '
 190        git -C r2 ls-files -s large.1000 \
 191                | awk -f print_2.awk \
 192                | sort >expected &&
 193        git -C r2 pack-objects --rev --stdout --filter=blob:limit=1k >filter.pack <<-EOF &&
 194        HEAD
 195        EOF
 196        git -C r2 index-pack ../filter.pack &&
 197        git -C r2 verify-pack -v ../filter.pack \
 198                | grep blob \
 199                | awk -f print_1.awk \
 200                | sort >observed &&
 201        test_cmp observed expected
 202'
 203
 204test_expect_success 'verify explicitly specifying oversized blob in input' '
 205        git -C r2 ls-files -s large.1000 large.10000 \
 206                | awk -f print_2.awk \
 207                | sort >expected &&
 208        git -C r2 pack-objects --rev --stdout --filter=blob:limit=1k >filter.pack <<-EOF &&
 209        HEAD
 210        $(git -C r2 rev-parse HEAD:large.10000)
 211        EOF
 212        git -C r2 index-pack ../filter.pack &&
 213        git -C r2 verify-pack -v ../filter.pack \
 214                | grep blob \
 215                | awk -f print_1.awk \
 216                | sort >observed &&
 217        test_cmp observed expected
 218'
 219
 220test_expect_success 'verify blob:limit=1m' '
 221        git -C r2 ls-files -s large.1000 large.10000 \
 222                | awk -f print_2.awk \
 223                | sort >expected &&
 224        git -C r2 pack-objects --rev --stdout --filter=blob:limit=1m >filter.pack <<-EOF &&
 225        HEAD
 226        EOF
 227        git -C r2 index-pack ../filter.pack &&
 228        git -C r2 verify-pack -v ../filter.pack \
 229                | grep blob \
 230                | awk -f print_1.awk \
 231                | sort >observed &&
 232        test_cmp observed expected
 233'
 234
 235test_expect_success 'verify normal and blob:limit packfiles have same commits/trees' '
 236        git -C r2 verify-pack -v ../all.pack \
 237                | grep -E "commit|tree" \
 238                | awk -f print_1.awk \
 239                | sort >expected &&
 240        git -C r2 verify-pack -v ../filter.pack \
 241                | grep -E "commit|tree" \
 242                | awk -f print_1.awk \
 243                | sort >observed &&
 244        test_cmp observed expected
 245'
 246
 247# Test sparse:path=<path> filter.
 248# Use a local file containing a sparse-checkout specification to filter
 249# out blobs not required for the corresponding sparse-checkout.  We do not
 250# require sparse-checkout to actually be enabled.
 251
 252test_expect_success 'setup r3' '
 253        git init r3 &&
 254        mkdir r3/dir1 &&
 255        for n in sparse1 sparse2
 256        do
 257                echo "This is file: $n" > r3/$n
 258                git -C r3 add $n
 259                echo "This is file: dir1/$n" > r3/dir1/$n
 260                git -C r3 add dir1/$n
 261        done &&
 262        git -C r3 commit -m "sparse" &&
 263        echo dir1/ >pattern1 &&
 264        echo sparse1 >pattern2
 265'
 266
 267test_expect_success 'verify blob count in normal packfile' '
 268        git -C r3 ls-files -s sparse1 sparse2 dir1/sparse1 dir1/sparse2 \
 269                | awk -f print_2.awk \
 270                | sort >expected &&
 271        git -C r3 pack-objects --rev --stdout >all.pack <<-EOF &&
 272        HEAD
 273        EOF
 274        git -C r3 index-pack ../all.pack &&
 275        git -C r3 verify-pack -v ../all.pack \
 276                | grep blob \
 277                | awk -f print_1.awk \
 278                | sort >observed &&
 279        test_cmp observed expected
 280'
 281
 282test_expect_success 'verify sparse:path=pattern1' '
 283        git -C r3 ls-files -s dir1/sparse1 dir1/sparse2 \
 284                | awk -f print_2.awk \
 285                | sort >expected &&
 286        git -C r3 pack-objects --rev --stdout --filter=sparse:path=../pattern1 >filter.pack <<-EOF &&
 287        HEAD
 288        EOF
 289        git -C r3 index-pack ../filter.pack &&
 290        git -C r3 verify-pack -v ../filter.pack \
 291                | grep blob \
 292                | awk -f print_1.awk \
 293                | sort >observed &&
 294        test_cmp observed expected
 295'
 296
 297test_expect_success 'verify normal and sparse:path=pattern1 packfiles have same commits/trees' '
 298        git -C r3 verify-pack -v ../all.pack \
 299                | grep -E "commit|tree" \
 300                | awk -f print_1.awk \
 301                | sort >expected &&
 302        git -C r3 verify-pack -v ../filter.pack \
 303                | grep -E "commit|tree" \
 304                | awk -f print_1.awk \
 305                | sort >observed &&
 306        test_cmp observed expected
 307'
 308
 309test_expect_success 'verify sparse:path=pattern2' '
 310        git -C r3 ls-files -s sparse1 dir1/sparse1 \
 311                | awk -f print_2.awk \
 312                | sort >expected &&
 313        git -C r3 pack-objects --rev --stdout --filter=sparse:path=../pattern2 >filter.pack <<-EOF &&
 314        HEAD
 315        EOF
 316        git -C r3 index-pack ../filter.pack &&
 317        git -C r3 verify-pack -v ../filter.pack \
 318                | grep blob \
 319                | awk -f print_1.awk \
 320                | sort >observed &&
 321        test_cmp observed expected
 322'
 323
 324test_expect_success 'verify normal and sparse:path=pattern2 packfiles have same commits/trees' '
 325        git -C r3 verify-pack -v ../all.pack \
 326                | grep -E "commit|tree" \
 327                | awk -f print_1.awk \
 328                | sort >expected &&
 329        git -C r3 verify-pack -v ../filter.pack \
 330                | grep -E "commit|tree" \
 331                | awk -f print_1.awk \
 332                | sort >observed &&
 333        test_cmp observed expected
 334'
 335
 336# Test sparse:oid=<oid-ish> filter.
 337# Like sparse:path, but we get the sparse-checkout specification from
 338# a blob rather than a file on disk.
 339
 340test_expect_success 'setup r4' '
 341        git init r4 &&
 342        mkdir r4/dir1 &&
 343        for n in sparse1 sparse2
 344        do
 345                echo "This is file: $n" > r4/$n
 346                git -C r4 add $n
 347                echo "This is file: dir1/$n" > r4/dir1/$n
 348                git -C r4 add dir1/$n
 349        done &&
 350        echo dir1/ >r4/pattern &&
 351        git -C r4 add pattern &&
 352        git -C r4 commit -m "pattern"
 353'
 354
 355test_expect_success 'verify blob count in normal packfile' '
 356        git -C r4 ls-files -s pattern sparse1 sparse2 dir1/sparse1 dir1/sparse2 \
 357                | awk -f print_2.awk \
 358                | sort >expected &&
 359        git -C r4 pack-objects --rev --stdout >all.pack <<-EOF &&
 360        HEAD
 361        EOF
 362        git -C r4 index-pack ../all.pack &&
 363        git -C r4 verify-pack -v ../all.pack \
 364                | grep blob \
 365                | awk -f print_1.awk \
 366                | sort >observed &&
 367        test_cmp observed expected
 368'
 369
 370test_expect_success 'verify sparse:oid=OID' '
 371        git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 \
 372                | awk -f print_2.awk \
 373                | sort >expected &&
 374        oid=$(git -C r4 ls-files -s pattern | awk -f print_2.awk) &&
 375        git -C r4 pack-objects --rev --stdout --filter=sparse:oid=$oid >filter.pack <<-EOF &&
 376        HEAD
 377        EOF
 378        git -C r4 index-pack ../filter.pack &&
 379        git -C r4 verify-pack -v ../filter.pack \
 380                | grep blob \
 381                | awk -f print_1.awk \
 382                | sort >observed &&
 383        test_cmp observed expected
 384'
 385
 386test_expect_success 'verify sparse:oid=oid-ish' '
 387        git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 \
 388                | awk -f print_2.awk \
 389                | sort >expected &&
 390        git -C r4 pack-objects --rev --stdout --filter=sparse:oid=master:pattern >filter.pack <<-EOF &&
 391        HEAD
 392        EOF
 393        git -C r4 index-pack ../filter.pack &&
 394        git -C r4 verify-pack -v ../filter.pack \
 395                | grep blob \
 396                | awk -f print_1.awk \
 397                | sort >observed &&
 398        test_cmp observed expected
 399'
 400
 401# Delete some loose objects and use pack-objects, but WITHOUT any filtering.
 402# This models previously omitted objects that we did not receive.
 403
 404test_expect_success 'setup r1 - delete loose blobs' '
 405        git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \
 406                | awk -f print_2.awk \
 407                | sort >expected &&
 408        for id in `cat expected | sed "s|..|&/|"`
 409        do
 410                rm r1/.git/objects/$id
 411        done
 412'
 413
 414test_expect_success 'verify pack-objects fails w/ missing objects' '
 415        test_must_fail git -C r1 pack-objects --rev --stdout >miss.pack <<-EOF
 416        HEAD
 417        EOF
 418'
 419
 420test_expect_success 'verify pack-objects fails w/ --missing=error' '
 421        test_must_fail git -C r1 pack-objects --rev --stdout --missing=error >miss.pack <<-EOF
 422        HEAD
 423        EOF
 424'
 425
 426test_expect_success 'verify pack-objects w/ --missing=allow-any' '
 427        git -C r1 pack-objects --rev --stdout --missing=allow-any >miss.pack <<-EOF
 428        HEAD
 429        EOF
 430'
 431
 432test_done