Ticket #196: git-bisect.diff
File git-bisect.diff, 21.8 KB (added by , 5 years ago) |
---|
-
git-bisect
old new 1 #! /bin/sh1 #!sh 2 2 3 USAGE='[help|start|bad|good| skip|next|reset|visualize|replay|log|run]'3 USAGE='[help|start|bad|good|new|old|terms|skip|next|reset|visualize|replay|log|run]' 4 4 LONG_USAGE='git bisect help 5 print this long help message. 6 git bisect start [<bad> [<good>...]] [--] [<pathspec>...] 7 reset bisect state and start bisection. 8 git bisect bad [<rev>] 9 mark <rev> a known-bad revision. 10 git bisect good [<rev>...] 11 mark <rev>... known-good revisions. 5 print this long help message. 6 git bisect start [--term-{old,good}=<term> --term-{new,bad}=<term>] 7 [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...] 8 reset bisect state and start bisection. 9 git bisect (bad|new) [<rev>] 10 mark <rev> a known-bad revision/ 11 a revision after change in a given property. 12 git bisect (good|old) [<rev>...] 13 mark <rev>... known-good revisions/ 14 revisions before change in a given property. 15 git bisect terms [--term-good | --term-bad] 16 show the terms used for old and new commits (default: bad, good) 12 17 git bisect skip [(<rev>|<range>)...] 13 18 mark <rev>... untestable revisions. 14 19 git bisect next 15 20 find next bisection to test and check it out. 16 21 git bisect reset [<commit>] 17 22 finish bisection search and go back to commit. 18 23 git bisect visualize 19 24 show bisect status in gitk. 20 25 git bisect replay <logfile> 21 26 replay bisection log. 22 27 git bisect log 23 28 show bisect log. 24 29 git bisect run <cmd>... 25 30 use <cmd>... to automatically bisect. 26 31 27 32 Please use "git help bisect" to get the full man page.' 28 33 29 34 OPTIONS_SPEC= 30 35 . git-sh-setup 31 require_work_tree32 36 33 37 _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' 34 38 _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" 39 TERM_BAD=bad 40 TERM_GOOD=good 41 42 bisect_head() 43 { 44 if test -f "$GIT_DIR/BISECT_HEAD" 45 then 46 echo BISECT_HEAD 47 else 48 echo HEAD 49 fi 50 } 35 51 36 52 bisect_autostart() { 37 53 test -s "$GIT_DIR/BISECT_START" || { 38 echo >&2 'You need to start by "git bisect start"'54 gettextln "You need to start by \"git bisect start\"" >&2 39 55 if test -t 0 40 56 then 41 echo >&2 -n 'Do you want me to do it for you [Y/n]? ' 57 # TRANSLATORS: Make sure to include [Y] and [n] in your 58 # translation. The program will only accept English input 59 # at this point. 60 gettext "Do you want me to do it for you [Y/n]? " >&2 42 61 read yesno 43 62 case "$yesno" in 44 63 [Nn]*) … … 53 72 54 73 bisect_start() { 55 74 # 75 # Check for one bad and then some good revisions. 76 # 77 has_double_dash=0 78 for arg; do 79 case "$arg" in --) has_double_dash=1; break ;; esac 80 done 81 orig_args=$(git rev-parse --sq-quote "$@") 82 bad_seen=0 83 eval='' 84 must_write_terms=0 85 revs='' 86 if test "z$(git rev-parse --is-bare-repository)" != zfalse 87 then 88 mode=--no-checkout 89 else 90 mode='' 91 fi 92 while [ $# -gt 0 ]; do 93 arg="$1" 94 case "$arg" in 95 --) 96 shift 97 break 98 ;; 99 --no-checkout) 100 mode=--no-checkout 101 shift ;; 102 --term-good|--term-old) 103 shift 104 must_write_terms=1 105 TERM_GOOD=$1 106 shift ;; 107 --term-good=*|--term-old=*) 108 must_write_terms=1 109 TERM_GOOD=${1#*=} 110 shift ;; 111 --term-bad|--term-new) 112 shift 113 must_write_terms=1 114 TERM_BAD=$1 115 shift ;; 116 --term-bad=*|--term-new=*) 117 must_write_terms=1 118 TERM_BAD=${1#*=} 119 shift ;; 120 --*) 121 die "$(eval_gettext "unrecognised option: '\$arg'")" ;; 122 *) 123 rev=$(git rev-parse -q --verify "$arg^{commit}") || { 124 test $has_double_dash -eq 1 && 125 die "$(eval_gettext "'\$arg' does not appear to be a valid revision")" 126 break 127 } 128 revs="$revs $rev" 129 shift 130 ;; 131 esac 132 done 133 134 for rev in $revs 135 do 136 # The user ran "git bisect start <sha1> 137 # <sha1>", hence did not explicitly specify 138 # the terms, but we are already starting to 139 # set references named with the default terms, 140 # and won't be able to change afterwards. 141 must_write_terms=1 142 143 case $bad_seen in 144 0) state=$TERM_BAD ; bad_seen=1 ;; 145 *) state=$TERM_GOOD ;; 146 esac 147 eval="$eval bisect_write '$state' '$rev' 'nolog' &&" 148 done 149 # 56 150 # Verify HEAD. 57 151 # 58 152 head=$(GIT_DIR="$GIT_DIR" git symbolic-ref -q HEAD) || 59 153 head=$(GIT_DIR="$GIT_DIR" git rev-parse --verify HEAD) || 60 die " Bad HEAD - I need a HEAD"154 die "$(gettext "Bad HEAD - I need a HEAD")" 61 155 62 156 # 63 157 # Check if we are bisecting. … … 67 161 then 68 162 # Reset to the rev from where we started. 69 163 start_head=$(cat "$GIT_DIR/BISECT_START") 70 git checkout "$start_head" -- || exit 164 if test "z$mode" != "z--no-checkout" 165 then 166 git checkout "$start_head" -- || 167 die "$(eval_gettext "Checking out '\$start_head' failed. Try 'git bisect reset <valid-branch>'.")" 168 fi 71 169 else 72 170 # Get rev from where we start. 73 171 case "$head" in … … 76 174 # cogito usage, and cogito users should understand 77 175 # it relates to cg-seek. 78 176 [ -s "$GIT_DIR/head-name" ] && 79 die " won't bisect on seeked tree"177 die "$(gettext "won't bisect on cg-seek'ed tree")" 80 178 start_head="${head#refs/heads/}" 81 179 ;; 82 180 *) 83 die " Bad HEAD - strange symbolic ref"181 die "$(gettext "Bad HEAD - strange symbolic ref")" 84 182 ;; 85 183 esac 86 184 fi … … 91 189 bisect_clean_state || exit 92 190 93 191 # 94 # Check for one bad and then some good revisions.95 #96 has_double_dash=097 for arg; do98 case "$arg" in --) has_double_dash=1; break ;; esac99 done100 orig_args=$(git rev-parse --sq-quote "$@")101 bad_seen=0102 eval=''103 while [ $# -gt 0 ]; do104 arg="$1"105 case "$arg" in106 --)107 shift108 break109 ;;110 *)111 rev=$(git rev-parse -q --verify "$arg^{commit}") || {112 test $has_double_dash -eq 1 &&113 die "'$arg' does not appear to be a valid revision"114 break115 }116 case $bad_seen in117 0) state='bad' ; bad_seen=1 ;;118 *) state='good' ;;119 esac120 eval="$eval bisect_write '$state' '$rev' 'nolog'; "121 shift122 ;;123 esac124 done125 126 #127 192 # Change state. 128 193 # In case of mistaken revs or checkout error, or signals received, 129 194 # "bisect_auto_next" below may exit or misbehave. … … 136 201 # 137 202 # Write new start state. 138 203 # 139 echo "$start_head" >"$GIT_DIR/BISECT_START" && 204 echo "$start_head" >"$GIT_DIR/BISECT_START" && { 205 test "z$mode" != "z--no-checkout" || 206 git update-ref --no-deref BISECT_HEAD "$start_head" 207 } && 140 208 git rev-parse --sq-quote "$@" >"$GIT_DIR/BISECT_NAMES" && 141 eval "$eval" && 209 eval "$eval true" && 210 if test $must_write_terms -eq 1 211 then 212 write_terms "$TERM_BAD" "$TERM_GOOD" 213 fi && 142 214 echo "git bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit 143 215 # 144 216 # Check if we can proceed to the next bisect state. … … 153 225 rev="$2" 154 226 nolog="$3" 155 227 case "$state" in 156 bad) tag="$state" ;; 157 good|skip) tag="$state"-"$rev" ;; 158 *) die "Bad bisect_write argument: $state" ;; 228 "$TERM_BAD") 229 tag="$state" ;; 230 "$TERM_GOOD"|skip) 231 tag="$state"-"$rev" ;; 232 *) 233 die "$(eval_gettext "Bad bisect_write argument: \$state")" ;; 159 234 esac 160 235 git update-ref "refs/bisect/$tag" "$rev" || exit 161 236 echo "# $state: $(git show-branch $rev)" >>"$GIT_DIR/BISECT_LOG" … … 169 244 170 245 check_expected_revs() { 171 246 for _rev in "$@"; do 172 if ! is_expected_rev "$_rev"; then 247 if ! is_expected_rev "$_rev" 248 then 173 249 rm -f "$GIT_DIR/BISECT_ANCESTORS_OK" 174 250 rm -f "$GIT_DIR/BISECT_EXPECTED_REV" 175 251 return … … 178 254 } 179 255 180 256 bisect_skip() { 181 257 all='' 182 258 for arg in "$@" 183 259 do 184 185 186 revs=$(git rev-list "$arg") || die "Bad rev input: $arg" ;;187 188 189 190 191 192 260 case "$arg" in 261 *..*) 262 revs=$(git rev-list "$arg") || die "$(eval_gettext "Bad rev input: \$arg")" ;; 263 *) 264 revs=$(git rev-parse --sq-quote "$arg") ;; 265 esac 266 all="$all $revs" 267 done 268 eval bisect_state 'skip' $all 193 269 } 194 270 195 271 bisect_state() { 196 272 bisect_autostart 197 273 state=$1 274 check_and_set_terms $state 198 275 case "$#,$state" in 199 276 0,*) 200 277 die "Please call 'bisect_state' with at least one argument." ;; 201 1,bad|1,good|1,skip) 202 rev=$(git rev-parse --verify HEAD) || 203 die "Bad rev input: HEAD" 278 1,"$TERM_BAD"|1,"$TERM_GOOD"|1,skip) 279 bisected_head=$(bisect_head) 280 rev=$(git rev-parse --verify "$bisected_head") || 281 die "$(eval_gettext "Bad rev input: \$bisected_head")" 204 282 bisect_write "$state" "$rev" 205 283 check_expected_revs "$rev" ;; 206 2, bad|*,good|*,skip)284 2,"$TERM_BAD"|*,"$TERM_GOOD"|*,skip) 207 285 shift 208 eval=''286 hash_list='' 209 287 for rev in "$@" 210 288 do 211 289 sha=$(git rev-parse --verify "$rev^{commit}") || 212 die "Bad rev input: $rev" 213 eval="$eval bisect_write '$state' '$sha'; " 290 die "$(eval_gettext "Bad rev input: \$rev")" 291 hash_list="$hash_list $sha" 292 done 293 for rev in $hash_list 294 do 295 bisect_write "$state" "$rev" 214 296 done 215 eval "$eval" 216 check_expected_revs "$@" ;; 217 *,bad) 218 die "'git bisect bad' can take only one argument." ;; 297 check_expected_revs $hash_list ;; 298 *,"$TERM_BAD") 299 die "$(eval_gettext "'git bisect \$TERM_BAD' can take only one argument.")" ;; 219 300 *) 220 301 usage ;; 221 302 esac … … 224 305 225 306 bisect_next_check() { 226 307 missing_good= missing_bad= 227 git show-ref -q --verify refs/bisect/ bad|| missing_bad=t228 test -n "$(git for-each-ref "refs/bisect/ good-*")" || missing_good=t308 git show-ref -q --verify refs/bisect/$TERM_BAD || missing_bad=t 309 test -n "$(git for-each-ref "refs/bisect/$TERM_GOOD-*")" || missing_good=t 229 310 230 311 case "$missing_good,$missing_bad,$1" in 231 312 ,,*) 232 : have both good and bad- ok313 : have both $TERM_GOOD and $TERM_BAD - ok 233 314 ;; 234 315 *,) 235 316 # do not have both but not asked to fail - just report. 236 317 false 237 318 ;; 238 t,, good)239 # have bad but not good. we could bisect although319 t,,"$TERM_GOOD") 320 # have bad (or new) but not good (or old). we could bisect although 240 321 # this is less optimum. 241 e cho >&2 'Warning: bisecting only with a bad commit.'322 eval_gettextln "Warning: bisecting only with a \$TERM_BAD commit." >&2 242 323 if test -t 0 243 324 then 244 printf >&2 'Are you sure [Y/n]? ' 325 # TRANSLATORS: Make sure to include [Y] and [n] in your 326 # translation. The program will only accept English input 327 # at this point. 328 gettext "Are you sure [Y/n]? " >&2 245 329 read yesno 246 330 case "$yesno" in [Nn]*) exit 1 ;; esac 247 331 fi 248 : bisect without good...332 : bisect without $TERM_GOOD... 249 333 ;; 250 334 *) 251 THEN='' 252 test -s "$GIT_DIR/BISECT_START" || { 253 echo >&2 'You need to start by "git bisect start".' 254 THEN='then ' 255 } 256 echo >&2 'You '$THEN'need to give me at least one good' \ 257 'and one bad revisions.' 258 echo >&2 '(You can use "git bisect bad" and' \ 259 '"git bisect good" for that.)' 335 bad_syn=$(bisect_voc bad) 336 good_syn=$(bisect_voc good) 337 if test -s "$GIT_DIR/BISECT_START" 338 then 339 340 eval_gettextln "You need to give me at least one \$bad_syn and one \$good_syn revision. 341 (You can use \"git bisect \$bad_syn\" and \"git bisect \$good_syn\" for that.)" >&2 342 else 343 eval_gettextln "You need to start by \"git bisect start\". 344 You then need to give me at least one \$good_syn and one \$bad_syn revision. 345 (You can use \"git bisect \$bad_syn\" and \"git bisect \$good_syn\" for that.)" >&2 346 fi 260 347 exit 1 ;; 261 348 esac 262 349 } … … 268 355 bisect_next() { 269 356 case "$#" in 0) ;; *) usage ;; esac 270 357 bisect_autostart 271 bisect_next_check good358 bisect_next_check $TERM_GOOD 272 359 273 360 # Perform all bisection computation, display and checkout 274 git bisect--helper --next-all 361 git bisect--helper --next-all $(test -f "$GIT_DIR/BISECT_HEAD" && echo --no-checkout) 275 362 res=$? 276 363 277 # Check if we should exit because bisection is finished 278 test $res -eq 10 && exit 0 364 # Check if we should exit because bisection is finished 365 if test $res -eq 10 366 then 367 bad_rev=$(git show-ref --hash --verify refs/bisect/$TERM_BAD) 368 bad_commit=$(git show-branch $bad_rev) 369 echo "# first $TERM_BAD commit: $bad_commit" >>"$GIT_DIR/BISECT_LOG" 370 exit 0 371 elif test $res -eq 2 372 then 373 echo "# only skipped commits left to test" >>"$GIT_DIR/BISECT_LOG" 374 good_revs=$(git for-each-ref --format="%(objectname)" "refs/bisect/$TERM_GOOD-*") 375 for skipped in $(git rev-list refs/bisect/$TERM_BAD --not $good_revs) 376 do 377 skipped_commit=$(git show-branch $skipped) 378 echo "# possible first $TERM_BAD commit: $skipped_commit" >>"$GIT_DIR/BISECT_LOG" 379 done 380 exit $res 381 fi 279 382 280 383 # Check for an error in the bisection process 281 384 test $res -ne 0 && exit $res … … 288 391 289 392 if test $# = 0 290 393 then 291 case "${DISPLAY+set}${SESSIONNAME+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" in 292 '') set git log ;; 293 set*) set gitk ;; 294 esac 394 if test -n "${DISPLAY+set}${SESSIONNAME+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" && 395 type gitk >/dev/null 2>&1 396 then 397 set gitk 398 else 399 set git log 400 fi 295 401 else 296 402 case "$1" in 297 403 git*|tig) ;; … … 305 411 306 412 bisect_reset() { 307 413 test -s "$GIT_DIR/BISECT_START" || { 308 echo"We are not bisecting."414 gettextln "We are not bisecting." 309 415 return 310 416 } 311 417 case "$#" in 312 418 0) branch=$(cat "$GIT_DIR/BISECT_START") ;; 313 1) git rev-parse --quiet --verify "$1^{commit}" > /dev/null || 314 die "'$1' is not a valid commit" 315 branch="$1" ;; 419 1) git rev-parse --quiet --verify "$1^{commit}" >/dev/null || { 420 invalid="$1" 421 die "$(eval_gettext "'\$invalid' is not a valid commit")" 422 } 423 branch="$1" ;; 316 424 *) 317 425 usage ;; 318 426 esac 319 git checkout "$branch" -- && bisect_clean_state 427 428 if ! test -f "$GIT_DIR/BISECT_HEAD" && ! git checkout "$branch" -- 429 then 430 die "$(eval_gettext "Could not check out original HEAD '\$branch'. 431 Try 'git bisect reset <commit>'.")" 432 fi 433 bisect_clean_state 320 434 } 321 435 322 436 bisect_clean_state() { … … 331 445 rm -f "$GIT_DIR/BISECT_LOG" && 332 446 rm -f "$GIT_DIR/BISECT_NAMES" && 333 447 rm -f "$GIT_DIR/BISECT_RUN" && 448 rm -f "$GIT_DIR/BISECT_TERMS" && 334 449 # Cleanup head-name if it got left by an old version of git-bisect 335 450 rm -f "$GIT_DIR/head-name" && 336 451 git update-ref -d --no-deref BISECT_HEAD && 452 # clean up BISECT_START last 337 453 rm -f "$GIT_DIR/BISECT_START" 338 454 } 339 455 340 456 bisect_replay () { 341 test -r "$1" || die "cannot read $1 for replaying" 457 file="$1" 458 test "$#" -eq 1 || die "$(gettext "No logfile given")" 459 test -r "$file" || die "$(eval_gettext "cannot read \$file for replaying")" 342 460 bisect_reset 343 461 while read git bisect command rev 344 462 do 345 test "$git $bisect" = "git bisect" -o "$git" = "git-bisect" || continue 346 if test "$git" = "git-bisect"; then 463 test "$git $bisect" = "git bisect" || test "$git" = "git-bisect" || continue 464 if test "$git" = "git-bisect" 465 then 347 466 rev="$command" 348 467 command="$bisect" 349 468 fi 469 get_terms 470 check_and_set_terms "$command" 350 471 case "$command" in 351 472 start) 352 473 cmd="bisect_start $rev" 353 474 eval "$cmd" ;; 354 good|bad|skip)475 "$TERM_GOOD"|"$TERM_BAD"|skip) 355 476 bisect_write "$command" "$rev" ;; 477 terms) 478 bisect_terms $rev ;; 356 479 *) 357 die " ?? what are you talking about?" ;;480 die "$(gettext "?? what are you talking about?")" ;; 358 481 esac 359 done <"$ 1"482 done <"$file" 360 483 bisect_auto_next 361 484 } 362 485 363 486 bisect_run () { 364 bisect_next_check fail 487 bisect_next_check fail 488 489 while true 490 do 491 command="$@" 492 eval_gettextln "running \$command" 493 "$@" 494 res=$? 495 496 # Check for really bad run error. 497 if [ $res -lt 0 -o $res -ge 128 ] 498 then 499 eval_gettextln "bisect run failed: 500 exit code \$res from '\$command' is < 0 or >= 128" >&2 501 exit $res 502 fi 503 504 # Find current state depending on run success or failure. 505 # A special exit code of 125 means cannot test. 506 if [ $res -eq 125 ] 507 then 508 state='skip' 509 elif [ $res -gt 0 ] 510 then 511 state="$TERM_BAD" 512 else 513 state="$TERM_GOOD" 514 fi 515 516 # We have to use a subshell because "bisect_state" can exit. 517 ( bisect_state $state >"$GIT_DIR/BISECT_RUN" ) 518 res=$? 519 520 cat "$GIT_DIR/BISECT_RUN" 521 522 if sane_grep "first $TERM_BAD commit could be any of" "$GIT_DIR/BISECT_RUN" \ 523 >/dev/null 524 then 525 gettextln "bisect run cannot continue any more" >&2 526 exit $res 527 fi 528 529 if [ $res -ne 0 ] 530 then 531 eval_gettextln "bisect run failed: 532 'bisect_state \$state' exited with error code \$res" >&2 533 exit $res 534 fi 535 536 if sane_grep "is the first $TERM_BAD commit" "$GIT_DIR/BISECT_RUN" >/dev/null 537 then 538 gettextln "bisect run success" 539 exit 0; 540 fi 541 542 done 543 } 544 545 bisect_log () { 546 test -s "$GIT_DIR/BISECT_LOG" || die "$(gettext "We are not bisecting.")" 547 cat "$GIT_DIR/BISECT_LOG" 548 } 549 550 get_terms () { 551 if test -s "$GIT_DIR/BISECT_TERMS" 552 then 553 { 554 read TERM_BAD 555 read TERM_GOOD 556 } <"$GIT_DIR/BISECT_TERMS" 557 fi 558 } 559 560 write_terms () { 561 TERM_BAD=$1 562 TERM_GOOD=$2 563 if test "$TERM_BAD" = "$TERM_GOOD" 564 then 565 die "$(gettext "please use two different terms")" 566 fi 567 check_term_format "$TERM_BAD" bad 568 check_term_format "$TERM_GOOD" good 569 printf '%s\n%s\n' "$TERM_BAD" "$TERM_GOOD" >"$GIT_DIR/BISECT_TERMS" 570 } 571 572 check_term_format () { 573 term=$1 574 git check-ref-format refs/bisect/"$term" || 575 die "$(eval_gettext "'\$term' is not a valid term")" 576 case "$term" in 577 help|start|terms|skip|next|reset|visualize|replay|log|run) 578 die "$(eval_gettext "can't use the builtin command '\$term' as a term")" 579 ;; 580 bad|new) 581 if test "$2" != bad 582 then 583 # In theory, nothing prevents swapping 584 # completely good and bad, but this situation 585 # could be confusing and hasn't been tested 586 # enough. Forbid it for now. 587 die "$(eval_gettext "can't change the meaning of term '\$term'")" 588 fi 589 ;; 590 good|old) 591 if test "$2" != good 592 then 593 die "$(eval_gettext "can't change the meaning of term '\$term'")" 594 fi 595 ;; 596 esac 597 } 365 598 366 while true 367 do 368 echo "running $@" 369 "$@" 370 res=$? 371 372 # Check for really bad run error. 373 if [ $res -lt 0 -o $res -ge 128 ]; then 374 echo >&2 "bisect run failed:" 375 echo >&2 "exit code $res from '$@' is < 0 or >= 128" 376 exit $res 377 fi 378 379 # Find current state depending on run success or failure. 380 # A special exit code of 125 means cannot test. 381 if [ $res -eq 125 ]; then 382 state='skip' 383 elif [ $res -gt 0 ]; then 384 state='bad' 385 else 386 state='good' 387 fi 388 389 # We have to use a subshell because "bisect_state" can exit. 390 ( bisect_state $state > "$GIT_DIR/BISECT_RUN" ) 391 res=$? 392 393 cat "$GIT_DIR/BISECT_RUN" 394 395 if sane_grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \ 396 > /dev/null; then 397 echo >&2 "bisect run cannot continue any more" 398 exit $res 399 fi 400 401 if [ $res -ne 0 ]; then 402 echo >&2 "bisect run failed:" 403 echo >&2 "'bisect_state $state' exited with error code $res" 404 exit $res 405 fi 406 407 if sane_grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null; then 408 echo "bisect run success" 409 exit 0; 410 fi 599 check_and_set_terms () { 600 cmd="$1" 601 case "$cmd" in 602 skip|start|terms) ;; 603 *) 604 if test -s "$GIT_DIR/BISECT_TERMS" && test "$cmd" != "$TERM_BAD" && test "$cmd" != "$TERM_GOOD" 605 then 606 die "$(eval_gettext "Invalid command: you're currently in a \$TERM_BAD/\$TERM_GOOD bisect.")" 607 fi 608 case "$cmd" in 609 bad|good) 610 if ! test -s "$GIT_DIR/BISECT_TERMS" 611 then 612 write_terms bad good 613 fi 614 ;; 615 new|old) 616 if ! test -s "$GIT_DIR/BISECT_TERMS" 617 then 618 write_terms new old 619 fi 620 ;; 621 esac ;; 622 esac 623 } 411 624 412 done 625 bisect_voc () { 626 case "$1" in 627 bad) echo "bad|new" ;; 628 good) echo "good|old" ;; 629 esac 413 630 } 414 631 632 bisect_terms () { 633 get_terms 634 if ! test -s "$GIT_DIR/BISECT_TERMS" 635 then 636 die "$(gettext "no terms defined")" 637 fi 638 case "$#" in 639 0) 640 gettextln "Your current terms are $TERM_GOOD for the old state 641 and $TERM_BAD for the new state." 642 ;; 643 1) 644 arg=$1 645 case "$arg" in 646 --term-good|--term-old) 647 printf '%s\n' "$TERM_GOOD" 648 ;; 649 --term-bad|--term-new) 650 printf '%s\n' "$TERM_BAD" 651 ;; 652 *) 653 die "$(eval_gettext "invalid argument \$arg for 'git bisect terms'. 654 Supported options are: --term-good|--term-old and --term-bad|--term-new.")" 655 ;; 656 esac 657 ;; 658 *) 659 usage ;; 660 esac 661 } 415 662 416 663 case "$#" in 417 664 0) 418 665 usage ;; 419 666 *) 420 cmd="$1" 421 shift 422 case "$cmd" in 423 help) 424 git bisect -h ;; 425 start) 426 bisect_start "$@" ;; 427 bad|good) 428 bisect_state "$cmd" "$@" ;; 429 skip) 430 bisect_skip "$@" ;; 431 next) 432 # Not sure we want "next" at the UI level anymore. 433 bisect_next "$@" ;; 434 visualize|view) 435 bisect_visualize "$@" ;; 436 reset) 437 bisect_reset "$@" ;; 438 replay) 439 bisect_replay "$@" ;; 440 log) 441 cat "$GIT_DIR/BISECT_LOG" ;; 442 run) 443 bisect_run "$@" ;; 444 *) 445 usage ;; 446 esac 667 cmd="$1" 668 get_terms 669 shift 670 case "$cmd" in 671 help) 672 git bisect -h ;; 673 start) 674 bisect_start "$@" ;; 675 bad|good|new|old|"$TERM_BAD"|"$TERM_GOOD") 676 bisect_state "$cmd" "$@" ;; 677 skip) 678 bisect_skip "$@" ;; 679 next) 680 # Not sure we want "next" at the UI level anymore. 681 bisect_next "$@" ;; 682 visualize|view) 683 bisect_visualize "$@" ;; 684 reset) 685 bisect_reset "$@" ;; 686 replay) 687 bisect_replay "$@" ;; 688 log) 689 bisect_log ;; 690 run) 691 bisect_run "$@" ;; 692 terms) 693 bisect_terms "$@" ;; 694 *) 695 usage ;; 696 esac 447 697 esac