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