t / t9301-fast-import-notes.shon commit Merge branch 'maint' (2cd900f)
   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
 258whitespace="    "
 259
 260cat >expect <<EXPECT_END
 261    fourth commit
 262    pre-prefix of note for fourth commit
 263$whitespace
 264    prefix of note for fourth commit
 265$whitespace
 266    third note for fourth commit
 267    third commit
 268    prefix of note for third commit
 269$whitespace
 270    third note for third commit
 271    second commit
 272    third note for second commit
 273    first commit
 274    third note for first commit
 275EXPECT_END
 276
 277test_expect_success 'add concatentation notes with M command' '
 278
 279        git fast-import <input &&
 280        GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
 281        test_cmp expect actual
 282
 283'
 284
 285test_tick
 286cat >input <<INPUT_END
 287commit refs/notes/test
 288committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 289data <<COMMIT
 290fifth notes commit
 291COMMIT
 292
 293from refs/notes/test^0
 294deleteall
 295
 296INPUT_END
 297
 298cat >expect <<EXPECT_END
 299    fourth commit
 300    third commit
 301    second commit
 302    first commit
 303EXPECT_END
 304
 305test_expect_success 'verify that deleteall also removes notes' '
 306
 307        git fast-import <input &&
 308        GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
 309        test_cmp expect actual
 310
 311'
 312
 313test_tick
 314cat >input <<INPUT_END
 315commit refs/notes/test
 316committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 317data <<COMMIT
 318sixth notes commit
 319COMMIT
 320
 321from refs/notes/test^0
 322M 644 inline $commit1
 323data <<EOF
 324third note for first commit
 325EOF
 326
 327M 644 inline $commit3
 328data <<EOF
 329third note for third commit
 330EOF
 331
 332N inline $commit1
 333data <<EOF
 334fourth note for first commit
 335EOF
 336
 337N inline $commit3
 338data <<EOF
 339fourth note for third commit
 340EOF
 341
 342INPUT_END
 343
 344cat >expect <<EXPECT_END
 345    fourth commit
 346    third commit
 347    fourth note for third commit
 348    second commit
 349    first commit
 350    fourth note for first commit
 351EXPECT_END
 352
 353test_expect_success 'verify that later N commands override earlier M commands' '
 354
 355        git fast-import <input &&
 356        GIT_NOTES_REF=refs/notes/test git log | grep "^    " > actual &&
 357        test_cmp expect actual
 358
 359'
 360
 361# Write fast-import commands to create the given number of commits
 362fast_import_commits () {
 363        my_ref=$1
 364        my_num_commits=$2
 365        my_append_to_file=$3
 366        my_i=0
 367        while test $my_i -lt $my_num_commits
 368        do
 369                my_i=$(($my_i + 1))
 370                test_tick
 371                cat >>"$my_append_to_file" <<INPUT_END
 372commit $my_ref
 373mark :$my_i
 374committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 375data <<COMMIT
 376commit #$my_i
 377COMMIT
 378
 379M 644 inline file
 380data <<EOF
 381file contents in commit #$my_i
 382EOF
 383
 384INPUT_END
 385        done
 386}
 387
 388# Write fast-import commands to create the given number of notes annotating
 389# the commits created by fast_import_commits()
 390fast_import_notes () {
 391        my_notes_ref=$1
 392        my_num_commits=$2
 393        my_append_to_file=$3
 394        my_note_append=$4
 395        test_tick
 396        cat >>"$my_append_to_file" <<INPUT_END
 397commit $my_notes_ref
 398committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 399data <<COMMIT
 400committing $my_num_commits notes
 401COMMIT
 402
 403INPUT_END
 404
 405        my_i=0
 406        while test $my_i -lt $my_num_commits
 407        do
 408                my_i=$(($my_i + 1))
 409                cat >>"$my_append_to_file" <<INPUT_END
 410N inline :$my_i
 411data <<EOF
 412note for commit #$my_i$my_note_append
 413EOF
 414
 415INPUT_END
 416        done
 417}
 418
 419
 420rm input expect
 421num_commits=400
 422# Create lots of commits
 423fast_import_commits "refs/heads/many_commits" $num_commits input
 424# Create one note per above commit
 425fast_import_notes "refs/notes/many_notes" $num_commits input
 426# Add a couple of non-notes as well
 427test_tick
 428cat >>input <<INPUT_END
 429commit refs/notes/many_notes
 430committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 431data <<COMMIT
 432committing some non-notes to the notes tree
 433COMMIT
 434
 435M 755 inline foobar/non-note.txt
 436data <<EOF
 437This is not a note, but rather a regular file residing in a notes tree
 438EOF
 439
 440M 644 inline deadbeef
 441data <<EOF
 442Non-note file
 443EOF
 444
 445M 644 inline de/adbeef
 446data <<EOF
 447Another non-note file
 448EOF
 449
 450INPUT_END
 451# Finally create the expected output from all these notes and commits
 452i=$num_commits
 453while test $i -gt 0
 454do
 455        cat >>expect <<EXPECT_END
 456    commit #$i
 457    note for commit #$i
 458EXPECT_END
 459        i=$(($i - 1))
 460done
 461
 462test_expect_success 'add lots of commits and notes' '
 463
 464        git fast-import <input &&
 465        GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
 466            grep "^    " > actual &&
 467        test_cmp expect actual
 468
 469'
 470
 471test_expect_success 'verify that lots of notes trigger a fanout scheme' '
 472
 473        # None of the entries in the top-level notes tree should be a full SHA1
 474        git ls-tree --name-only refs/notes/many_notes |
 475        while read path
 476        do
 477                if test $(expr length "$path") -ge 40
 478                then
 479                        return 1
 480                fi
 481        done
 482
 483'
 484
 485cat >>expect_non-note1 << EOF
 486This is not a note, but rather a regular file residing in a notes tree
 487EOF
 488
 489cat >>expect_non-note2 << EOF
 490Non-note file
 491EOF
 492
 493cat >>expect_non-note3 << EOF
 494Another non-note file
 495EOF
 496
 497test_expect_success 'verify that non-notes are untouched by a fanout change' '
 498
 499        git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
 500        test_cmp expect_non-note1 actual &&
 501        git cat-file -p refs/notes/many_notes:deadbeef > actual &&
 502        test_cmp expect_non-note2 actual &&
 503        git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
 504        test_cmp expect_non-note3 actual
 505
 506'
 507remaining_notes=10
 508test_tick
 509cat >>input <<INPUT_END
 510commit refs/notes/many_notes
 511committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 512data <<COMMIT
 513removing all notes but $remaining_notes
 514COMMIT
 515from refs/notes/many_notes^0
 516INPUT_END
 517
 518i=$remaining_notes
 519while test $i -lt $num_commits
 520do
 521        i=$(($i + 1))
 522        cat >>input <<INPUT_END
 523N 0000000000000000000000000000000000000000 :$i
 524INPUT_END
 525done
 526
 527i=$num_commits
 528rm expect
 529while test $i -gt 0
 530do
 531        cat >>expect <<EXPECT_END
 532    commit #$i
 533EXPECT_END
 534        if test $i -le $remaining_notes
 535        then
 536                cat >>expect <<EXPECT_END
 537    note for commit #$i
 538EXPECT_END
 539        fi
 540        i=$(($i - 1))
 541done
 542
 543test_expect_success 'remove lots of notes' '
 544
 545        git fast-import <input &&
 546        GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
 547            grep "^    " > actual &&
 548        test_cmp expect actual
 549
 550'
 551
 552test_expect_success 'verify that removing notes trigger fanout consolidation' '
 553
 554        # All entries in the top-level notes tree should be a full SHA1
 555        git ls-tree --name-only -r refs/notes/many_notes |
 556        while read path
 557        do
 558                # Explicitly ignore the non-note paths
 559                test "$path" = "foobar/non-note.txt" && continue
 560                test "$path" = "deadbeef" && continue
 561                test "$path" = "de/adbeef" && continue
 562
 563                if test $(expr length "$path") -ne 40
 564                then
 565                        return 1
 566                fi
 567        done
 568
 569'
 570
 571test_expect_success 'verify that non-notes are untouched by a fanout change' '
 572
 573        git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
 574        test_cmp expect_non-note1 actual &&
 575        git cat-file -p refs/notes/many_notes:deadbeef > actual &&
 576        test_cmp expect_non-note2 actual &&
 577        git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
 578        test_cmp expect_non-note3 actual
 579
 580'
 581
 582
 583rm input expect
 584num_notes_refs=10
 585num_commits=16
 586some_commits=8
 587# Create commits
 588fast_import_commits "refs/heads/more_commits" $num_commits input
 589# Create one note per above commit per notes ref
 590i=0
 591while test $i -lt $num_notes_refs
 592do
 593        i=$(($i + 1))
 594        fast_import_notes "refs/notes/more_notes_$i" $num_commits input
 595done
 596# Trigger branch reloading in git-fast-import by repeating the note creation
 597i=0
 598while test $i -lt $num_notes_refs
 599do
 600        i=$(($i + 1))
 601        fast_import_notes "refs/notes/more_notes_$i" $some_commits input " (2)"
 602done
 603# Finally create the expected output from the notes in refs/notes/more_notes_1
 604i=$num_commits
 605while test $i -gt 0
 606do
 607        note_data="note for commit #$i"
 608        if test $i -le $some_commits
 609        then
 610                note_data="$note_data (2)"
 611        fi
 612        cat >>expect <<EXPECT_END
 613    commit #$i
 614    $note_data
 615EXPECT_END
 616        i=$(($i - 1))
 617done
 618
 619test_expect_success "add notes to $num_commits commits in each of $num_notes_refs refs" '
 620
 621        git fast-import --active-branches=5 <input &&
 622        GIT_NOTES_REF=refs/notes/more_notes_1 git log refs/heads/more_commits |
 623            grep "^    " > actual &&
 624        test_cmp expect actual
 625
 626'
 627
 628test_done