t / t6030-bisect-porcelain.shon commit bisect: fix bad rev checking in "git bisect good" (e338907)
   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 good and bad fails if not given only revs' '
  75        git bisect reset &&
  76        git bisect start &&
  77        test_must_fail git bisect good foo $HASH1 &&
  78        test_must_fail git bisect good $HASH1 bar &&
  79        test_must_fail git bisect bad frotz &&
  80        test_must_fail git bisect bad $HASH3 $HASH4 &&
  81        test_must_fail git bisect skip bar $HASH3 &&
  82        test_must_fail git bisect skip $HASH1 foo &&
  83        git bisect good $HASH1 &&
  84        git bisect bad $HASH4
  85'
  86
  87test_expect_success 'bisect reset: back in the master branch' '
  88        git bisect reset &&
  89        echo "* master" > branch.expect &&
  90        git branch > branch.output &&
  91        cmp branch.expect branch.output
  92'
  93
  94test_expect_success 'bisect reset: back in another branch' '
  95        git checkout -b other &&
  96        git bisect start &&
  97        git bisect good $HASH1 &&
  98        git bisect bad $HASH3 &&
  99        git bisect reset &&
 100        echo "  master" > branch.expect &&
 101        echo "* other" >> branch.expect &&
 102        git branch > branch.output &&
 103        cmp branch.expect branch.output
 104'
 105
 106test_expect_success 'bisect reset when not bisecting' '
 107        git bisect reset &&
 108        git branch > branch.output &&
 109        cmp branch.expect branch.output
 110'
 111
 112test_expect_success 'bisect reset removes packed refs' '
 113        git bisect reset &&
 114        git bisect start &&
 115        git bisect good $HASH1 &&
 116        git bisect bad $HASH3 &&
 117        git pack-refs --all --prune &&
 118        git bisect next &&
 119        git bisect reset &&
 120        test -z "$(git for-each-ref "refs/bisect/*")" &&
 121        test -z "$(git for-each-ref "refs/heads/bisect")"
 122'
 123
 124# $HASH1 is good, $HASH4 is bad, we skip $HASH3
 125# but $HASH2 is bad,
 126# so we should find $HASH2 as the first bad commit
 127test_expect_success 'bisect skip: successfull result' '
 128        git bisect reset &&
 129        git bisect start $HASH4 $HASH1 &&
 130        git bisect skip &&
 131        git bisect bad > my_bisect_log.txt &&
 132        grep "$HASH2 is first bad commit" my_bisect_log.txt &&
 133        git bisect reset
 134'
 135
 136# $HASH1 is good, $HASH4 is bad, we skip $HASH3 and $HASH2
 137# so we should not be able to tell the first bad commit
 138# among $HASH2, $HASH3 and $HASH4
 139test_expect_success 'bisect skip: cannot tell between 3 commits' '
 140        git bisect start $HASH4 $HASH1 &&
 141        git bisect skip || return 1
 142
 143        if git bisect skip > my_bisect_log.txt
 144        then
 145                echo Oops, should have failed.
 146                false
 147        else
 148                test $? -eq 2 &&
 149                grep "first bad commit could be any of" my_bisect_log.txt &&
 150                ! grep $HASH1 my_bisect_log.txt &&
 151                grep $HASH2 my_bisect_log.txt &&
 152                grep $HASH3 my_bisect_log.txt &&
 153                grep $HASH4 my_bisect_log.txt &&
 154                git bisect reset
 155        fi
 156'
 157
 158# $HASH1 is good, $HASH4 is bad, we skip $HASH3
 159# but $HASH2 is good,
 160# so we should not be able to tell the first bad commit
 161# among $HASH3 and $HASH4
 162test_expect_success 'bisect skip: cannot tell between 2 commits' '
 163        git bisect start $HASH4 $HASH1 &&
 164        git bisect skip || return 1
 165
 166        if git bisect good > my_bisect_log.txt
 167        then
 168                echo Oops, should have failed.
 169                false
 170        else
 171                test $? -eq 2 &&
 172                grep "first bad commit could be any of" my_bisect_log.txt &&
 173                ! grep $HASH1 my_bisect_log.txt &&
 174                ! grep $HASH2 my_bisect_log.txt &&
 175                grep $HASH3 my_bisect_log.txt &&
 176                grep $HASH4 my_bisect_log.txt &&
 177                git bisect reset
 178        fi
 179'
 180
 181# We want to automatically find the commit that
 182# introduced "Another" into hello.
 183test_expect_success \
 184    '"git bisect run" simple case' \
 185    'echo "#"\!"/bin/sh" > test_script.sh &&
 186     echo "grep Another hello > /dev/null" >> test_script.sh &&
 187     echo "test \$? -ne 0" >> test_script.sh &&
 188     chmod +x test_script.sh &&
 189     git bisect start &&
 190     git bisect good $HASH1 &&
 191     git bisect bad $HASH4 &&
 192     git bisect run ./test_script.sh > my_bisect_log.txt &&
 193     grep "$HASH3 is first bad commit" my_bisect_log.txt &&
 194     git bisect reset'
 195
 196# We want to automatically find the commit that
 197# introduced "Ciao" into hello.
 198test_expect_success \
 199    '"git bisect run" with more complex "git bisect start"' \
 200    'echo "#"\!"/bin/sh" > test_script.sh &&
 201     echo "grep Ciao hello > /dev/null" >> test_script.sh &&
 202     echo "test \$? -ne 0" >> test_script.sh &&
 203     chmod +x test_script.sh &&
 204     git bisect start $HASH4 $HASH1 &&
 205     git bisect run ./test_script.sh > my_bisect_log.txt &&
 206     grep "$HASH4 is first bad commit" my_bisect_log.txt &&
 207     git bisect reset'
 208
 209# $HASH1 is good, $HASH5 is bad, we skip $HASH3
 210# but $HASH4 is good,
 211# so we should find $HASH5 as the first bad commit
 212HASH5=
 213test_expect_success 'bisect skip: add line and then a new test' '
 214        add_line_into_file "5: Another new line." hello &&
 215        HASH5=$(git rev-parse --verify HEAD) &&
 216        git bisect start $HASH5 $HASH1 &&
 217        git bisect skip &&
 218        git bisect good > my_bisect_log.txt &&
 219        grep "$HASH5 is first bad commit" my_bisect_log.txt &&
 220        git bisect log > log_to_replay.txt &&
 221        git bisect reset
 222'
 223
 224test_expect_success 'bisect skip and bisect replay' '
 225        git bisect replay log_to_replay.txt > my_bisect_log.txt &&
 226        grep "$HASH5 is first bad commit" my_bisect_log.txt &&
 227        git bisect reset
 228'
 229
 230HASH6=
 231test_expect_success 'bisect run & skip: cannot tell between 2' '
 232        add_line_into_file "6: Yet a line." hello &&
 233        HASH6=$(git rev-parse --verify HEAD) &&
 234        echo "#"\!"/bin/sh" > test_script.sh &&
 235        echo "tail -1 hello | grep Ciao > /dev/null && exit 125" >> test_script.sh &&
 236        echo "grep line hello > /dev/null" >> test_script.sh &&
 237        echo "test \$? -ne 0" >> test_script.sh &&
 238        chmod +x test_script.sh &&
 239        git bisect start $HASH6 $HASH1 &&
 240        if git bisect run ./test_script.sh > my_bisect_log.txt
 241        then
 242                echo Oops, should have failed.
 243                false
 244        else
 245                test $? -eq 2 &&
 246                grep "first bad commit could be any of" my_bisect_log.txt &&
 247                ! grep $HASH3 my_bisect_log.txt &&
 248                ! grep $HASH6 my_bisect_log.txt &&
 249                grep $HASH4 my_bisect_log.txt &&
 250                grep $HASH5 my_bisect_log.txt
 251        fi
 252'
 253
 254HASH7=
 255test_expect_success 'bisect run & skip: find first bad' '
 256        git bisect reset &&
 257        add_line_into_file "7: Should be the last line." hello &&
 258        HASH7=$(git rev-parse --verify HEAD) &&
 259        echo "#"\!"/bin/sh" > test_script.sh &&
 260        echo "tail -1 hello | grep Ciao > /dev/null && exit 125" >> test_script.sh &&
 261        echo "tail -1 hello | grep day > /dev/null && exit 125" >> test_script.sh &&
 262        echo "grep Yet hello > /dev/null" >> test_script.sh &&
 263        echo "test \$? -ne 0" >> test_script.sh &&
 264        chmod +x test_script.sh &&
 265        git bisect start $HASH7 $HASH1 &&
 266        git bisect run ./test_script.sh > my_bisect_log.txt &&
 267        grep "$HASH6 is first bad commit" my_bisect_log.txt
 268'
 269
 270test_expect_success 'bisect starting with a detached HEAD' '
 271
 272        git bisect reset &&
 273        git checkout master^ &&
 274        HEAD=$(git rev-parse --verify HEAD) &&
 275        git bisect start &&
 276        test $HEAD = $(cat .git/BISECT_START) &&
 277        git bisect reset &&
 278        test $HEAD = $(git rev-parse --verify HEAD)
 279
 280'
 281
 282#
 283#
 284test_done