3 USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'
4 LONG_USAGE='git bisect help
5 print this long help message.
6 git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]
7 reset bisect state and start bisection.
9 mark <rev> a known-bad revision.
10 git bisect good [<rev>...]
11 mark <rev>... known-good revisions.
12 git bisect skip [(<rev>|<range>)...]
13 mark <rev>... untestable revisions.
15 find next bisection to test and check it out.
16 git bisect reset [<commit>]
17 finish bisection search and go back to commit.
19 show bisect status in gitk.
20 git bisect replay <logfile>
24 git bisect run <cmd>...
25 use <cmd>... to automatically bisect.
27 Please use "git help bisect" to get the full man page.'
33 _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
34 _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
38 if test -f "$GIT_DIR/BISECT_HEAD"
47 test -s "$GIT_DIR/BISECT_START" || {
48 gettextln "You need to start by \"git bisect start\"" >&2
51 # TRANSLATORS: Make sure to include [Y] and [n] in your
52 # translation. The program will only accept English input
54 gettext "Do you want me to do it for you [Y/n]? " >&2
69 # Check for one bad and then some good revisions.
73 case "$arg" in --) has_double_dash=1; break ;; esac
75 orig_args=$(git rev-parse --sq-quote "$@")
78 if test "z$(git rev-parse --is-bare-repository)" != zfalse
84 while [ $# -gt 0 ]; do
95 die "$(eval_gettext "unrecognised option: '\$arg'")" ;;
97 rev=$(git rev-parse -q --verify "$arg^{commit}") || {
98 test $has_double_dash -eq 1 &&
99 die "$(eval_gettext "'\$arg' does not appear to be a valid revision")"
103 0) state='bad' ; bad_seen=1 ;;
106 eval="$eval bisect_write '$state' '$rev' 'nolog' &&"
115 head=$(GIT_DIR="$GIT_DIR" git symbolic-ref -q HEAD) ||
116 head=$(GIT_DIR="$GIT_DIR" git rev-parse --verify HEAD) ||
117 die "$(gettext "Bad HEAD - I need a HEAD")"
120 # Check if we are bisecting.
123 if test -s "$GIT_DIR/BISECT_START"
125 # Reset to the rev from where we started.
126 start_head=$(cat "$GIT_DIR/BISECT_START")
127 if test "z$mode" != "z--no-checkout"
129 git checkout "$start_head" -- ||
130 die "$(eval_gettext "Checking out '\$start_head' failed. Try 'git bisect reset <valid-branch>'.")"
133 # Get rev from where we start.
136 # This error message should only be triggered by
137 # cogito usage, and cogito users should understand
138 # it relates to cg-seek.
139 [ -s "$GIT_DIR/head-name" ] &&
140 die "$(gettext "won't bisect on cg-seek'ed tree")"
141 start_head="${head#refs/heads/}"
144 die "$(gettext "Bad HEAD - strange symbolic ref")"
150 # Get rid of any old bisect state.
152 bisect_clean_state || exit
156 # In case of mistaken revs or checkout error, or signals received,
157 # "bisect_auto_next" below may exit or misbehave.
158 # We have to trap this to be able to clean up using
159 # "bisect_clean_state".
161 trap 'bisect_clean_state' 0
162 trap 'exit 255' 1 2 3 15
165 # Write new start state.
167 echo "$start_head" >"$GIT_DIR/BISECT_START" && {
168 test "z$mode" != "z--no-checkout" ||
169 git update-ref --no-deref BISECT_HEAD "$start_head"
171 git rev-parse --sq-quote "$@" >"$GIT_DIR/BISECT_NAMES" &&
173 echo "git bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit
175 # Check if we can proceed to the next bisect state.
188 good|skip) tag="$state"-"$rev" ;;
189 *) die "$(eval_gettext "Bad bisect_write argument: \$state")" ;;
191 git update-ref "refs/bisect/$tag" "$rev" || exit
192 echo "# $state: $(git show-branch $rev)" >>"$GIT_DIR/BISECT_LOG"
193 test -n "$nolog" || echo "git bisect $state $rev" >>"$GIT_DIR/BISECT_LOG"
197 test -f "$GIT_DIR/BISECT_EXPECTED_REV" &&
198 test "$1" = $(cat "$GIT_DIR/BISECT_EXPECTED_REV")
201 check_expected_revs() {
203 if ! is_expected_rev "$_rev"
205 rm -f "$GIT_DIR/BISECT_ANCESTORS_OK"
206 rm -f "$GIT_DIR/BISECT_EXPECTED_REV"
218 revs=$(git rev-list "$arg") || die "$(eval_gettext "Bad rev input: \$arg")" ;;
220 revs=$(git rev-parse --sq-quote "$arg") ;;
224 eval bisect_state 'skip' $all
232 die "$(gettext "Please call 'bisect_state' with at least one argument.")" ;;
234 rev=$(git rev-parse --verify $(bisect_head)) ||
235 die "$(gettext "Bad rev input: $(bisect_head)")"
236 bisect_write "$state" "$rev"
237 check_expected_revs "$rev" ;;
243 sha=$(git rev-parse --verify "$rev^{commit}") ||
244 die "$(eval_gettext "Bad rev input: \$rev")"
245 hash_list="$hash_list $sha"
247 for rev in $hash_list
249 bisect_write "$state" "$rev"
251 check_expected_revs $hash_list ;;
253 die "$(gettext "'git bisect bad' can take only one argument.")" ;;
260 bisect_next_check() {
261 missing_good= missing_bad=
262 git show-ref -q --verify refs/bisect/bad || missing_bad=t
263 test -n "$(git for-each-ref "refs/bisect/good-*")" || missing_good=t
265 case "$missing_good,$missing_bad,$1" in
267 : have both good and bad - ok
270 # do not have both but not asked to fail - just report.
274 # have bad but not good. we could bisect although
275 # this is less optimum.
276 gettextln "Warning: bisecting only with a bad commit." >&2
279 # TRANSLATORS: Make sure to include [Y] and [n] in your
280 # translation. The program will only accept English input
282 gettext "Are you sure [Y/n]? " >&2
284 case "$yesno" in [Nn]*) exit 1 ;; esac
286 : bisect without good...
290 if test -s "$GIT_DIR/BISECT_START"
292 gettextln "You need to give me at least one good and one bad revision.
293 (You can use \"git bisect bad\" and \"git bisect good\" for that.)" >&2
295 gettextln "You need to start by \"git bisect start\".
296 You then need to give me at least one good and one bad revision.
297 (You can use \"git bisect bad\" and \"git bisect good\" for that.)" >&2
304 bisect_next_check && bisect_next || :
308 case "$#" in 0) ;; *) usage ;; esac
310 bisect_next_check good
312 # Perform all bisection computation, display and checkout
313 git bisect--helper --next-all $(test -f "$GIT_DIR/BISECT_HEAD" && echo --no-checkout)
316 # Check if we should exit because bisection is finished
319 bad_rev=$(git show-ref --hash --verify refs/bisect/bad)
320 bad_commit=$(git show-branch $bad_rev)
321 echo "# first bad commit: $bad_commit" >>"$GIT_DIR/BISECT_LOG"
325 echo "# only skipped commits left to test" >>"$GIT_DIR/BISECT_LOG"
326 good_revs=$(git for-each-ref --format="%(objectname)" "refs/bisect/good-*")
327 for skipped in $(git rev-list refs/bisect/bad --not $good_revs)
329 skipped_commit=$(git show-branch $skipped)
330 echo "# possible first bad commit: $skipped_commit" >>"$GIT_DIR/BISECT_LOG"
335 # Check for an error in the bisection process
336 test $res -ne 0 && exit $res
342 bisect_next_check fail
346 if test -n "${DISPLAY+set}${SESSIONNAME+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" &&
347 type gitk >/dev/null 2>&1
356 -*) set git log "$@" ;;
361 eval '"$@"' --bisect -- $(cat "$GIT_DIR/BISECT_NAMES")
365 test -s "$GIT_DIR/BISECT_START" || {
366 gettextln "We are not bisecting."
370 0) branch=$(cat "$GIT_DIR/BISECT_START") ;;
371 1) git rev-parse --quiet --verify "$1^{commit}" >/dev/null || {
373 die "$(eval_gettext "'\$invalid' is not a valid commit")"
380 if ! test -f "$GIT_DIR/BISECT_HEAD" && ! git checkout "$branch" --
382 die "$(eval_gettext "Could not check out original HEAD '\$branch'.
383 Try 'git bisect reset <commit>'.")"
388 bisect_clean_state() {
389 # There may be some refs packed during bisection.
390 git for-each-ref --format='%(refname) %(objectname)' refs/bisect/\* |
393 git update-ref -d $ref $hash || exit
395 rm -f "$GIT_DIR/BISECT_EXPECTED_REV" &&
396 rm -f "$GIT_DIR/BISECT_ANCESTORS_OK" &&
397 rm -f "$GIT_DIR/BISECT_LOG" &&
398 rm -f "$GIT_DIR/BISECT_NAMES" &&
399 rm -f "$GIT_DIR/BISECT_RUN" &&
400 # Cleanup head-name if it got left by an old version of git-bisect
401 rm -f "$GIT_DIR/head-name" &&
402 git update-ref -d --no-deref BISECT_HEAD &&
403 # clean up BISECT_START last
404 rm -f "$GIT_DIR/BISECT_START"
409 test "$#" -eq 1 || die "$(gettext "No logfile given")"
410 test -r "$file" || die "$(eval_gettext "cannot read \$file for replaying")"
412 while read git bisect command rev
414 test "$git $bisect" = "git bisect" || test "$git" = "git-bisect" || continue
415 if test "$git" = "git-bisect"
422 cmd="bisect_start $rev"
425 bisect_write "$command" "$rev" ;;
427 die "$(gettext "?? what are you talking about?")" ;;
434 bisect_next_check fail
439 eval_gettextln "running \$command"
443 # Check for really bad run error.
444 if [ $res -lt 0 -o $res -ge 128 ]
446 eval_gettextln "bisect run failed:
447 exit code \$res from '\$command' is < 0 or >= 128" >&2
451 # Find current state depending on run success or failure.
452 # A special exit code of 125 means cannot test.
463 # We have to use a subshell because "bisect_state" can exit.
464 ( bisect_state $state >"$GIT_DIR/BISECT_RUN" )
467 cat "$GIT_DIR/BISECT_RUN"
469 if sane_grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \
472 gettextln "bisect run cannot continue any more" >&2
478 eval_gettextln "bisect run failed:
479 'bisect_state \$state' exited with error code \$res" >&2
483 if sane_grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" >/dev/null
485 gettextln "bisect run success"
493 test -s "$GIT_DIR/BISECT_LOG" || die "$(gettext "We are not bisecting.")"
494 cat "$GIT_DIR/BISECT_LOG"
509 bisect_state "$cmd" "$@" ;;
513 # Not sure we want "next" at the UI level anymore.
516 bisect_visualize "$@" ;;
520 bisect_replay "$@" ;;