t / t1006-cat-file.shon commit cat-file: add --follow-symlinks to --batch (122d534)
   1#!/bin/sh
   2
   3test_description='git cat-file'
   4
   5. ./test-lib.sh
   6
   7echo_without_newline () {
   8    printf '%s' "$*"
   9}
  10
  11strlen () {
  12    echo_without_newline "$1" | wc -c | sed -e 's/^ *//'
  13}
  14
  15maybe_remove_timestamp () {
  16    if test -z "$2"; then
  17        echo_without_newline "$1"
  18    else
  19        echo_without_newline "$(printf '%s\n' "$1" | sed -e 's/ [0-9][0-9]* [-+][0-9][0-9][0-9][0-9]$//')"
  20    fi
  21}
  22
  23run_tests () {
  24    type=$1
  25    sha1=$2
  26    size=$3
  27    content=$4
  28    pretty_content=$5
  29    no_ts=$6
  30
  31    batch_output="$sha1 $type $size
  32$content"
  33
  34    test_expect_success "$type exists" '
  35        git cat-file -e $sha1
  36    '
  37
  38    test_expect_success "Type of $type is correct" '
  39        echo $type >expect &&
  40        git cat-file -t $sha1 >actual &&
  41        test_cmp expect actual
  42    '
  43
  44    test_expect_success "Size of $type is correct" '
  45        echo $size >expect &&
  46        git cat-file -s $sha1 >actual &&
  47        test_cmp expect actual
  48    '
  49
  50    test -z "$content" ||
  51    test_expect_success "Content of $type is correct" '
  52        maybe_remove_timestamp "$content" $no_ts >expect &&
  53        maybe_remove_timestamp "$(git cat-file $type $sha1)" $no_ts >actual &&
  54        test_cmp expect actual
  55    '
  56
  57    test_expect_success "Pretty content of $type is correct" '
  58        maybe_remove_timestamp "$pretty_content" $no_ts >expect &&
  59        maybe_remove_timestamp "$(git cat-file -p $sha1)" $no_ts >actual &&
  60        test_cmp expect actual
  61    '
  62
  63    test -z "$content" ||
  64    test_expect_success "--batch output of $type is correct" '
  65        maybe_remove_timestamp "$batch_output" $no_ts >expect &&
  66        maybe_remove_timestamp "$(echo $sha1 | git cat-file --batch)" $no_ts >actual &&
  67        test_cmp expect actual
  68    '
  69
  70    test_expect_success "--batch-check output of $type is correct" '
  71        echo "$sha1 $type $size" >expect &&
  72        echo_without_newline $sha1 | git cat-file --batch-check >actual &&
  73        test_cmp expect actual
  74    '
  75
  76    test_expect_success "custom --batch-check format" '
  77        echo "$type $sha1" >expect &&
  78        echo $sha1 | git cat-file --batch-check="%(objecttype) %(objectname)" >actual &&
  79        test_cmp expect actual
  80    '
  81
  82    test_expect_success '--batch-check with %(rest)' '
  83        echo "$type this is some extra content" >expect &&
  84        echo "$sha1    this is some extra content" |
  85                git cat-file --batch-check="%(objecttype) %(rest)" >actual &&
  86        test_cmp expect actual
  87    '
  88
  89    test -z "$content" ||
  90    test_expect_success "--batch without type ($type)" '
  91        {
  92                echo "$size" &&
  93                maybe_remove_timestamp "$content" $no_ts
  94        } >expect &&
  95        echo $sha1 | git cat-file --batch="%(objectsize)" >actual.full &&
  96        maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual &&
  97        test_cmp expect actual
  98    '
  99
 100    test -z "$content" ||
 101    test_expect_success "--batch without size ($type)" '
 102        {
 103                echo "$type" &&
 104                maybe_remove_timestamp "$content" $no_ts
 105        } >expect &&
 106        echo $sha1 | git cat-file --batch="%(objecttype)" >actual.full &&
 107        maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual &&
 108        test_cmp expect actual
 109    '
 110}
 111
 112hello_content="Hello World"
 113hello_size=$(strlen "$hello_content")
 114hello_sha1=$(echo_without_newline "$hello_content" | git hash-object --stdin)
 115
 116test_expect_success "setup" '
 117        echo_without_newline "$hello_content" > hello &&
 118        git update-index --add hello
 119'
 120
 121run_tests 'blob' $hello_sha1 $hello_size "$hello_content" "$hello_content"
 122
 123test_expect_success '--batch-check without %(rest) considers whole line' '
 124        echo "$hello_sha1 blob $hello_size" >expect &&
 125        git update-index --add --cacheinfo 100644 $hello_sha1 "white space" &&
 126        test_when_finished "git update-index --remove \"white space\"" &&
 127        echo ":white space" | git cat-file --batch-check >actual &&
 128        test_cmp expect actual
 129'
 130
 131tree_sha1=$(git write-tree)
 132tree_size=33
 133tree_pretty_content="100644 blob $hello_sha1    hello"
 134
 135run_tests 'tree' $tree_sha1 $tree_size "" "$tree_pretty_content"
 136
 137commit_message="Initial commit"
 138commit_sha1=$(echo_without_newline "$commit_message" | git commit-tree $tree_sha1)
 139commit_size=177
 140commit_content="tree $tree_sha1
 141author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 0000000000 +0000
 142committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 0000000000 +0000
 143
 144$commit_message"
 145
 146run_tests 'commit' $commit_sha1 $commit_size "$commit_content" "$commit_content" 1
 147
 148tag_header_without_timestamp="object $hello_sha1
 149type blob
 150tag hellotag
 151tagger $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
 152tag_description="This is a tag"
 153tag_content="$tag_header_without_timestamp 0000000000 +0000
 154
 155$tag_description"
 156
 157tag_sha1=$(echo_without_newline "$tag_content" | git mktag)
 158tag_size=$(strlen "$tag_content")
 159
 160run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_content" 1
 161
 162test_expect_success \
 163    "Reach a blob from a tag pointing to it" \
 164    "test '$hello_content' = \"\$(git cat-file blob $tag_sha1)\""
 165
 166for batch in batch batch-check
 167do
 168    for opt in t s e p
 169    do
 170        test_expect_success "Passing -$opt with --$batch fails" '
 171            test_must_fail git cat-file --$batch -$opt $hello_sha1
 172        '
 173
 174        test_expect_success "Passing --$batch with -$opt fails" '
 175            test_must_fail git cat-file -$opt --$batch $hello_sha1
 176        '
 177    done
 178
 179    test_expect_success "Passing <type> with --$batch fails" '
 180        test_must_fail git cat-file --$batch blob $hello_sha1
 181    '
 182
 183    test_expect_success "Passing --$batch with <type> fails" '
 184        test_must_fail git cat-file blob --$batch $hello_sha1
 185    '
 186
 187    test_expect_success "Passing sha1 with --$batch fails" '
 188        test_must_fail git cat-file --$batch $hello_sha1
 189    '
 190done
 191
 192for opt in t s e p
 193do
 194    test_expect_success "Passing -$opt with --follow-symlinks fails" '
 195            test_must_fail git cat-file --follow-symlinks -$opt $hello_sha1
 196        '
 197done
 198
 199test_expect_success "--batch-check for a non-existent named object" '
 200    test "foobar42 missing
 201foobar84 missing" = \
 202    "$( ( echo foobar42; echo_without_newline foobar84; ) | git cat-file --batch-check)"
 203'
 204
 205test_expect_success "--batch-check for a non-existent hash" '
 206    test "0000000000000000000000000000000000000042 missing
 2070000000000000000000000000000000000000084 missing" = \
 208    "$( ( echo 0000000000000000000000000000000000000042;
 209         echo_without_newline 0000000000000000000000000000000000000084; ) \
 210       | git cat-file --batch-check)"
 211'
 212
 213test_expect_success "--batch for an existent and a non-existent hash" '
 214    test "$tag_sha1 tag $tag_size
 215$tag_content
 2160000000000000000000000000000000000000000 missing" = \
 217    "$( ( echo $tag_sha1;
 218         echo_without_newline 0000000000000000000000000000000000000000; ) \
 219       | git cat-file --batch)"
 220'
 221
 222test_expect_success "--batch-check for an emtpy line" '
 223    test " missing" = "$(echo | git cat-file --batch-check)"
 224'
 225
 226test_expect_success 'empty --batch-check notices missing object' '
 227        echo "$_z40 missing" >expect &&
 228        echo "$_z40" | git cat-file --batch-check="" >actual &&
 229        test_cmp expect actual
 230'
 231
 232batch_input="$hello_sha1
 233$commit_sha1
 234$tag_sha1
 235deadbeef
 236
 237"
 238
 239batch_output="$hello_sha1 blob $hello_size
 240$hello_content
 241$commit_sha1 commit $commit_size
 242$commit_content
 243$tag_sha1 tag $tag_size
 244$tag_content
 245deadbeef missing
 246 missing"
 247
 248test_expect_success '--batch with multiple sha1s gives correct format' '
 249        test "$(maybe_remove_timestamp "$batch_output" 1)" = "$(maybe_remove_timestamp "$(echo_without_newline "$batch_input" | git cat-file --batch)" 1)"
 250'
 251
 252batch_check_input="$hello_sha1
 253$tree_sha1
 254$commit_sha1
 255$tag_sha1
 256deadbeef
 257
 258"
 259
 260batch_check_output="$hello_sha1 blob $hello_size
 261$tree_sha1 tree $tree_size
 262$commit_sha1 commit $commit_size
 263$tag_sha1 tag $tag_size
 264deadbeef missing
 265 missing"
 266
 267test_expect_success "--batch-check with multiple sha1s gives correct format" '
 268    test "$batch_check_output" = \
 269    "$(echo_without_newline "$batch_check_input" | git cat-file --batch-check)"
 270'
 271
 272test_expect_success 'setup blobs which are likely to delta' '
 273        test-genrandom foo 10240 >foo &&
 274        { cat foo; echo plus; } >foo-plus &&
 275        git add foo foo-plus &&
 276        git commit -m foo &&
 277        cat >blobs <<-\EOF
 278        HEAD:foo
 279        HEAD:foo-plus
 280        EOF
 281'
 282
 283test_expect_success 'confirm that neither loose blob is a delta' '
 284        cat >expect <<-EOF &&
 285        $_z40
 286        $_z40
 287        EOF
 288        git cat-file --batch-check="%(deltabase)" <blobs >actual &&
 289        test_cmp expect actual
 290'
 291
 292# To avoid relying too much on the current delta heuristics,
 293# we will check only that one of the two objects is a delta
 294# against the other, but not the order. We can do so by just
 295# asking for the base of both, and checking whether either
 296# sha1 appears in the output.
 297test_expect_success '%(deltabase) reports packed delta bases' '
 298        git repack -ad &&
 299        git cat-file --batch-check="%(deltabase)" <blobs >actual &&
 300        {
 301                grep "$(git rev-parse HEAD:foo)" actual ||
 302                grep "$(git rev-parse HEAD:foo-plus)" actual
 303        }
 304'
 305
 306# Tests for git cat-file --follow-symlinks
 307test_expect_success 'prep for symlink tests' '
 308        echo_without_newline "$hello_content" >morx &&
 309        test_ln_s_add morx same-dir-link &&
 310        test_ln_s_add dir link-to-dir &&
 311        test_ln_s_add ../fleem out-of-repo-link &&
 312        test_ln_s_add .. out-of-repo-link-dir &&
 313        test_ln_s_add same-dir-link link-to-link &&
 314        test_ln_s_add nope broken-same-dir-link &&
 315        mkdir dir &&
 316        test_ln_s_add ../morx dir/parent-dir-link &&
 317        test_ln_s_add .. dir/link-dir &&
 318        test_ln_s_add ../../escape dir/out-of-repo-link &&
 319        test_ln_s_add ../.. dir/out-of-repo-link-dir &&
 320        test_ln_s_add nope dir/broken-link-in-dir &&
 321        mkdir dir/subdir &&
 322        test_ln_s_add ../../morx dir/subdir/grandparent-dir-link &&
 323        test_ln_s_add ../../../great-escape dir/subdir/out-of-repo-link &&
 324        test_ln_s_add ../../.. dir/subdir/out-of-repo-link-dir &&
 325        test_ln_s_add ../../../ dir/subdir/out-of-repo-link-dir-trailing &&
 326        test_ln_s_add ../parent-dir-link dir/subdir/parent-dir-link-to-link &&
 327        echo_without_newline "$hello_content" >dir/subdir/ind2 &&
 328        echo_without_newline "$hello_content" >dir/ind1 &&
 329        test_ln_s_add dir dirlink &&
 330        test_ln_s_add dir/subdir subdirlink &&
 331        test_ln_s_add subdir/ind2 dir/link-to-child &&
 332        test_ln_s_add dir/link-to-child link-to-down-link &&
 333        test_ln_s_add dir/.. up-down &&
 334        test_ln_s_add dir/../ up-down-trailing &&
 335        test_ln_s_add dir/../morx up-down-file &&
 336        test_ln_s_add dir/../../morx up-up-down-file &&
 337        test_ln_s_add subdirlink/../../morx up-two-down-file &&
 338        test_ln_s_add loop1 loop2 &&
 339        test_ln_s_add loop2 loop1 &&
 340        git add morx dir/subdir/ind2 dir/ind1 &&
 341        git commit -am "test" &&
 342        echo $hello_sha1 blob $hello_size >found
 343'
 344
 345test_expect_success 'git cat-file --batch-check --follow-symlinks works for non-links' '
 346        echo HEAD:morx | git cat-file --batch-check --follow-symlinks >actual &&
 347        test_cmp found actual &&
 348        echo HEAD:nope missing >expect &&
 349        echo HEAD:nope | git cat-file --batch-check --follow-symlinks >actual &&
 350        test_cmp expect actual
 351'
 352
 353test_expect_success 'git cat-file --batch-check --follow-symlinks works for in-repo, same-dir links' '
 354        echo HEAD:same-dir-link | git cat-file --batch-check --follow-symlinks >actual &&
 355        test_cmp found actual
 356'
 357
 358test_expect_success 'git cat-file --batch-check --follow-symlinks works for in-repo, links to dirs' '
 359        echo HEAD:link-to-dir/ind1 | git cat-file --batch-check --follow-symlinks >actual &&
 360        test_cmp found actual
 361'
 362
 363
 364test_expect_success 'git cat-file --batch-check --follow-symlinks works for broken in-repo, same-dir links' '
 365        echo dangling 25 >expect &&
 366        echo HEAD:broken-same-dir-link >>expect &&
 367        echo HEAD:broken-same-dir-link | git cat-file --batch-check --follow-symlinks >actual &&
 368        test_cmp expect actual
 369'
 370
 371test_expect_success 'git cat-file --batch-check --follow-symlinks works for same-dir links-to-links' '
 372        echo HEAD:link-to-link | git cat-file --batch-check --follow-symlinks >actual &&
 373        test_cmp found actual
 374'
 375
 376test_expect_success 'git cat-file --batch-check --follow-symlinks works for parent-dir links' '
 377        echo HEAD:dir/parent-dir-link | git cat-file --batch-check --follow-symlinks >actual &&
 378        test_cmp found actual &&
 379        echo notdir 29 >expect &&
 380        echo HEAD:dir/parent-dir-link/nope >>expect &&
 381        echo HEAD:dir/parent-dir-link/nope | git cat-file --batch-check --follow-symlinks >actual &&
 382        test_cmp expect actual
 383'
 384
 385test_expect_success 'git cat-file --batch-check --follow-symlinks works for .. links' '
 386        echo dangling 22 >expect &&
 387        echo HEAD:dir/link-dir/nope >>expect &&
 388        echo HEAD:dir/link-dir/nope | git cat-file --batch-check --follow-symlinks >actual &&
 389        test_cmp expect actual &&
 390        echo HEAD:dir/link-dir/morx | git cat-file --batch-check --follow-symlinks >actual &&
 391        test_cmp found actual &&
 392        echo dangling 27 >expect &&
 393        echo HEAD:dir/broken-link-in-dir >>expect &&
 394        echo HEAD:dir/broken-link-in-dir | git cat-file --batch-check --follow-symlinks >actual &&
 395        test_cmp expect actual
 396'
 397
 398test_expect_success 'git cat-file --batch-check --follow-symlinks works for ../.. links' '
 399        echo notdir 41 >expect &&
 400        echo HEAD:dir/subdir/grandparent-dir-link/nope >>expect &&
 401        echo HEAD:dir/subdir/grandparent-dir-link/nope | git cat-file --batch-check --follow-symlinks >actual &&
 402        test_cmp expect actual &&
 403        echo HEAD:dir/subdir/grandparent-dir-link | git cat-file --batch-check --follow-symlinks >actual &&
 404        test_cmp found actual &&
 405        echo HEAD:dir/subdir/parent-dir-link-to-link | git cat-file --batch-check --follow-symlinks >actual &&
 406        test_cmp found actual
 407'
 408
 409test_expect_success 'git cat-file --batch-check --follow-symlinks works for dir/ links' '
 410        echo dangling 17 >expect &&
 411        echo HEAD:dirlink/morx >>expect &&
 412        echo HEAD:dirlink/morx | git cat-file --batch-check --follow-symlinks >actual &&
 413        test_cmp expect actual &&
 414        echo $hello_sha1 blob $hello_size >expect &&
 415        echo HEAD:dirlink/ind1 | git cat-file --batch-check --follow-symlinks >actual &&
 416        test_cmp expect actual
 417'
 418
 419test_expect_success 'git cat-file --batch-check --follow-symlinks works for dir/subdir links' '
 420        echo dangling 20 >expect &&
 421        echo HEAD:subdirlink/morx >>expect &&
 422        echo HEAD:subdirlink/morx | git cat-file --batch-check --follow-symlinks >actual &&
 423        test_cmp expect actual &&
 424        echo HEAD:subdirlink/ind2 | git cat-file --batch-check --follow-symlinks >actual &&
 425        test_cmp found actual
 426'
 427
 428test_expect_success 'git cat-file --batch-check --follow-symlinks works for dir ->subdir links' '
 429        echo notdir 27 >expect &&
 430        echo HEAD:dir/link-to-child/morx >>expect &&
 431        echo HEAD:dir/link-to-child/morx | git cat-file --batch-check --follow-symlinks >actual &&
 432        test_cmp expect actual &&
 433        echo HEAD:dir/link-to-child | git cat-file --batch-check --follow-symlinks >actual &&
 434        test_cmp found actual &&
 435        echo HEAD:link-to-down-link | git cat-file --batch-check --follow-symlinks >actual &&
 436        test_cmp found actual
 437'
 438
 439test_expect_success 'git cat-file --batch-check --follow-symlinks works for out-of-repo symlinks' '
 440        echo symlink 8 >expect &&
 441        echo ../fleem >>expect &&
 442        echo HEAD:out-of-repo-link | git cat-file --batch-check --follow-symlinks >actual &&
 443        test_cmp expect actual &&
 444        echo symlink 2 >expect &&
 445        echo .. >>expect &&
 446        echo HEAD:out-of-repo-link-dir | git cat-file --batch-check --follow-symlinks >actual &&
 447        test_cmp expect actual
 448'
 449
 450test_expect_success 'git cat-file --batch-check --follow-symlinks works for out-of-repo symlinks in dirs' '
 451        echo symlink 9 >expect &&
 452        echo ../escape >>expect &&
 453        echo HEAD:dir/out-of-repo-link | git cat-file --batch-check --follow-symlinks >actual &&
 454        test_cmp expect actual &&
 455        echo symlink 2 >expect &&
 456        echo .. >>expect &&
 457        echo HEAD:dir/out-of-repo-link-dir | git cat-file --batch-check --follow-symlinks >actual &&
 458        test_cmp expect actual
 459'
 460
 461test_expect_success 'git cat-file --batch-check --follow-symlinks works for out-of-repo symlinks in subdirs' '
 462        echo symlink 15 >expect &&
 463        echo ../great-escape >>expect &&
 464        echo HEAD:dir/subdir/out-of-repo-link | git cat-file --batch-check --follow-symlinks >actual &&
 465        test_cmp expect actual &&
 466        echo symlink 2 >expect &&
 467        echo .. >>expect &&
 468        echo HEAD:dir/subdir/out-of-repo-link-dir | git cat-file --batch-check --follow-symlinks >actual &&
 469        test_cmp expect actual &&
 470        echo symlink 3 >expect &&
 471        echo ../ >>expect &&
 472        echo HEAD:dir/subdir/out-of-repo-link-dir-trailing | git cat-file --batch-check --follow-symlinks >actual &&
 473        test_cmp expect actual
 474'
 475
 476test_expect_success 'git cat-file --batch-check --follow-symlinks works for symlinks with internal ..' '
 477        echo HEAD: | git cat-file --batch-check >expect &&
 478        echo HEAD:up-down | git cat-file --batch-check --follow-symlinks >actual &&
 479        test_cmp expect actual &&
 480        echo HEAD:up-down-trailing | git cat-file --batch-check --follow-symlinks >actual &&
 481        test_cmp expect actual &&
 482        echo HEAD:up-down-file | git cat-file --batch-check --follow-symlinks >actual &&
 483        test_cmp found actual &&
 484        echo symlink 7 >expect &&
 485        echo ../morx >>expect &&
 486        echo HEAD:up-up-down-file | git cat-file --batch-check --follow-symlinks >actual &&
 487        test_cmp expect actual &&
 488        echo HEAD:up-two-down-file | git cat-file --batch-check --follow-symlinks >actual &&
 489        test_cmp found actual
 490'
 491
 492test_expect_success 'git cat-file --batch-check --follow-symlink breaks loops' '
 493        echo loop 10 >expect &&
 494        echo HEAD:loop1 >>expect &&
 495        echo HEAD:loop1 | git cat-file --batch-check --follow-symlinks >actual &&
 496        test_cmp expect actual
 497'
 498
 499test_expect_success 'git cat-file --batch --follow-symlink returns correct sha and mode' '
 500        echo HEAD:morx | git cat-file --batch >expect &&
 501        echo HEAD:morx | git cat-file --batch --follow-symlinks >actual &&
 502        test_cmp expect actual
 503'
 504test_done