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