Skip to content

Commit 4796e82

Browse files
jonseymourgitster
authored andcommitted
bisect: introduce --no-checkout support into porcelain.
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 <[email protected]> Improved-by: Junio C Hamano <[email protected]> Improved-by: Jonathan Nieder <[email protected]> Signed-off-by: Jon Seymour <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fee92fc commit 4796e82

File tree

1 file changed

+37
-11
lines changed

1 file changed

+37
-11
lines changed

git-bisect.sh

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'
44
LONG_USAGE='git bisect help
55
print this long help message.
6-
git bisect start [<bad> [<good>...]] [--] [<pathspec>...]
6+
git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]
77
reset bisect state and start bisection.
88
git bisect bad [<rev>]
99
mark <rev> a known-bad revision.
@@ -34,6 +34,16 @@ require_work_tree
3434
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
3535
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
3636

37+
bisect_head()
38+
{
39+
if test -f "$GIT_DIR/BISECT_HEAD"
40+
then
41+
echo BISECT_HEAD
42+
else
43+
echo HEAD
44+
fi
45+
}
46+
3747
bisect_autostart() {
3848
test -s "$GIT_DIR/BISECT_START" || {
3949
(
@@ -69,13 +79,19 @@ bisect_start() {
6979
orig_args=$(git rev-parse --sq-quote "$@")
7080
bad_seen=0
7181
eval=''
82+
mode=''
7283
while [ $# -gt 0 ]; do
7384
arg="$1"
7485
case "$arg" in
7586
--)
7687
shift
7788
break
7889
;;
90+
--no-checkout)
91+
mode=--no-checkout
92+
shift ;;
93+
--*)
94+
die "$(eval_gettext "unrecognised option: '\$arg'")" ;;
7995
*)
8096
rev=$(git rev-parse -q --verify "$arg^{commit}") || {
8197
test $has_double_dash -eq 1 &&
@@ -107,7 +123,10 @@ bisect_start() {
107123
then
108124
# Reset to the rev from where we started.
109125
start_head=$(cat "$GIT_DIR/BISECT_START")
110-
git checkout "$start_head" -- || exit
126+
if test "z$mode" != "z--no-checkout"
127+
then
128+
git checkout "$start_head" --
129+
fi
111130
else
112131
# Get rev from where we start.
113132
case "$head" in
@@ -143,7 +162,10 @@ bisect_start() {
143162
#
144163
# Write new start state.
145164
#
146-
echo "$start_head" >"$GIT_DIR/BISECT_START" &&
165+
echo "$start_head" >"$GIT_DIR/BISECT_START" && {
166+
test "z$mode" != "z--no-checkout" ||
167+
git update-ref --no-deref BISECT_HEAD "$start_head"
168+
} &&
147169
git rev-parse --sq-quote "$@" >"$GIT_DIR/BISECT_NAMES" &&
148170
eval "$eval true" &&
149171
echo "git bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit
@@ -206,8 +228,8 @@ bisect_state() {
206228
0,*)
207229
die "$(gettext "Please call 'bisect_state' with at least one argument.")" ;;
208230
1,bad|1,good|1,skip)
209-
rev=$(git rev-parse --verify HEAD) ||
210-
die "$(gettext "Bad rev input: HEAD")"
231+
rev=$(git rev-parse --verify $(bisect_head)) ||
232+
die "$(gettext "Bad rev input: $(bisect_head)")"
211233
bisect_write "$state" "$rev"
212234
check_expected_revs "$rev" ;;
213235
2,bad|*,good|*,skip)
@@ -291,7 +313,7 @@ bisect_next() {
291313
bisect_next_check good
292314

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

297319
# Check if we should exit because bisection is finished
@@ -340,12 +362,15 @@ bisect_reset() {
340362
*)
341363
usage ;;
342364
esac
343-
if git checkout "$branch" -- ; then
344-
bisect_clean_state
345-
else
346-
die "$(eval_gettext "Could not check out original HEAD '\$branch'.
365+
if ! test -f "$GIT_DIR/BISECT_HEAD"
366+
then
367+
if ! git checkout "$branch" --
368+
then
369+
die "$(eval_gettext "Could not check out original HEAD '\$branch'.
347370
Try 'git bisect reset <commit>'.")"
371+
fi
348372
fi
373+
bisect_clean_state
349374
}
350375

351376
bisect_clean_state() {
@@ -362,7 +387,8 @@ bisect_clean_state() {
362387
rm -f "$GIT_DIR/BISECT_RUN" &&
363388
# Cleanup head-name if it got left by an old version of git-bisect
364389
rm -f "$GIT_DIR/head-name" &&
365-
390+
git update-ref -d --no-deref BISECT_HEAD &&
391+
# clean up BISECT_START last
366392
rm -f "$GIT_DIR/BISECT_START"
367393
}
368394

0 commit comments

Comments
 (0)