Merge branch 'cc/bisect'
* cc/bisect: bisect: use a detached HEAD to bisect bisect: trap critical errors in "bisect_start" bisect: fix left over "BISECT_START" file when starting with junk rev bisect: add test cases to check that "git bisect start" is atomicmaint
commit
325566cc5d
|
@ -63,40 +63,40 @@ bisect_autostart() {
|
||||||
|
|
||||||
bisect_start() {
|
bisect_start() {
|
||||||
#
|
#
|
||||||
# Verify HEAD. If we were bisecting before this, reset to the
|
# Verify HEAD.
|
||||||
# top-of-line master first!
|
|
||||||
#
|
#
|
||||||
head=$(GIT_DIR="$GIT_DIR" git symbolic-ref -q HEAD) ||
|
head=$(GIT_DIR="$GIT_DIR" git symbolic-ref -q HEAD) ||
|
||||||
head=$(GIT_DIR="$GIT_DIR" git rev-parse --verify HEAD) ||
|
head=$(GIT_DIR="$GIT_DIR" git rev-parse --verify HEAD) ||
|
||||||
die "Bad HEAD - I need a HEAD"
|
die "Bad HEAD - I need a HEAD"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check that we either already have BISECT_START, or that the
|
# Check if we are bisecting.
|
||||||
# branches bisect, new-bisect don't exist, to not override them.
|
|
||||||
#
|
#
|
||||||
test -s "$GIT_DIR/BISECT_START" ||
|
|
||||||
if git show-ref --verify -q refs/heads/bisect ||
|
|
||||||
git show-ref --verify -q refs/heads/new-bisect; then
|
|
||||||
die 'The branches "bisect" and "new-bisect" must not exist.'
|
|
||||||
fi
|
|
||||||
start_head=''
|
start_head=''
|
||||||
|
if test -s "$GIT_DIR/BISECT_START"
|
||||||
|
then
|
||||||
|
# Reset to the rev from where we started.
|
||||||
|
start_head=$(cat "$GIT_DIR/BISECT_START")
|
||||||
|
git checkout "$start_head" || exit
|
||||||
|
else
|
||||||
|
# Get rev from where we start.
|
||||||
case "$head" in
|
case "$head" in
|
||||||
refs/heads/bisect)
|
|
||||||
branch=`cat "$GIT_DIR/BISECT_START"`
|
|
||||||
git checkout $branch || exit
|
|
||||||
;;
|
|
||||||
refs/heads/*|$_x40)
|
refs/heads/*|$_x40)
|
||||||
# This error message should only be triggered by cogito usage,
|
# This error message should only be triggered by
|
||||||
# and cogito users should understand it relates to cg-seek.
|
# cogito usage, and cogito users should understand
|
||||||
[ -s "$GIT_DIR/head-name" ] && die "won't bisect on seeked tree"
|
# it relates to cg-seek.
|
||||||
|
[ -s "$GIT_DIR/head-name" ] &&
|
||||||
|
die "won't bisect on seeked tree"
|
||||||
start_head="${head#refs/heads/}"
|
start_head="${head#refs/heads/}"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
die "Bad HEAD - strange symbolic ref"
|
die "Bad HEAD - strange symbolic ref"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
#
|
#
|
||||||
# Get rid of any old bisect state
|
# Get rid of any old bisect state.
|
||||||
#
|
#
|
||||||
bisect_clean_state
|
bisect_clean_state
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ bisect_start() {
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
rev=$(git rev-parse --verify "$arg^{commit}" 2>/dev/null) || {
|
rev=$(git rev-parse -q --verify "$arg^{commit}") || {
|
||||||
test $has_double_dash -eq 1 &&
|
test $has_double_dash -eq 1 &&
|
||||||
die "'$arg' does not appear to be a valid revision"
|
die "'$arg' does not appear to be a valid revision"
|
||||||
break
|
break
|
||||||
|
@ -133,11 +133,29 @@ bisect_start() {
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
sq "$@" >"$GIT_DIR/BISECT_NAMES"
|
#
|
||||||
test -n "$start_head" && echo "$start_head" >"$GIT_DIR/BISECT_START"
|
# Change state.
|
||||||
eval "$eval"
|
# In case of mistaken revs or checkout error, or signals received,
|
||||||
echo "git-bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG"
|
# "bisect_auto_next" below may exit or misbehave.
|
||||||
|
# We have to trap this to be able to clean up using
|
||||||
|
# "bisect_clean_state".
|
||||||
|
#
|
||||||
|
trap 'bisect_clean_state' 0
|
||||||
|
trap 'exit 255' 1 2 3 15
|
||||||
|
|
||||||
|
#
|
||||||
|
# Write new start state.
|
||||||
|
#
|
||||||
|
sq "$@" >"$GIT_DIR/BISECT_NAMES" &&
|
||||||
|
echo "$start_head" >"$GIT_DIR/BISECT_START" &&
|
||||||
|
eval "$eval" &&
|
||||||
|
echo "git-bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit
|
||||||
|
#
|
||||||
|
# Check if we can proceed to the next bisect state.
|
||||||
|
#
|
||||||
bisect_auto_next
|
bisect_auto_next
|
||||||
|
|
||||||
|
trap '-' 0
|
||||||
}
|
}
|
||||||
|
|
||||||
bisect_write() {
|
bisect_write() {
|
||||||
|
@ -149,9 +167,9 @@ bisect_write() {
|
||||||
good|skip) tag="$state"-"$rev" ;;
|
good|skip) tag="$state"-"$rev" ;;
|
||||||
*) die "Bad bisect_write argument: $state" ;;
|
*) die "Bad bisect_write argument: $state" ;;
|
||||||
esac
|
esac
|
||||||
git update-ref "refs/bisect/$tag" "$rev"
|
git update-ref "refs/bisect/$tag" "$rev" || exit
|
||||||
echo "# $state: $(git show-branch $rev)" >>"$GIT_DIR/BISECT_LOG"
|
echo "# $state: $(git show-branch $rev)" >>"$GIT_DIR/BISECT_LOG"
|
||||||
test -z "$nolog" && echo "git-bisect $state $rev" >>"$GIT_DIR/BISECT_LOG"
|
test -n "$nolog" || echo "git-bisect $state $rev" >>"$GIT_DIR/BISECT_LOG"
|
||||||
}
|
}
|
||||||
|
|
||||||
bisect_state() {
|
bisect_state() {
|
||||||
|
@ -348,9 +366,7 @@ bisect_next() {
|
||||||
exit_if_skipped_commits "$bisect_rev"
|
exit_if_skipped_commits "$bisect_rev"
|
||||||
|
|
||||||
echo "Bisecting: $bisect_nr revisions left to test after this"
|
echo "Bisecting: $bisect_nr revisions left to test after this"
|
||||||
git branch -D new-bisect 2> /dev/null
|
git checkout -q "$bisect_rev" || exit
|
||||||
git checkout -q -b new-bisect "$bisect_rev" || exit
|
|
||||||
git branch -M new-bisect bisect
|
|
||||||
git show-branch "$bisect_rev"
|
git show-branch "$bisect_rev"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,24 +408,22 @@ bisect_reset() {
|
||||||
*)
|
*)
|
||||||
usage ;;
|
usage ;;
|
||||||
esac
|
esac
|
||||||
if git checkout "$branch"; then
|
git checkout "$branch" && bisect_clean_state
|
||||||
# Cleanup head-name if it got left by an old version of git-bisect
|
|
||||||
rm -f "$GIT_DIR/head-name"
|
|
||||||
rm -f "$GIT_DIR/BISECT_START"
|
|
||||||
bisect_clean_state
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bisect_clean_state() {
|
bisect_clean_state() {
|
||||||
# There may be some refs packed during bisection.
|
# There may be some refs packed during bisection.
|
||||||
git for-each-ref --format='%(refname) %(objectname)' refs/bisect/\* refs/heads/bisect |
|
git for-each-ref --format='%(refname) %(objectname)' refs/bisect/\* |
|
||||||
while read ref hash
|
while read ref hash
|
||||||
do
|
do
|
||||||
git update-ref -d $ref $hash
|
git update-ref -d $ref $hash
|
||||||
done
|
done
|
||||||
|
rm -f "$GIT_DIR/BISECT_START"
|
||||||
rm -f "$GIT_DIR/BISECT_LOG"
|
rm -f "$GIT_DIR/BISECT_LOG"
|
||||||
rm -f "$GIT_DIR/BISECT_NAMES"
|
rm -f "$GIT_DIR/BISECT_NAMES"
|
||||||
rm -f "$GIT_DIR/BISECT_RUN"
|
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"
|
||||||
}
|
}
|
||||||
|
|
||||||
bisect_replay () {
|
bisect_replay () {
|
||||||
|
|
|
@ -126,6 +126,47 @@ test_expect_success 'bisect reset removes packed refs' '
|
||||||
test -z "$(git for-each-ref "refs/heads/bisect")"
|
test -z "$(git for-each-ref "refs/heads/bisect")"
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'bisect start: back in good branch' '
|
||||||
|
git branch > branch.output &&
|
||||||
|
grep "* other" branch.output > /dev/null &&
|
||||||
|
git bisect start $HASH4 $HASH1 -- &&
|
||||||
|
git bisect good &&
|
||||||
|
git bisect start $HASH4 $HASH1 -- &&
|
||||||
|
git bisect bad &&
|
||||||
|
git bisect reset &&
|
||||||
|
git branch > branch.output &&
|
||||||
|
grep "* other" branch.output > /dev/null
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'bisect start: no ".git/BISECT_START" if junk rev' '
|
||||||
|
git bisect start $HASH4 $HASH1 -- &&
|
||||||
|
git bisect good &&
|
||||||
|
test_must_fail git bisect start $HASH4 foo -- &&
|
||||||
|
git branch > branch.output &&
|
||||||
|
grep "* other" branch.output > /dev/null &&
|
||||||
|
test_must_fail test -e .git/BISECT_START
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'bisect start: no ".git/BISECT_START" if mistaken rev' '
|
||||||
|
git bisect start $HASH4 $HASH1 -- &&
|
||||||
|
git bisect good &&
|
||||||
|
test_must_fail git bisect start $HASH1 $HASH4 -- &&
|
||||||
|
git branch > branch.output &&
|
||||||
|
grep "* other" branch.output > /dev/null &&
|
||||||
|
test_must_fail test -e .git/BISECT_START
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'bisect start: no ".git/BISECT_START" if checkout error' '
|
||||||
|
echo "temp stuff" > hello &&
|
||||||
|
test_must_fail git bisect start $HASH4 $HASH1 -- &&
|
||||||
|
git branch &&
|
||||||
|
git branch > branch.output &&
|
||||||
|
grep "* other" branch.output > /dev/null &&
|
||||||
|
test_must_fail test -e .git/BISECT_START &&
|
||||||
|
test -z "$(git for-each-ref "refs/bisect/*")" &&
|
||||||
|
git checkout HEAD hello
|
||||||
|
'
|
||||||
|
|
||||||
# $HASH1 is good, $HASH4 is bad, we skip $HASH3
|
# $HASH1 is good, $HASH4 is bad, we skip $HASH3
|
||||||
# but $HASH2 is bad,
|
# but $HASH2 is bad,
|
||||||
# so we should find $HASH2 as the first bad commit
|
# so we should find $HASH2 as the first bad commit
|
||||||
|
@ -281,25 +322,6 @@ test_expect_success 'bisect starting with a detached HEAD' '
|
||||||
test $HEAD = $(cat .git/BISECT_START) &&
|
test $HEAD = $(cat .git/BISECT_START) &&
|
||||||
git bisect reset &&
|
git bisect reset &&
|
||||||
test $HEAD = $(git rev-parse --verify HEAD)
|
test $HEAD = $(git rev-parse --verify HEAD)
|
||||||
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'bisect refuses to start if branch bisect exists' '
|
|
||||||
git bisect reset &&
|
|
||||||
git branch bisect &&
|
|
||||||
test_must_fail git bisect start &&
|
|
||||||
git branch -d bisect &&
|
|
||||||
git checkout -b bisect &&
|
|
||||||
test_must_fail git bisect start &&
|
|
||||||
git checkout master &&
|
|
||||||
git branch -d bisect
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'bisect refuses to start if branch new-bisect exists' '
|
|
||||||
git bisect reset &&
|
|
||||||
git branch new-bisect &&
|
|
||||||
test_must_fail git bisect start &&
|
|
||||||
git branch -d new-bisect
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'bisect errors out if bad and good are mistaken' '
|
test_expect_success 'bisect errors out if bad and good are mistaken' '
|
||||||
|
@ -309,6 +331,25 @@ test_expect_success 'bisect errors out if bad and good are mistaken' '
|
||||||
git bisect reset
|
git bisect reset
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'bisect does not create a "bisect" branch' '
|
||||||
|
git bisect reset &&
|
||||||
|
git bisect start $HASH7 $HASH1 &&
|
||||||
|
git branch bisect &&
|
||||||
|
rev_hash4=$(git rev-parse --verify HEAD) &&
|
||||||
|
test "$rev_hash4" = "$HASH4" &&
|
||||||
|
git branch -D bisect &&
|
||||||
|
git bisect good &&
|
||||||
|
git branch bisect &&
|
||||||
|
rev_hash6=$(git rev-parse --verify HEAD) &&
|
||||||
|
test "$rev_hash6" = "$HASH6" &&
|
||||||
|
git bisect good > my_bisect_log.txt &&
|
||||||
|
grep "$HASH7 is first bad commit" my_bisect_log.txt &&
|
||||||
|
git bisect reset &&
|
||||||
|
rev_hash6=$(git rev-parse --verify bisect) &&
|
||||||
|
test "$rev_hash6" = "$HASH6" &&
|
||||||
|
git branch -D bisect
|
||||||
|
'
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
test_done
|
test_done
|
||||||
|
|
Loading…
Reference in New Issue