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