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 <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>
Jon Seymour committed
Aug 4, 2011 at 22:01 UTC
4796e823a3d24d29dbcccfda166d6c88051cbfaa
1 file changed
+37
-11
git-bisect.sh
+37
-11
@@ -3,7 +3,7 @@
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 [<bad> [<good>...]] [--] [<pathspec>...]
6
+git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]
7
reset bisect state and start bisection.
8
git bisect bad [<rev>]
9
mark <rev> a known-bad revision.
@@ -34,6 +34,16 @@ require_work_tree
34
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
35
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
36
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
+
47
bisect_autostart() {
48
test -s "$GIT_DIR/BISECT_START" || {
49
(
@@ -69,6 +79,7 @@ bisect_start() {
79
orig_args=$(git rev-parse --sq-quote "$@")
80
bad_seen=0
81
eval=''
82
+ mode=''
83
while [ $# -gt 0 ]; do
84
arg="$1"
85
case "$arg" in
@@ -76,6 +87,11 @@ bisect_start() {
87
shift
88
break
89
;;
90
+ --no-checkout)
91
+ mode=--no-checkout
92
+ shift ;;
93
+ --*)
94
+ die "$(eval_gettext "unrecognised option: '\$arg'")" ;;
95
*)
96
rev=$(git rev-parse -q --verify "$arg^{commit}") || {
97
test $has_double_dash -eq 1 &&
@@ -107,7 +123,10 @@ bisect_start() {
123
then
124
# Reset to the rev from where we started.
125
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
130
else
131
# Get rev from where we start.
132
case "$head" in
@@ -143,7 +162,10 @@ bisect_start() {
162
#
163
# Write new start state.
164
#
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
+ } &&
169
git rev-parse --sq-quote "$@" >"$GIT_DIR/BISECT_NAMES" &&
170
eval "$eval true" &&
171
echo "git bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit
@@ -206,8 +228,8 @@ bisect_state() {
228
0,*)
229
die "$(gettext "Please call 'bisect_state' with at least one argument.")" ;;
230
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)")"
233
bisect_write "$state" "$rev"
234
check_expected_revs "$rev" ;;
235
2,bad|*,good|*,skip)
@@ -291,7 +313,7 @@ bisect_next() {
313
bisect_next_check good
314
315
# 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)
317
res=$?
318
319
# Check if we should exit because bisection is finished
@@ -340,12 +362,15 @@ bisect_reset() {
362
*)
363
usage ;;
364
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'.
370
Try 'git bisect reset <commit>'.")"
371
+ fi
372
fi
373
+ bisect_clean_state
374
}
375
376
bisect_clean_state() {
@@ -362,7 +387,8 @@ bisect_clean_state() {
387
rm -f "$GIT_DIR/BISECT_RUN" &&
388
# Cleanup head-name if it got left by an old version of git-bisect
389
rm -f "$GIT_DIR/head-name" &&
365
-
390
+ git update-ref -d --no-deref BISECT_HEAD &&
391
+ # clean up BISECT_START last
392
rm -f "$GIT_DIR/BISECT_START"
393
}
394