t / t9301-fast-import-notes.shon commit Merge branch 'mm/shortopt-detached' (e40b34b)
   1#!/bin/sh
   2#
   3# Copyright (c) 2009 Johan Herland
   4#
   5
   6test_description='test git fast-import of notes objects'
   7. ./test-lib.sh
   8
   9
  10test_tick
  11cat >input <<INPUT_END
  12commit refs/heads/master
  13committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
  14data <<COMMIT
  15first commit
  16COMMIT
  17
  18M 644 inline foo
  19data <<EOF
  20file foo in first commit
  21EOF
  22
  23M 755 inline bar
  24data <<EOF
  25file bar in first commit
  26EOF
  27
  28M 644 inline baz/xyzzy
  29data <<EOF
  30file baz/xyzzy in first commit
  31EOF
  32
  33commit refs/heads/master
  34committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
  35data <<COMMIT
  36second commit
  37COMMIT
  38
  39M 644 inline foo
  40data <<EOF
  41file foo in second commit
  42EOF
  43
  44M 755 inline baz/xyzzy
  45data <<EOF
  46file baz/xyzzy in second commit
  47EOF
  48
  49commit refs/heads/master
  50committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
  51data <<COMMIT
  52third commit
  53COMMIT
  54
  55M 644 inline foo
  56data <<EOF
  57file foo in third commit
  58EOF
  59
  60commit refs/heads/master
  61committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
  62data <<COMMIT
  63fourth commit
  64COMMIT
  65
  66M 755 inline bar
  67data <<EOF
  68file bar in fourth commit
  69EOF
  70
  71INPUT_END
  72
  73test_expect_success 'set up master branch' '
  74
  75        git fast-import <input &&
  76        git whatchanged master
  77'
  78
  79commit4=$(git rev-parse refs/heads/master)
  80commit3=$(git rev-parse "$commit4^")
  81commit2=$(git rev-parse "$commit4~2")
  82commit1=$(git rev-parse "$commit4~3")
  83
  84test_tick
  85cat >input <<INPUT_END
  86commit refs/notes/test
  87committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
  88data <<COMMIT
  89first notes commit
  90COMMIT
  91
  92M 644 inline $commit1
  93data <<EOF
  94first note for first commit
  95EOF
  96
  97M 755 inline $commit2
  98data <<EOF
  99first note for second commit
 100EOF
 101
 102INPUT_END
 103
 104cat >expect <<EXPECT_END
 105    fourth commit
 106    third commit
 107    second commit
 108    first note for second commit
 109    first commit
 110    first note for first commit
 111EXPECT_END
 112
 113test_expect_success 'add notes with simple M command' '
 114
 115        git fast-import <input &&
 116        GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
 117        test_cmp expect actual
 118
 119'
 120
 121test_tick
 122cat >input <<INPUT_END
 123commit refs/notes/test
 124committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 125data <<COMMIT
 126second notes commit
 127COMMIT
 128
 129from refs/notes/test^0
 130N inline $commit3
 131data <<EOF
 132first note for third commit
 133EOF
 134
 135N inline $commit4
 136data <<EOF
 137first note for fourth commit
 138EOF
 139
 140INPUT_END
 141
 142cat >expect <<EXPECT_END
 143    fourth commit
 144    first note for fourth commit
 145    third commit
 146    first note for third commit
 147    second commit
 148    first note for second commit
 149    first commit
 150    first note for first commit
 151EXPECT_END
 152
 153test_expect_success 'add notes with simple N command' '
 154
 155        git fast-import <input &&
 156        GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
 157        test_cmp expect actual
 158
 159'
 160
 161test_tick
 162cat >input <<INPUT_END
 163commit refs/notes/test
 164committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 165data <<COMMIT
 166third notes commit
 167COMMIT
 168
 169from refs/notes/test^0
 170N inline $commit1
 171data <<EOF
 172second note for first commit
 173EOF
 174
 175N inline $commit2
 176data <<EOF
 177second note for second commit
 178EOF
 179
 180N inline $commit3
 181data <<EOF
 182second note for third commit
 183EOF
 184
 185N inline $commit4
 186data <<EOF
 187second note for fourth commit
 188EOF
 189
 190INPUT_END
 191
 192cat >expect <<EXPECT_END
 193    fourth commit
 194    second note for fourth commit
 195    third commit
 196    second note for third commit
 197    second commit
 198    second note for second commit
 199    first commit
 200    second note for first commit
 201EXPECT_END
 202
 203test_expect_success 'update existing notes with N command' '
 204
 205        git fast-import <input &&
 206        GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
 207        test_cmp expect actual
 208
 209'
 210
 211test_tick
 212cat >input <<INPUT_END
 213commit refs/notes/test
 214committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 215data <<COMMIT
 216fourth notes commit
 217COMMIT
 218
 219from refs/notes/test^0
 220M 644 inline $(echo "$commit3" | sed "s|^..|&/|")
 221data <<EOF
 222prefix of note for third commit
 223EOF
 224
 225M 644 inline $(echo "$commit4" | sed "s|^..|&/|")
 226data <<EOF
 227prefix of note for fourth commit
 228EOF
 229
 230M 644 inline $(echo "$commit4" | sed "s|^\(..\)\(..\)|\1/\2/|")
 231data <<EOF
 232pre-prefix of note for fourth commit
 233EOF
 234
 235N inline $commit1
 236data <<EOF
 237third note for first commit
 238EOF
 239
 240N inline $commit2
 241data <<EOF
 242third note for second commit
 243EOF
 244
 245N inline $commit3
 246data <<EOF
 247third note for third commit
 248EOF
 249
 250N inline $commit4
 251data <<EOF
 252third note for fourth commit
 253EOF
 254
 255
 256INPUT_END
 257
 258cat >expect <<EXPECT_END
 259    fourth commit
 260    pre-prefix of note for fourth commit
 261    prefix of note for fourth commit
 262    third note for fourth commit
 263    third commit
 264    prefix of note for third commit
 265    third note for third commit
 266    second commit
 267    third note for second commit
 268    first commit
 269    third note for first commit
 270EXPECT_END
 271
 272test_expect_success 'add concatentation notes with M command' '
 273
 274        git fast-import <input &&
 275        GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
 276        test_cmp expect actual
 277
 278'
 279
 280test_tick
 281cat >input <<INPUT_END
 282commit refs/notes/test
 283committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 284data <<COMMIT
 285fifth notes commit
 286COMMIT
 287
 288from refs/notes/test^0
 289deleteall
 290
 291INPUT_END
 292
 293cat >expect <<EXPECT_END
 294    fourth commit
 295    third commit
 296    second commit
 297    first commit
 298EXPECT_END
 299
 300test_expect_success 'verify that deleteall also removes notes' '
 301
 302        git fast-import <input &&
 303        GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
 304        test_cmp expect actual
 305
 306'
 307
 308test_tick
 309cat >input <<INPUT_END
 310commit refs/notes/test
 311committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 312data <<COMMIT
 313sixth notes commit
 314COMMIT
 315
 316from refs/notes/test^0
 317M 644 inline $commit1
 318data <<EOF
 319third note for first commit
 320EOF
 321
 322M 644 inline $commit3
 323data <<EOF
 324third note for third commit
 325EOF
 326
 327N inline $commit1
 328data <<EOF
 329fourth note for first commit
 330EOF
 331
 332N inline $commit3
 333data <<EOF
 334fourth note for third commit
 335EOF
 336
 337INPUT_END
 338
 339cat >expect <<EXPECT_END
 340    fourth commit
 341    third commit
 342    fourth note for third commit
 343    second commit
 344    first commit
 345    fourth note for first commit
 346EXPECT_END
 347
 348test_expect_success 'verify that later N commands override earlier M commands' '
 349
 350        git fast-import <input &&
 351        GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
 352        test_cmp expect actual
 353
 354'
 355
 356# Write fast-import commands to create the given number of commits
 357fast_import_commits () {
 358        my_ref=$1
 359        my_num_commits=$2
 360        my_append_to_file=$3
 361        my_i=0
 362        while test $my_i -lt $my_num_commits
 363        do
 364                my_i=$(($my_i + 1))
 365                test_tick
 366                cat >>"$my_append_to_file" <<INPUT_END
 367commit $my_ref
 368mark :$my_i
 369committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 370data <<COMMIT
 371commit #$my_i
 372COMMIT
 373
 374M 644 inline file
 375data <<EOF
 376file contents in commit #$my_i
 377EOF
 378
 379INPUT_END
 380        done
 381}
 382
 383# Write fast-import commands to create the given number of notes annotating
 384# the commits created by fast_import_commits()
 385fast_import_notes () {
 386        my_notes_ref=$1
 387        my_num_commits=$2
 388        my_append_to_file=$3
 389        my_note_append=$4
 390        test_tick
 391        cat >>"$my_append_to_file" <<INPUT_END
 392commit $my_notes_ref
 393committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 394data <<COMMIT
 395committing $my_num_commits notes
 396COMMIT
 397
 398INPUT_END
 399
 400        my_i=0
 401        while test $my_i -lt $my_num_commits
 402        do
 403                my_i=$(($my_i + 1))
 404                cat >>"$my_append_to_file" <<INPUT_END
 405N inline :$my_i
 406data <<EOF
 407note for commit #$my_i$my_note_append
 408EOF
 409
 410INPUT_END
 411        done
 412}
 413
 414
 415rm input expect
 416num_commits=400
 417# Create lots of commits
 418fast_import_commits "refs/heads/many_commits" $num_commits input
 419# Create one note per above commit
 420fast_import_notes "refs/notes/many_notes" $num_commits input
 421# Add a couple of non-notes as well
 422test_tick
 423cat >>input <<INPUT_END
 424commit refs/notes/many_notes
 425committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 426data <<COMMIT
 427committing some non-notes to the notes tree
 428COMMIT
 429
 430M 755 inline foobar/non-note.txt
 431data <<EOF
 432This is not a note, but rather a regular file residing in a notes tree
 433EOF
 434
 435M 644 inline deadbeef
 436data <<EOF
 437Non-note file
 438EOF
 439
 440M 644 inline de/adbeef
 441data <<EOF
 442Another non-note file
 443EOF
 444
 445INPUT_END
 446# Finally create the expected output from all these notes and commits
 447i=$num_commits
 448while test $i -gt 0
 449do
 450        cat >>expect <<EXPECT_END
 451    commit #$i
 452    note for commit #$i
 453EXPECT_END
 454        i=$(($i - 1))
 455done
 456
 457test_expect_success 'add lots of commits and notes' '
 458
 459        git fast-import <input &&
 460        GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
 461            grep "^    " > actual &&
 462        test_cmp expect actual
 463
 464'
 465
 466test_expect_success 'verify that lots of notes trigger a fanout scheme' '
 467
 468        # None of the entries in the top-level notes tree should be a full SHA1
 469        git ls-tree --name-only refs/notes/many_notes |
 470        while read path
 471        do
 472                if test $(expr length "$path") -ge 40
 473                then
 474                        return 1
 475                fi
 476        done
 477
 478'
 479
 480cat >>expect_non-note1 << EOF
 481This is not a note, but rather a regular file residing in a notes tree
 482EOF
 483
 484cat >>expect_non-note2 << EOF
 485Non-note file
 486EOF
 487
 488cat >>expect_non-note3 << EOF
 489Another non-note file
 490EOF
 491
 492test_expect_success 'verify that non-notes are untouched by a fanout change' '
 493
 494        git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
 495        test_cmp expect_non-note1 actual &&
 496        git cat-file -p refs/notes/many_notes:deadbeef > actual &&
 497        test_cmp expect_non-note2 actual &&
 498        git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
 499        test_cmp expect_non-note3 actual
 500
 501'
 502remaining_notes=10
 503test_tick
 504cat >>input <<INPUT_END
 505commit refs/notes/many_notes
 506committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 507data <<COMMIT
 508removing all notes but $remaining_notes
 509COMMIT
 510from refs/notes/many_notes^0
 511INPUT_END
 512
 513i=$remaining_notes
 514while test $i -lt $num_commits
 515do
 516        i=$(($i + 1))
 517        cat >>input <<INPUT_END
 518N 0000000000000000000000000000000000000000 :$i
 519INPUT_END
 520done
 521
 522i=$num_commits
 523rm expect
 524while test $i -gt 0
 525do
 526        cat >>expect <<EXPECT_END
 527    commit #$i
 528EXPECT_END
 529        if test $i -le $remaining_notes
 530        then
 531                cat >>expect <<EXPECT_END
 532    note for commit #$i
 533EXPECT_END
 534        fi
 535        i=$(($i - 1))
 536done
 537
 538test_expect_success 'remove lots of notes' '
 539
 540        git fast-import <input &&
 541        GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
 542            grep "^    " > actual &&
 543        test_cmp expect actual
 544
 545'
 546
 547test_expect_success 'verify that removing notes trigger fanout consolidation' '
 548
 549        # All entries in the top-level notes tree should be a full SHA1
 550        git ls-tree --name-only -r refs/notes/many_notes |
 551        while read path
 552        do
 553                # Explicitly ignore the non-note paths
 554                test "$path" = "foobar/non-note.txt" && continue
 555                test "$path" = "deadbeef" && continue
 556                test "$path" = "de/adbeef" && continue
 557
 558                if test $(expr length "$path") -ne 40
 559                then
 560                        return 1
 561                fi
 562        done
 563
 564'
 565
 566test_expect_success 'verify that non-notes are untouched by a fanout change' '
 567
 568        git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
 569        test_cmp expect_non-note1 actual &&
 570        git cat-file -p refs/notes/many_notes:deadbeef > actual &&
 571        test_cmp expect_non-note2 actual &&
 572        git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
 573        test_cmp expect_non-note3 actual
 574
 575'
 576
 577
 578rm input expect
 579num_notes_refs=10
 580num_commits=16
 581some_commits=8
 582# Create commits
 583fast_import_commits "refs/heads/more_commits" $num_commits input
 584# Create one note per above commit per notes ref
 585i=0
 586while test $i -lt $num_notes_refs
 587do
 588        i=$(($i + 1))
 589        fast_import_notes "refs/notes/more_notes_$i" $num_commits input
 590done
 591# Trigger branch reloading in git-fast-import by repeating the note creation
 592i=0
 593while test $i -lt $num_notes_refs
 594do
 595        i=$(($i + 1))
 596        fast_import_notes "refs/notes/more_notes_$i" $some_commits input " (2)"
 597done
 598# Finally create the expected output from the notes in refs/notes/more_notes_1
 599i=$num_commits
 600while test $i -gt 0
 601do
 602        note_data="note for commit #$i"
 603        if test $i -le $some_commits
 604        then
 605                note_data="$note_data (2)"
 606        fi
 607        cat >>expect <<EXPECT_END
 608    commit #$i
 609    $note_data
 610EXPECT_END
 611        i=$(($i - 1))
 612done
 613
 614test_expect_success "add notes to $num_commits commits in each of $num_notes_refs refs" '
 615
 616        git fast-import --active-branches=5 <input &&
 617        GIT_NOTES_REF=refs/notes/more_notes_1 git log refs/heads/more_commits |
 618            grep "^    " > actual &&
 619        test_cmp expect actual
 620
 621'
 622
 623test_done