t / t6030-bisect-porcelain.shon commit Merge git://git.kernel.org/pub/scm/gitk/gitk (998b912)
   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_must_fail ls .git/BISECT_* &&
  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
 129# $HASH1 is good, $HASH4 is bad, we skip $HASH3
 130# but $HASH2 is bad,
 131# so we should find $HASH2 as the first bad commit
 132test_expect_success 'bisect skip: successfull result' '
 133        git bisect reset &&
 134        git bisect start $HASH4 $HASH1 &&
 135        git bisect skip &&
 136        git bisect bad > my_bisect_log.txt &&
 137        grep "$HASH2 is first bad commit" my_bisect_log.txt &&
 138        git bisect reset
 139'
 140
 141# $HASH1 is good, $HASH4 is bad, we skip $HASH3 and $HASH2
 142# so we should not be able to tell the first bad commit
 143# among $HASH2, $HASH3 and $HASH4
 144test_expect_success 'bisect skip: cannot tell between 3 commits' '
 145        git bisect start $HASH4 $HASH1 &&
 146        git bisect skip || return 1
 147
 148        if git bisect skip > my_bisect_log.txt
 149        then
 150                echo Oops, should have failed.
 151                false
 152        else
 153                test $? -eq 2 &&
 154                grep "first bad commit could be any of" my_bisect_log.txt &&
 155                ! grep $HASH1 my_bisect_log.txt &&
 156                grep $HASH2 my_bisect_log.txt &&
 157                grep $HASH3 my_bisect_log.txt &&
 158                grep $HASH4 my_bisect_log.txt &&
 159                git bisect reset
 160        fi
 161'
 162
 163# $HASH1 is good, $HASH4 is bad, we skip $HASH3
 164# but $HASH2 is good,
 165# so we should not be able to tell the first bad commit
 166# among $HASH3 and $HASH4
 167test_expect_success 'bisect skip: cannot tell between 2 commits' '
 168        git bisect start $HASH4 $HASH1 &&
 169        git bisect skip || return 1
 170
 171        if git bisect good > my_bisect_log.txt
 172        then
 173                echo Oops, should have failed.
 174                false
 175        else
 176                test $? -eq 2 &&
 177                grep "first bad commit could be any of" my_bisect_log.txt &&
 178                ! grep $HASH1 my_bisect_log.txt &&
 179                ! grep $HASH2 my_bisect_log.txt &&
 180                grep $HASH3 my_bisect_log.txt &&
 181                grep $HASH4 my_bisect_log.txt &&
 182                git bisect reset
 183        fi
 184'
 185
 186# We want to automatically find the commit that
 187# introduced "Another" into hello.
 188test_expect_success \
 189    '"git bisect run" simple case' \
 190    'echo "#"\!"/bin/sh" > test_script.sh &&
 191     echo "grep Another hello > /dev/null" >> test_script.sh &&
 192     echo "test \$? -ne 0" >> test_script.sh &&
 193     chmod +x test_script.sh &&
 194     git bisect start &&
 195     git bisect good $HASH1 &&
 196     git bisect bad $HASH4 &&
 197     git bisect run ./test_script.sh > my_bisect_log.txt &&
 198     grep "$HASH3 is first bad commit" my_bisect_log.txt &&
 199     git bisect reset'
 200
 201# We want to automatically find the commit that
 202# introduced "Ciao" into hello.
 203test_expect_success \
 204    '"git bisect run" with more complex "git bisect start"' \
 205    'echo "#"\!"/bin/sh" > test_script.sh &&
 206     echo "grep Ciao hello > /dev/null" >> test_script.sh &&
 207     echo "test \$? -ne 0" >> test_script.sh &&
 208     chmod +x test_script.sh &&
 209     git bisect start $HASH4 $HASH1 &&
 210     git bisect run ./test_script.sh > my_bisect_log.txt &&
 211     grep "$HASH4 is first bad commit" my_bisect_log.txt &&
 212     git bisect reset'
 213
 214# $HASH1 is good, $HASH5 is bad, we skip $HASH3
 215# but $HASH4 is good,
 216# so we should find $HASH5 as the first bad commit
 217HASH5=
 218test_expect_success 'bisect skip: add line and then a new test' '
 219        add_line_into_file "5: Another new line." hello &&
 220        HASH5=$(git rev-parse --verify HEAD) &&
 221        git bisect start $HASH5 $HASH1 &&
 222        git bisect skip &&
 223        git bisect good > my_bisect_log.txt &&
 224        grep "$HASH5 is first bad commit" my_bisect_log.txt &&
 225        git bisect log > log_to_replay.txt &&
 226        git bisect reset
 227'
 228
 229test_expect_success 'bisect skip and bisect replay' '
 230        git bisect replay log_to_replay.txt > my_bisect_log.txt &&
 231        grep "$HASH5 is first bad commit" my_bisect_log.txt &&
 232        git bisect reset
 233'
 234
 235HASH6=
 236test_expect_success 'bisect run & skip: cannot tell between 2' '
 237        add_line_into_file "6: Yet a line." hello &&
 238        HASH6=$(git rev-parse --verify HEAD) &&
 239        echo "#"\!"/bin/sh" > test_script.sh &&
 240        echo "sed -ne \\\$p hello | grep Ciao > /dev/null && exit 125" >> test_script.sh &&
 241        echo "grep line hello > /dev/null" >> test_script.sh &&
 242        echo "test \$? -ne 0" >> test_script.sh &&
 243        chmod +x test_script.sh &&
 244        git bisect start $HASH6 $HASH1 &&
 245        if git bisect run ./test_script.sh > 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 $HASH3 my_bisect_log.txt &&
 253                ! grep $HASH6 my_bisect_log.txt &&
 254                grep $HASH4 my_bisect_log.txt &&
 255                grep $HASH5 my_bisect_log.txt
 256        fi
 257'
 258
 259HASH7=
 260test_expect_success 'bisect run & skip: find first bad' '
 261        git bisect reset &&
 262        add_line_into_file "7: Should be the last line." hello &&
 263        HASH7=$(git rev-parse --verify HEAD) &&
 264        echo "#"\!"/bin/sh" > test_script.sh &&
 265        echo "sed -ne \\\$p hello | grep Ciao > /dev/null && exit 125" >> test_script.sh &&
 266        echo "sed -ne \\\$p hello | grep day > /dev/null && exit 125" >> test_script.sh &&
 267        echo "grep Yet hello > /dev/null" >> test_script.sh &&
 268        echo "test \$? -ne 0" >> test_script.sh &&
 269        chmod +x test_script.sh &&
 270        git bisect start $HASH7 $HASH1 &&
 271        git bisect run ./test_script.sh > my_bisect_log.txt &&
 272        grep "$HASH6 is first bad commit" my_bisect_log.txt
 273'
 274
 275test_expect_success 'bisect starting with a detached HEAD' '
 276
 277        git bisect reset &&
 278        git checkout master^ &&
 279        HEAD=$(git rev-parse --verify HEAD) &&
 280        git bisect start &&
 281        test $HEAD = $(cat .git/BISECT_START) &&
 282        git bisect reset &&
 283        test $HEAD = $(git rev-parse --verify HEAD)
 284
 285'
 286
 287test_expect_success 'bisect refuses to start if branch bisect exists' '
 288        git bisect reset &&
 289        git branch bisect &&
 290        test_must_fail git bisect start &&
 291        git branch -d bisect &&
 292        git checkout -b bisect &&
 293        test_must_fail git bisect start &&
 294        git checkout master &&
 295        git branch -d bisect
 296'
 297
 298test_expect_success 'bisect refuses to start if branch new-bisect exists' '
 299        git bisect reset &&
 300        git branch new-bisect &&
 301        test_must_fail git bisect start &&
 302        git branch -d new-bisect
 303'
 304
 305test_expect_success 'bisect errors out if bad and good are mistaken' '
 306        git bisect reset &&
 307        test_must_fail git bisect start $HASH2 $HASH4 2> rev_list_error &&
 308        grep "mistake good and bad" rev_list_error &&
 309        git bisect reset
 310'
 311
 312#
 313#
 314test_done