Skip to content

Commit

Permalink
bisect: introduce --no-checkout support into porcelain.
Browse files Browse the repository at this point in the history
git-bisect can now perform bisection of a history without performing
a checkout at each stage of the bisection process. Instead, HEAD is updated.

One use-case for this function is allow git bisect to be used with
damaged repositories where git checkout would fail because the tree
referenced by the commit is damaged.

It can also be used in other cases where actual checkout of the tree
is not required to progress the bisection.

Improved-by: Christian Couder <chriscool@tuxfamily.org>
Improved-by: Junio C Hamano <gitster@pobox.com>
Improved-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jon Seymour authored and Junio C Hamano committed Aug 4, 2011
1 parent fee92fc commit 4796e82
Showing 1 changed file with 37 additions and 11 deletions.
48 changes: 37 additions & 11 deletions git-bisect.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'
LONG_USAGE='git bisect help
print this long help message.
git bisect start [<bad> [<good>...]] [--] [<pathspec>...]
git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]
reset bisect state and start bisection.
git bisect bad [<rev>]
mark <rev> a known-bad revision.
Expand Down Expand Up @@ -34,6 +34,16 @@ require_work_tree
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"

bisect_head()
{
if test -f "$GIT_DIR/BISECT_HEAD"
then
echo BISECT_HEAD
else
echo HEAD
fi
}

bisect_autostart() {
test -s "$GIT_DIR/BISECT_START" || {
(
Expand Down Expand Up @@ -69,13 +79,19 @@ bisect_start() {
orig_args=$(git rev-parse --sq-quote "$@")
bad_seen=0
eval=''
mode=''
while [ $# -gt 0 ]; do
arg="$1"
case "$arg" in
--)
shift
break
;;
--no-checkout)
mode=--no-checkout
shift ;;
--*)
die "$(eval_gettext "unrecognised option: '\$arg'")" ;;
*)
rev=$(git rev-parse -q --verify "$arg^{commit}") || {
test $has_double_dash -eq 1 &&
Expand Down Expand Up @@ -107,7 +123,10 @@ bisect_start() {
then
# Reset to the rev from where we started.
start_head=$(cat "$GIT_DIR/BISECT_START")
git checkout "$start_head" -- || exit
if test "z$mode" != "z--no-checkout"
then
git checkout "$start_head" --
fi
else
# Get rev from where we start.
case "$head" in
Expand Down Expand Up @@ -143,7 +162,10 @@ bisect_start() {
#
# Write new start state.
#
echo "$start_head" >"$GIT_DIR/BISECT_START" &&
echo "$start_head" >"$GIT_DIR/BISECT_START" && {
test "z$mode" != "z--no-checkout" ||
git update-ref --no-deref BISECT_HEAD "$start_head"
} &&
git rev-parse --sq-quote "$@" >"$GIT_DIR/BISECT_NAMES" &&
eval "$eval true" &&
echo "git bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit
Expand Down Expand Up @@ -206,8 +228,8 @@ bisect_state() {
0,*)
die "$(gettext "Please call 'bisect_state' with at least one argument.")" ;;
1,bad|1,good|1,skip)
rev=$(git rev-parse --verify HEAD) ||
die "$(gettext "Bad rev input: HEAD")"
rev=$(git rev-parse --verify $(bisect_head)) ||
die "$(gettext "Bad rev input: $(bisect_head)")"
bisect_write "$state" "$rev"
check_expected_revs "$rev" ;;
2,bad|*,good|*,skip)
Expand Down Expand Up @@ -291,7 +313,7 @@ bisect_next() {
bisect_next_check good

# Perform all bisection computation, display and checkout
git bisect--helper --next-all
git bisect--helper --next-all $(test -f "$GIT_DIR/BISECT_HEAD" && echo --no-checkout)
res=$?

# Check if we should exit because bisection is finished
Expand Down Expand Up @@ -340,12 +362,15 @@ bisect_reset() {
*)
usage ;;
esac
if git checkout "$branch" -- ; then
bisect_clean_state
else
die "$(eval_gettext "Could not check out original HEAD '\$branch'.
if ! test -f "$GIT_DIR/BISECT_HEAD"
then
if ! git checkout "$branch" --
then
die "$(eval_gettext "Could not check out original HEAD '\$branch'.
Try 'git bisect reset <commit>'.")"
fi
fi
bisect_clean_state
}

bisect_clean_state() {
Expand All @@ -362,7 +387,8 @@ bisect_clean_state() {
rm -f "$GIT_DIR/BISECT_RUN" &&
# Cleanup head-name if it got left by an old version of git-bisect
rm -f "$GIT_DIR/head-name" &&

git update-ref -d --no-deref BISECT_HEAD &&
# clean up BISECT_START last
rm -f "$GIT_DIR/BISECT_START"
}

Expand Down

0 comments on commit 4796e82

Please sign in to comment.