t / t9301-fast-import-notes.shon commit wt-status.c: set commitable bit if there is a meaningful merge. (8dc874b)
   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'
 508
 509# Change the notes for the three top commits
 510test_tick
 511cat >input <<INPUT_END
 512commit refs/notes/many_notes
 513committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 514data <<COMMIT
 515changing notes for the top three commits
 516COMMIT
 517from refs/notes/many_notes^0
 518INPUT_END
 519
 520rm expect
 521i=$num_commits
 522j=0
 523while test $j -lt 3
 524do
 525        cat >>input <<INPUT_END
 526N inline refs/heads/many_commits~$j
 527data <<EOF
 528changed note for commit #$i
 529EOF
 530INPUT_END
 531        cat >>expect <<EXPECT_END
 532    commit #$i
 533    changed note for commit #$i
 534EXPECT_END
 535        i=$(($i - 1))
 536        j=$(($j + 1))
 537done
 538
 539test_expect_success 'change a few existing notes' '
 540
 541        git fast-import <input &&
 542        GIT_NOTES_REF=refs/notes/many_notes git log -n3 refs/heads/many_commits |
 543            grep "^    " > actual &&
 544        test_cmp expect actual
 545
 546'
 547
 548test_expect_success 'verify that changing notes respect existing fanout' '
 549
 550        # None of the entries in the top-level notes tree should be a full SHA1
 551        git ls-tree --name-only refs/notes/many_notes |
 552        while read path
 553        do
 554                if test $(expr length "$path") -ge 40
 555                then
 556                        return 1
 557                fi
 558        done
 559
 560'
 561
 562remaining_notes=10
 563test_tick
 564cat >input <<INPUT_END
 565commit refs/notes/many_notes
 566committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 567data <<COMMIT
 568removing all notes but $remaining_notes
 569COMMIT
 570from refs/notes/many_notes^0
 571INPUT_END
 572
 573i=$(($num_commits - $remaining_notes))
 574for sha1 in $(git rev-list -n $i refs/heads/many_commits)
 575do
 576        cat >>input <<INPUT_END
 577N 0000000000000000000000000000000000000000 $sha1
 578INPUT_END
 579done
 580
 581i=$num_commits
 582rm expect
 583while test $i -gt 0
 584do
 585        cat >>expect <<EXPECT_END
 586    commit #$i
 587EXPECT_END
 588        if test $i -le $remaining_notes
 589        then
 590                cat >>expect <<EXPECT_END
 591    note for commit #$i
 592EXPECT_END
 593        fi
 594        i=$(($i - 1))
 595done
 596
 597test_expect_success 'remove lots of notes' '
 598
 599        git fast-import <input &&
 600        GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits |
 601            grep "^    " > actual &&
 602        test_cmp expect actual
 603
 604'
 605
 606test_expect_success 'verify that removing notes trigger fanout consolidation' '
 607
 608        # All entries in the top-level notes tree should be a full SHA1
 609        git ls-tree --name-only -r refs/notes/many_notes |
 610        while read path
 611        do
 612                # Explicitly ignore the non-note paths
 613                test "$path" = "foobar/non-note.txt" && continue
 614                test "$path" = "deadbeef" && continue
 615                test "$path" = "de/adbeef" && continue
 616
 617                if test $(expr length "$path") -ne 40
 618                then
 619                        return 1
 620                fi
 621        done
 622
 623'
 624
 625test_expect_success 'verify that non-notes are untouched by a fanout change' '
 626
 627        git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual &&
 628        test_cmp expect_non-note1 actual &&
 629        git cat-file -p refs/notes/many_notes:deadbeef > actual &&
 630        test_cmp expect_non-note2 actual &&
 631        git cat-file -p refs/notes/many_notes:de/adbeef > actual &&
 632        test_cmp expect_non-note3 actual
 633
 634'
 635
 636
 637rm input expect
 638num_notes_refs=10
 639num_commits=16
 640some_commits=8
 641# Create commits
 642fast_import_commits "refs/heads/more_commits" $num_commits input
 643# Create one note per above commit per notes ref
 644i=0
 645while test $i -lt $num_notes_refs
 646do
 647        i=$(($i + 1))
 648        fast_import_notes "refs/notes/more_notes_$i" $num_commits input
 649done
 650# Trigger branch reloading in git-fast-import by repeating the note creation
 651i=0
 652while test $i -lt $num_notes_refs
 653do
 654        i=$(($i + 1))
 655        fast_import_notes "refs/notes/more_notes_$i" $some_commits input " (2)"
 656done
 657# Finally create the expected output from the notes in refs/notes/more_notes_1
 658i=$num_commits
 659while test $i -gt 0
 660do
 661        note_data="note for commit #$i"
 662        if test $i -le $some_commits
 663        then
 664                note_data="$note_data (2)"
 665        fi
 666        cat >>expect <<EXPECT_END
 667    commit #$i
 668    $note_data
 669EXPECT_END
 670        i=$(($i - 1))
 671done
 672
 673test_expect_success "add notes to $num_commits commits in each of $num_notes_refs refs" '
 674
 675        git fast-import --active-branches=5 <input &&
 676        GIT_NOTES_REF=refs/notes/more_notes_1 git log refs/heads/more_commits |
 677            grep "^    " > actual &&
 678        test_cmp expect actual
 679
 680'
 681
 682test_done