t / t6030-bisect-porcelain.shon commit bisect: introduce --no-checkout support into porcelain. (4796e82)
   1#!/bin/sh
   2#
   3# Copyright (c) 2007 Christian Couder
   4#
   5test_description='Tests git bisect functionality'
   6
   7exec </dev/null
   8
   9. ./test-lib.sh
  10
  11add_line_into_file()
  12{
  13    _line=$1
  14    _file=$2
  15
  16    if [ -f "$_file" ]; then
  17        echo "$_line" >> $_file || return $?
  18        MSG="Add <$_line> into <$_file>."
  19    else
  20        echo "$_line" > $_file || return $?
  21        git add $_file || return $?
  22        MSG="Create file <$_file> with <$_line> inside."
  23    fi
  24
  25    test_tick
  26    git commit --quiet -m "$MSG" $_file
  27}
  28
  29HASH1=
  30HASH2=
  31HASH3=
  32HASH4=
  33
  34test_expect_success 'set up basic repo with 1 file (hello) and 4 commits' '
  35     add_line_into_file "1: Hello World" hello &&
  36     HASH1=$(git rev-parse --verify HEAD) &&
  37     add_line_into_file "2: A new day for git" hello &&
  38     HASH2=$(git rev-parse --verify HEAD) &&
  39     add_line_into_file "3: Another new day for git" hello &&
  40     HASH3=$(git rev-parse --verify HEAD) &&
  41     add_line_into_file "4: Ciao for now" hello &&
  42     HASH4=$(git rev-parse --verify HEAD)
  43'
  44
  45test_expect_success 'bisect starts with only one bad' '
  46        git bisect reset &&
  47        git bisect start &&
  48        git bisect bad $HASH4 &&
  49        git bisect next
  50'
  51
  52test_expect_success 'bisect does not start with only one good' '
  53        git bisect reset &&
  54        git bisect start &&
  55        git bisect good $HASH1 || return 1
  56
  57        if git bisect next
  58        then
  59                echo Oops, should have failed.
  60                false
  61        else
  62                :
  63        fi
  64'
  65
  66test_expect_success 'bisect start with one bad and good' '
  67        git bisect reset &&
  68        git bisect start &&
  69        git bisect good $HASH1 &&
  70        git bisect bad $HASH4 &&
  71        git bisect next
  72'
  73
  74test_expect_success 'bisect fails if given any junk instead of revs' '
  75        git bisect reset &&
  76        test_must_fail git bisect start foo $HASH1 -- &&
  77        test_must_fail git bisect start $HASH4 $HASH1 bar -- &&
  78        test -z "$(git for-each-ref "refs/bisect/*")" &&
  79        test -z "$(ls .git/BISECT_* 2>/dev/null)" &&
  80        git bisect start &&
  81        test_must_fail git bisect good foo $HASH1 &&
  82        test_must_fail git bisect good $HASH1 bar &&
  83        test_must_fail git bisect bad frotz &&
  84        test_must_fail git bisect bad $HASH3 $HASH4 &&
  85        test_must_fail git bisect skip bar $HASH3 &&
  86        test_must_fail git bisect skip $HASH1 foo &&
  87        test -z "$(git for-each-ref "refs/bisect/*")" &&
  88        git bisect good $HASH1 &&
  89        git bisect bad $HASH4
  90'
  91
  92test_expect_success 'bisect reset: back in the master branch' '
  93        git bisect reset &&
  94        echo "* master" > branch.expect &&
  95        git branch > branch.output &&
  96        cmp branch.expect branch.output
  97'
  98
  99test_expect_success 'bisect reset: back in another branch' '
 100        git checkout -b other &&
 101        git bisect start &&
 102        git bisect good $HASH1 &&
 103        git bisect bad $HASH3 &&
 104        git bisect reset &&
 105        echo "  master" > branch.expect &&
 106        echo "* other" >> branch.expect &&
 107        git branch > branch.output &&
 108        cmp branch.expect branch.output
 109'
 110
 111test_expect_success 'bisect reset when not bisecting' '
 112        git bisect reset &&
 113        git branch > branch.output &&
 114        cmp branch.expect branch.output
 115'
 116
 117test_expect_success 'bisect reset removes packed refs' '
 118        git bisect reset &&
 119        git bisect start &&
 120        git bisect good $HASH1 &&
 121        git bisect bad $HASH3 &&
 122        git pack-refs --all --prune &&
 123        git bisect next &&
 124        git bisect reset &&
 125        test -z "$(git for-each-ref "refs/bisect/*")" &&
 126        test -z "$(git for-each-ref "refs/heads/bisect")"
 127'
 128
 129test_expect_success 'bisect start: back in good branch' '
 130        git branch > branch.output &&
 131        grep "* other" branch.output > /dev/null &&
 132        git bisect start $HASH4 $HASH1 -- &&
 133        git bisect good &&
 134        git bisect start $HASH4 $HASH1 -- &&
 135        git bisect bad &&
 136        git bisect reset &&
 137        git branch > branch.output &&
 138        grep "* other" branch.output > /dev/null
 139'
 140
 141test_expect_success 'bisect start: no ".git/BISECT_START" created if junk rev' '
 142        git bisect reset &&
 143        test_must_fail git bisect start $HASH4 foo -- &&
 144        git branch > branch.output &&
 145        grep "* other" branch.output > /dev/null &&
 146        test_must_fail test -e .git/BISECT_START
 147'
 148
 149test_expect_success 'bisect start: existing ".git/BISECT_START" not modified if junk rev' '
 150        git bisect start $HASH4 $HASH1 -- &&
 151        git bisect good &&
 152        cp .git/BISECT_START saved &&
 153        test_must_fail git bisect start $HASH4 foo -- &&
 154        git branch > branch.output &&
 155        grep "* (no branch)" branch.output > /dev/null &&
 156        test_cmp saved .git/BISECT_START
 157'
 158test_expect_success 'bisect start: no ".git/BISECT_START" if mistaken rev' '
 159        git bisect start $HASH4 $HASH1 -- &&
 160        git bisect good &&
 161        test_must_fail git bisect start $HASH1 $HASH4 -- &&
 162        git branch > branch.output &&
 163        grep "* other" branch.output > /dev/null &&
 164        test_must_fail test -e .git/BISECT_START
 165'
 166
 167test_expect_success 'bisect start: no ".git/BISECT_START" if checkout error' '
 168        echo "temp stuff" > hello &&
 169        test_must_fail git bisect start $HASH4 $HASH1 -- &&
 170        git branch &&
 171        git branch > branch.output &&
 172        grep "* other" branch.output > /dev/null &&
 173        test_must_fail test -e .git/BISECT_START &&
 174        test -z "$(git for-each-ref "refs/bisect/*")" &&
 175        git checkout HEAD hello
 176'
 177
 178# $HASH1 is good, $HASH4 is bad, we skip $HASH3
 179# but $HASH2 is bad,
 180# so we should find $HASH2 as the first bad commit
 181test_expect_success 'bisect skip: successfull result' '
 182        git bisect reset &&
 183        git bisect start $HASH4 $HASH1 &&
 184        git bisect skip &&
 185        git bisect bad > my_bisect_log.txt &&
 186        grep "$HASH2 is the first bad commit" my_bisect_log.txt &&
 187        git bisect reset
 188'
 189
 190# $HASH1 is good, $HASH4 is bad, we skip $HASH3 and $HASH2
 191# so we should not be able to tell the first bad commit
 192# among $HASH2, $HASH3 and $HASH4
 193test_expect_success 'bisect skip: cannot tell between 3 commits' '
 194        git bisect start $HASH4 $HASH1 &&
 195        git bisect skip || return 1
 196
 197        if git bisect skip > my_bisect_log.txt
 198        then
 199                echo Oops, should have failed.
 200                false
 201        else
 202                test $? -eq 2 &&
 203                grep "first bad commit could be any of" my_bisect_log.txt &&
 204                ! grep $HASH1 my_bisect_log.txt &&
 205                grep $HASH2 my_bisect_log.txt &&
 206                grep $HASH3 my_bisect_log.txt &&
 207                grep $HASH4 my_bisect_log.txt &&
 208                git bisect reset
 209        fi
 210'
 211
 212# $HASH1 is good, $HASH4 is bad, we skip $HASH3
 213# but $HASH2 is good,
 214# so we should not be able to tell the first bad commit
 215# among $HASH3 and $HASH4
 216test_expect_success 'bisect skip: cannot tell between 2 commits' '
 217        git bisect start $HASH4 $HASH1 &&
 218        git bisect skip || return 1
 219
 220        if git bisect good > my_bisect_log.txt
 221        then
 222                echo Oops, should have failed.
 223                false
 224        else
 225                test $? -eq 2 &&
 226                grep "first bad commit could be any of" my_bisect_log.txt &&
 227                ! grep $HASH1 my_bisect_log.txt &&
 228                ! grep $HASH2 my_bisect_log.txt &&
 229                grep $HASH3 my_bisect_log.txt &&
 230                grep $HASH4 my_bisect_log.txt &&
 231                git bisect reset
 232        fi
 233'
 234
 235# $HASH1 is good, $HASH4 is both skipped and bad, we skip $HASH3
 236# and $HASH2 is good,
 237# so we should not be able to tell the first bad commit
 238# among $HASH3 and $HASH4
 239test_expect_success 'bisect skip: with commit both bad and skipped' '
 240        git bisect start &&
 241        git bisect skip &&
 242        git bisect bad &&
 243        git bisect good $HASH1 &&
 244        git bisect skip &&
 245        if git bisect good > my_bisect_log.txt
 246        then
 247                echo Oops, should have failed.
 248                false
 249        else
 250                test $? -eq 2 &&
 251                grep "first bad commit could be any of" my_bisect_log.txt &&
 252                ! grep $HASH1 my_bisect_log.txt &&
 253                ! grep $HASH2 my_bisect_log.txt &&
 254                grep $HASH3 my_bisect_log.txt &&
 255                grep $HASH4 my_bisect_log.txt &&
 256                git bisect reset
 257        fi
 258'
 259
 260# We want to automatically find the commit that
 261# introduced "Another" into hello.
 262test_expect_success \
 263    '"git bisect run" simple case' \
 264    'echo "#"\!"/bin/sh" > test_script.sh &&
 265     echo "grep Another hello > /dev/null" >> test_script.sh &&
 266     echo "test \$? -ne 0" >> test_script.sh &&
 267     chmod +x test_script.sh &&
 268     git bisect start &&
 269     git bisect good $HASH1 &&
 270     git bisect bad $HASH4 &&
 271     git bisect run ./test_script.sh > my_bisect_log.txt &&
 272     grep "$HASH3 is the first bad commit" my_bisect_log.txt &&
 273     git bisect reset'
 274
 275# We want to automatically find the commit that
 276# introduced "Ciao" into hello.
 277test_expect_success \
 278    '"git bisect run" with more complex "git bisect start"' \
 279    'echo "#"\!"/bin/sh" > test_script.sh &&
 280     echo "grep Ciao hello > /dev/null" >> test_script.sh &&
 281     echo "test \$? -ne 0" >> test_script.sh &&
 282     chmod +x test_script.sh &&
 283     git bisect start $HASH4 $HASH1 &&
 284     git bisect run ./test_script.sh > my_bisect_log.txt &&
 285     grep "$HASH4 is the first bad commit" my_bisect_log.txt &&
 286     git bisect reset'
 287
 288# $HASH1 is good, $HASH5 is bad, we skip $HASH3
 289# but $HASH4 is good,
 290# so we should find $HASH5 as the first bad commit
 291HASH5=
 292test_expect_success 'bisect skip: add line and then a new test' '
 293        add_line_into_file "5: Another new line." hello &&
 294        HASH5=$(git rev-parse --verify HEAD) &&
 295        git bisect start $HASH5 $HASH1 &&
 296        git bisect skip &&
 297        git bisect good > my_bisect_log.txt &&
 298        grep "$HASH5 is the first bad commit" my_bisect_log.txt &&
 299        git bisect log > log_to_replay.txt &&
 300        git bisect reset
 301'
 302
 303test_expect_success 'bisect skip and bisect replay' '
 304        git bisect replay log_to_replay.txt > my_bisect_log.txt &&
 305        grep "$HASH5 is the first bad commit" my_bisect_log.txt &&
 306        git bisect reset
 307'
 308
 309HASH6=
 310test_expect_success 'bisect run & skip: cannot tell between 2' '
 311        add_line_into_file "6: Yet a line." hello &&
 312        HASH6=$(git rev-parse --verify HEAD) &&
 313        echo "#"\!"/bin/sh" > test_script.sh &&
 314        echo "sed -ne \\\$p hello | grep Ciao > /dev/null && exit 125" >> test_script.sh &&
 315        echo "grep line hello > /dev/null" >> test_script.sh &&
 316        echo "test \$? -ne 0" >> test_script.sh &&
 317        chmod +x test_script.sh &&
 318        git bisect start $HASH6 $HASH1 &&
 319        if git bisect run ./test_script.sh > my_bisect_log.txt
 320        then
 321                echo Oops, should have failed.
 322                false
 323        else
 324                test $? -eq 2 &&
 325                grep "first bad commit could be any of" my_bisect_log.txt &&
 326                ! grep $HASH3 my_bisect_log.txt &&
 327                ! grep $HASH6 my_bisect_log.txt &&
 328                grep $HASH4 my_bisect_log.txt &&
 329                grep $HASH5 my_bisect_log.txt
 330        fi
 331'
 332
 333HASH7=
 334test_expect_success 'bisect run & skip: find first bad' '
 335        git bisect reset &&
 336        add_line_into_file "7: Should be the last line." hello &&
 337        HASH7=$(git rev-parse --verify HEAD) &&
 338        echo "#"\!"/bin/sh" > test_script.sh &&
 339        echo "sed -ne \\\$p hello | grep Ciao > /dev/null && exit 125" >> test_script.sh &&
 340        echo "sed -ne \\\$p hello | grep day > /dev/null && exit 125" >> test_script.sh &&
 341        echo "grep Yet hello > /dev/null" >> test_script.sh &&
 342        echo "test \$? -ne 0" >> test_script.sh &&
 343        chmod +x test_script.sh &&
 344        git bisect start $HASH7 $HASH1 &&
 345        git bisect run ./test_script.sh > my_bisect_log.txt &&
 346        grep "$HASH6 is the first bad commit" my_bisect_log.txt
 347'
 348
 349test_expect_success 'bisect skip only one range' '
 350        git bisect reset &&
 351        git bisect start $HASH7 $HASH1 &&
 352        git bisect skip $HASH1..$HASH5 &&
 353        test "$HASH6" = "$(git rev-parse --verify HEAD)" &&
 354        test_must_fail git bisect bad > my_bisect_log.txt &&
 355        grep "first bad commit could be any of" my_bisect_log.txt
 356'
 357
 358test_expect_success 'bisect skip many ranges' '
 359        git bisect start $HASH7 $HASH1 &&
 360        test "$HASH4" = "$(git rev-parse --verify HEAD)" &&
 361        git bisect skip $HASH2 $HASH2.. ..$HASH5 &&
 362        test "$HASH6" = "$(git rev-parse --verify HEAD)" &&
 363        test_must_fail git bisect bad > my_bisect_log.txt &&
 364        grep "first bad commit could be any of" my_bisect_log.txt
 365'
 366
 367test_expect_success 'bisect starting with a detached HEAD' '
 368        git bisect reset &&
 369        git checkout master^ &&
 370        HEAD=$(git rev-parse --verify HEAD) &&
 371        git bisect start &&
 372        test $HEAD = $(cat .git/BISECT_START) &&
 373        git bisect reset &&
 374        test $HEAD = $(git rev-parse --verify HEAD)
 375'
 376
 377test_expect_success 'bisect errors out if bad and good are mistaken' '
 378        git bisect reset &&
 379        test_must_fail git bisect start $HASH2 $HASH4 2> rev_list_error &&
 380        grep "mistake good and bad" rev_list_error &&
 381        git bisect reset
 382'
 383
 384test_expect_success 'bisect does not create a "bisect" branch' '
 385        git bisect reset &&
 386        git bisect start $HASH7 $HASH1 &&
 387        git branch bisect &&
 388        rev_hash4=$(git rev-parse --verify HEAD) &&
 389        test "$rev_hash4" = "$HASH4" &&
 390        git branch -D bisect &&
 391        git bisect good &&
 392        git branch bisect &&
 393        rev_hash6=$(git rev-parse --verify HEAD) &&
 394        test "$rev_hash6" = "$HASH6" &&
 395        git bisect good > my_bisect_log.txt &&
 396        grep "$HASH7 is the first bad commit" my_bisect_log.txt &&
 397        git bisect reset &&
 398        rev_hash6=$(git rev-parse --verify bisect) &&
 399        test "$rev_hash6" = "$HASH6" &&
 400        git branch -D bisect
 401'
 402
 403# This creates a "side" branch to test "siblings" cases.
 404#
 405# H1-H2-H3-H4-H5-H6-H7  <--other
 406#            \
 407#             S5-S6-S7  <--side
 408#
 409test_expect_success 'side branch creation' '
 410        git bisect reset &&
 411        git checkout -b side $HASH4 &&
 412        add_line_into_file "5(side): first line on a side branch" hello2 &&
 413        SIDE_HASH5=$(git rev-parse --verify HEAD) &&
 414        add_line_into_file "6(side): second line on a side branch" hello2 &&
 415        SIDE_HASH6=$(git rev-parse --verify HEAD) &&
 416        add_line_into_file "7(side): third line on a side branch" hello2 &&
 417        SIDE_HASH7=$(git rev-parse --verify HEAD)
 418'
 419
 420test_expect_success 'good merge base when good and bad are siblings' '
 421        git bisect start "$HASH7" "$SIDE_HASH7" > my_bisect_log.txt &&
 422        grep "merge base must be tested" my_bisect_log.txt &&
 423        grep $HASH4 my_bisect_log.txt &&
 424        git bisect good > my_bisect_log.txt &&
 425        test_must_fail grep "merge base must be tested" my_bisect_log.txt &&
 426        grep $HASH6 my_bisect_log.txt &&
 427        git bisect reset
 428'
 429test_expect_success 'skipped merge base when good and bad are siblings' '
 430        git bisect start "$SIDE_HASH7" "$HASH7" > my_bisect_log.txt &&
 431        grep "merge base must be tested" my_bisect_log.txt &&
 432        grep $HASH4 my_bisect_log.txt &&
 433        git bisect skip > my_bisect_log.txt 2>&1 &&
 434        grep "warning" my_bisect_log.txt &&
 435        grep $SIDE_HASH6 my_bisect_log.txt &&
 436        git bisect reset
 437'
 438
 439test_expect_success 'bad merge base when good and bad are siblings' '
 440        git bisect start "$HASH7" HEAD > my_bisect_log.txt &&
 441        grep "merge base must be tested" my_bisect_log.txt &&
 442        grep $HASH4 my_bisect_log.txt &&
 443        test_must_fail git bisect bad > my_bisect_log.txt 2>&1 &&
 444        grep "merge base $HASH4 is bad" my_bisect_log.txt &&
 445        grep "fixed between $HASH4 and \[$SIDE_HASH7\]" my_bisect_log.txt &&
 446        git bisect reset
 447'
 448
 449# This creates a few more commits (A and B) to test "siblings" cases
 450# when a good and a bad rev have many merge bases.
 451#
 452# We should have the following:
 453#
 454# H1-H2-H3-H4-H5-H6-H7
 455#            \  \     \
 456#             S5-A     \
 457#              \        \
 458#               S6-S7----B
 459#
 460# And there A and B have 2 merge bases (S5 and H5) that should be
 461# reported by "git merge-base --all A B".
 462#
 463test_expect_success 'many merge bases creation' '
 464        git checkout "$SIDE_HASH5" &&
 465        git merge -m "merge HASH5 and SIDE_HASH5" "$HASH5" &&
 466        A_HASH=$(git rev-parse --verify HEAD) &&
 467        git checkout side &&
 468        git merge -m "merge HASH7 and SIDE_HASH7" "$HASH7" &&
 469        B_HASH=$(git rev-parse --verify HEAD) &&
 470        git merge-base --all "$A_HASH" "$B_HASH" > merge_bases.txt &&
 471        test $(wc -l < merge_bases.txt) = "2" &&
 472        grep "$HASH5" merge_bases.txt &&
 473        grep "$SIDE_HASH5" merge_bases.txt
 474'
 475
 476test_expect_success 'good merge bases when good and bad are siblings' '
 477        git bisect start "$B_HASH" "$A_HASH" > my_bisect_log.txt &&
 478        grep "merge base must be tested" my_bisect_log.txt &&
 479        git bisect good > my_bisect_log2.txt &&
 480        grep "merge base must be tested" my_bisect_log2.txt &&
 481        {
 482                {
 483                        grep "$SIDE_HASH5" my_bisect_log.txt &&
 484                        grep "$HASH5" my_bisect_log2.txt
 485                } || {
 486                        grep "$SIDE_HASH5" my_bisect_log2.txt &&
 487                        grep "$HASH5" my_bisect_log.txt
 488                }
 489        } &&
 490        git bisect reset
 491'
 492
 493test_expect_success 'optimized merge base checks' '
 494        git bisect start "$HASH7" "$SIDE_HASH7" > my_bisect_log.txt &&
 495        grep "merge base must be tested" my_bisect_log.txt &&
 496        grep "$HASH4" my_bisect_log.txt &&
 497        git bisect good > my_bisect_log2.txt &&
 498        test -f ".git/BISECT_ANCESTORS_OK" &&
 499        test "$HASH6" = $(git rev-parse --verify HEAD) &&
 500        git bisect bad > my_bisect_log3.txt &&
 501        git bisect good "$A_HASH" > my_bisect_log4.txt &&
 502        grep "merge base must be tested" my_bisect_log4.txt &&
 503        test_must_fail test -f ".git/BISECT_ANCESTORS_OK"
 504'
 505
 506# This creates another side branch called "parallel" with some files
 507# in some directories, to test bisecting with paths.
 508#
 509# We should have the following:
 510#
 511#    P1-P2-P3-P4-P5-P6-P7
 512#   /        /        /
 513# H1-H2-H3-H4-H5-H6-H7
 514#            \  \     \
 515#             S5-A     \
 516#              \        \
 517#               S6-S7----B
 518#
 519test_expect_success '"parallel" side branch creation' '
 520        git bisect reset &&
 521        git checkout -b parallel $HASH1 &&
 522        mkdir dir1 dir2 &&
 523        add_line_into_file "1(para): line 1 on parallel branch" dir1/file1 &&
 524        PARA_HASH1=$(git rev-parse --verify HEAD) &&
 525        add_line_into_file "2(para): line 2 on parallel branch" dir2/file2 &&
 526        PARA_HASH2=$(git rev-parse --verify HEAD) &&
 527        add_line_into_file "3(para): line 3 on parallel branch" dir2/file3 &&
 528        PARA_HASH3=$(git rev-parse --verify HEAD) &&
 529        git merge -m "merge HASH4 and PARA_HASH3" "$HASH4" &&
 530        PARA_HASH4=$(git rev-parse --verify HEAD) &&
 531        add_line_into_file "5(para): add line on parallel branch" dir1/file1 &&
 532        PARA_HASH5=$(git rev-parse --verify HEAD) &&
 533        add_line_into_file "6(para): add line on parallel branch" dir2/file2 &&
 534        PARA_HASH6=$(git rev-parse --verify HEAD) &&
 535        git merge -m "merge HASH7 and PARA_HASH6" "$HASH7" &&
 536        PARA_HASH7=$(git rev-parse --verify HEAD)
 537'
 538
 539test_expect_success 'restricting bisection on one dir' '
 540        git bisect reset &&
 541        git bisect start HEAD $HASH1 -- dir1 &&
 542        para1=$(git rev-parse --verify HEAD) &&
 543        test "$para1" = "$PARA_HASH1" &&
 544        git bisect bad > my_bisect_log.txt &&
 545        grep "$PARA_HASH1 is the first bad commit" my_bisect_log.txt
 546'
 547
 548test_expect_success 'restricting bisection on one dir and a file' '
 549        git bisect reset &&
 550        git bisect start HEAD $HASH1 -- dir1 hello &&
 551        para4=$(git rev-parse --verify HEAD) &&
 552        test "$para4" = "$PARA_HASH4" &&
 553        git bisect bad &&
 554        hash3=$(git rev-parse --verify HEAD) &&
 555        test "$hash3" = "$HASH3" &&
 556        git bisect good &&
 557        hash4=$(git rev-parse --verify HEAD) &&
 558        test "$hash4" = "$HASH4" &&
 559        git bisect good &&
 560        para1=$(git rev-parse --verify HEAD) &&
 561        test "$para1" = "$PARA_HASH1" &&
 562        git bisect good > my_bisect_log.txt &&
 563        grep "$PARA_HASH4 is the first bad commit" my_bisect_log.txt
 564'
 565
 566test_expect_success 'skipping away from skipped commit' '
 567        git bisect start $PARA_HASH7 $HASH1 &&
 568        para4=$(git rev-parse --verify HEAD) &&
 569        test "$para4" = "$PARA_HASH4" &&
 570        git bisect skip &&
 571        hash7=$(git rev-parse --verify HEAD) &&
 572        test "$hash7" = "$HASH7" &&
 573        git bisect skip &&
 574        para3=$(git rev-parse --verify HEAD) &&
 575        test "$para3" = "$PARA_HASH3"
 576'
 577
 578test_expect_success 'erroring out when using bad path parameters' '
 579        test_must_fail git bisect start $PARA_HASH7 $HASH1 -- foobar 2> error.txt &&
 580        grep "bad path parameters" error.txt
 581'
 582
 583#
 584# This creates a broken branch which cannot be checked out because
 585# the tree created has been deleted.
 586#
 587# H1-H2-H3-H4-H5-H6-H7  <--other
 588#            \
 589#             S5-S6'-S7'-S8'-S9  <--broken
 590#
 591# Commits marked with ' have a missing tree.
 592#
 593test_expect_success 'broken branch creation' '
 594        git bisect reset &&
 595        git checkout -b broken $HASH4 &&
 596        git tag BROKEN_HASH4 $HASH4 &&
 597        add_line_into_file "5(broken): first line on a broken branch" hello2 &&
 598        git tag BROKEN_HASH5 &&
 599        mkdir missing &&
 600        :> missing/MISSING &&
 601        git add missing/MISSING &&
 602        git commit -m "6(broken): Added file that will be deleted"
 603        git tag BROKEN_HASH6 &&
 604        add_line_into_file "7(broken): second line on a broken branch" hello2 &&
 605        git tag BROKEN_HASH7 &&
 606        add_line_into_file "8(broken): third line on a broken branch" hello2 &&
 607        git tag BROKEN_HASH8 &&
 608        git rm missing/MISSING &&
 609        git commit -m "9(broken): Remove missing file"
 610        git tag BROKEN_HASH9 &&
 611        rm .git/objects/39/f7e61a724187ab767d2e08442d9b6b9dab587d
 612'
 613
 614echo "" > expected.ok
 615cat > expected.missing-tree.default <<EOF
 616fatal: unable to read tree 39f7e61a724187ab767d2e08442d9b6b9dab587d
 617EOF
 618
 619test_expect_success 'bisect fails if tree is broken on start commit' '
 620        git bisect reset &&
 621        test_must_fail git bisect start BROKEN_HASH7 BROKEN_HASH4 2>error.txt &&
 622        test_cmp expected.missing-tree.default error.txt
 623'
 624
 625test_expect_success 'bisect fails if tree is broken on trial commit' '
 626        git bisect reset &&
 627        test_must_fail git bisect start BROKEN_HASH9 BROKEN_HASH4 2>error.txt &&
 628        git reset --hard broken &&
 629        git checkout broken &&
 630        test_cmp expected.missing-tree.default error.txt
 631'
 632
 633test_done