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 <validbranch>'.")"
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 seeked 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 eval="$eval bisect_write '$state' '$sha'; "
248 check_expected_revs "$@" ;;
250 die "$(gettext "'git bisect bad' can take only one argument.")" ;;
257 bisect_next_check() {
258 missing_good= missing_bad=
259 git show-ref -q --verify refs/bisect/bad || missing_bad=t
260 test -n "$(git for-each-ref "refs/bisect/good-*")" || missing_good=t
262 case "$missing_good,$missing_bad,$1" in
264 : have both good and bad - ok
267 # do not have both but not asked to fail - just report.
271 # have bad but not good. we could bisect although
272 # this is less optimum.
273 gettextln "Warning: bisecting only with a bad commit." >&2
276 # TRANSLATORS: Make sure to include [Y] and [n] in your
277 # translation. The program will only accept English input
279 gettext "Are you sure [Y/n]? " >&2
281 case "$yesno" in [Nn]*) exit 1 ;; esac
283 : bisect without good...
287 if test -s "$GIT_DIR/BISECT_START"
289 gettextln "You need to give me at least one good and one bad revisions.
290 (You can use \"git bisect bad\" and \"git bisect good\" for that.)" >&2
292 gettextln "You need to start by \"git bisect start\".
293 You then need to give me at least one good and one bad revisions.
294 (You can use \"git bisect bad\" and \"git bisect good\" for that.)" >&2
301 bisect_next_check && bisect_next || :
305 case "$#" in 0) ;; *) usage ;; esac
307 bisect_next_check good
309 # Perform all bisection computation, display and checkout
310 git bisect--helper --next-all $(test -f "$GIT_DIR/BISECT_HEAD" && echo --no-checkout)
313 # Check if we should exit because bisection is finished
316 bad_rev=$(git show-ref --hash --verify refs/bisect/bad)
317 bad_commit=$(git show-branch $bad_rev)
318 echo "# first bad commit: $bad_commit" >>"$GIT_DIR/BISECT_LOG"
322 echo "# only skipped commits left to test" >>"$GIT_DIR/BISECT_LOG"
323 good_revs=$(git for-each-ref --format="--not %(objectname)" "refs/bisect/good-*")
324 for skipped in $(git rev-list refs/bisect/bad $good_revs)
326 skipped_commit=$(git show-branch $skipped)
327 echo "# possible first bad commit: $skipped_commit" >>"$GIT_DIR/BISECT_LOG"
332 # Check for an error in the bisection process
333 test $res -ne 0 && exit $res
339 bisect_next_check fail
343 if test -n "${DISPLAY+set}${SESSIONNAME+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" &&
344 type gitk >/dev/null 2>&1
353 -*) set git log "$@" ;;
358 eval '"$@"' --bisect -- $(cat "$GIT_DIR/BISECT_NAMES")
362 test -s "$GIT_DIR/BISECT_START" || {
363 gettextln "We are not bisecting."
367 0) branch=$(cat "$GIT_DIR/BISECT_START") ;;
368 1) git rev-parse --quiet --verify "$1^{commit}" > /dev/null || {
370 die "$(eval_gettext "'\$invalid' is not a valid commit")"
377 if ! test -f "$GIT_DIR/BISECT_HEAD" && ! git checkout "$branch" --
379 die "$(eval_gettext "Could not check out original HEAD '\$branch'.
380 Try 'git bisect reset <commit>'.")"
385 bisect_clean_state() {
386 # There may be some refs packed during bisection.
387 git for-each-ref --format='%(refname) %(objectname)' refs/bisect/\* |
390 git update-ref -d $ref $hash || exit
392 rm -f "$GIT_DIR/BISECT_EXPECTED_REV" &&
393 rm -f "$GIT_DIR/BISECT_ANCESTORS_OK" &&
394 rm -f "$GIT_DIR/BISECT_LOG" &&
395 rm -f "$GIT_DIR/BISECT_NAMES" &&
396 rm -f "$GIT_DIR/BISECT_RUN" &&
397 # Cleanup head-name if it got left by an old version of git-bisect
398 rm -f "$GIT_DIR/head-name" &&
399 git update-ref -d --no-deref BISECT_HEAD &&
400 # clean up BISECT_START last
401 rm -f "$GIT_DIR/BISECT_START"
406 test "$#" -eq 1 || die "$(gettext "No logfile given")"
407 test -r "$file" || die "$(eval_gettext "cannot read \$file for replaying")"
409 while read git bisect command rev
411 test "$git $bisect" = "git bisect" -o "$git" = "git-bisect" || continue
412 if test "$git" = "git-bisect"
419 cmd="bisect_start $rev"
422 bisect_write "$command" "$rev" ;;
424 die "$(gettext "?? what are you talking about?")" ;;
431 bisect_next_check fail
436 eval_gettextln "running \$command"
440 # Check for really bad run error.
441 if [ $res -lt 0 -o $res -ge 128 ]
443 eval_gettextln "bisect run failed:
444 exit code \$res from '\$command' is < 0 or >= 128" >&2
448 # Find current state depending on run success or failure.
449 # A special exit code of 125 means cannot test.
460 # We have to use a subshell because "bisect_state" can exit.
461 ( bisect_state $state > "$GIT_DIR/BISECT_RUN" )
464 cat "$GIT_DIR/BISECT_RUN"
466 if sane_grep "first bad commit could be any of" "$GIT_DIR/BISECT_RUN" \
469 gettextln "bisect run cannot continue any more" >&2
475 eval_gettextln "bisect run failed:
476 'bisect_state \$state' exited with error code \$res" >&2
480 if sane_grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null
482 gettextln "bisect run success"
490 test -s "$GIT_DIR/BISECT_LOG" || die "$(gettext "We are not bisecting.")"
491 cat "$GIT_DIR/BISECT_LOG"
506 bisect_state "$cmd" "$@" ;;
510 # Not sure we want "next" at the UI level anymore.
513 bisect_visualize "$@" ;;
517 bisect_replay "$@" ;;