diff options
Diffstat (limited to 'git-bisect.sh')
| -rwxr-xr-x | git-bisect.sh | 133 | 
1 files changed, 75 insertions, 58 deletions
| diff --git a/git-bisect.sh b/git-bisect.sh index b1800edaf7..991b2ef37e 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -1,7 +1,9 @@  #!/bin/sh -USAGE='[start|bad|good|skip|next|reset|visualize|replay|log|run]' -LONG_USAGE='git bisect start [<bad> [<good>...]] [--] [<pathspec>...] +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>...]          reset bisect state and start bisection.  git bisect bad [<rev>]          mark <rev> a known-bad revision. @@ -20,7 +22,9 @@ git bisect replay <logfile>  git bisect log          show bisect log.  git bisect run <cmd>... -        use <cmd>... to automatically bisect.' +        use <cmd>... to automatically bisect. + +Please use "git help bisect" to get the full man page.'  OPTIONS_SPEC=  . git-sh-setup @@ -40,7 +44,7 @@ sq() {  }  bisect_autostart() { -	test -f "$GIT_DIR/BISECT_NAMES" || { +	test -s "$GIT_DIR/BISECT_START" || {  		echo >&2 'You need to start by "git bisect start"'  		if test -t 0  		then @@ -59,42 +63,42 @@ bisect_autostart() {  bisect_start() {  	# -	# Verify HEAD. If we were bisecting before this, reset to the -	# top-of-line master first! +	# Verify HEAD.  	#  	head=$(GIT_DIR="$GIT_DIR" git symbolic-ref -q HEAD) ||  	head=$(GIT_DIR="$GIT_DIR" git rev-parse --verify HEAD) ||  	die "Bad HEAD - I need a HEAD" +  	# -	# Check that we either already have BISECT_START, or that the -	# branches bisect, new-bisect don't exist, to not override them. +	# Check if we are bisecting.  	# -	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='' -	case "$head" in -	refs/heads/bisect) -		branch=`cat "$GIT_DIR/BISECT_START"` -		git checkout $branch || exit -		;; -	refs/heads/*|$_x40) -		# This error message should only be triggered by cogito usage, -		# and cogito users should understand it relates to cg-seek. -		[ -s "$GIT_DIR/head-name" ] && die "won't bisect on seeked tree" -		start_head="${head#refs/heads/}" -		;; -	*) -		die "Bad HEAD - strange symbolic ref" -		;; -	esac +	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 +		refs/heads/*|$_x40) +			# This error message should only be triggered by +			# cogito usage, and cogito users should understand +			# it relates to cg-seek. +			[ -s "$GIT_DIR/head-name" ] && +				die "won't bisect on seeked tree" +			start_head="${head#refs/heads/}" +			;; +		*) +			die "Bad HEAD - strange symbolic ref" +			;; +		esac +	fi  	# -	# Get rid of any old bisect state +	# Get rid of any old bisect state.  	# -	bisect_clean_state +	bisect_clean_state || exit  	#  	# Check for one bad and then some good revisions. @@ -114,7 +118,7 @@ bisect_start() {  		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 &&  		        die "'$arg' does not appear to be a valid revision"  		    break @@ -129,11 +133,29 @@ bisect_start() {  	    esac  	done -	sq "$@" >"$GIT_DIR/BISECT_NAMES" -	test -n "$start_head" && echo "$start_head" >"$GIT_DIR/BISECT_START" -	eval "$eval" -	echo "git-bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" +	# +	# Change state. +	# In case of mistaken revs or checkout error, or signals received, +	# "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. +	# +	echo "$start_head" >"$GIT_DIR/BISECT_START" && +	sq "$@" >"$GIT_DIR/BISECT_NAMES" && +	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 + +	trap '-' 0  }  bisect_write() { @@ -145,9 +167,9 @@ bisect_write() {  		good|skip)	tag="$state"-"$rev" ;;  		*)		die "Bad bisect_write argument: $state" ;;  	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" -	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() { @@ -204,7 +226,7 @@ bisect_next_check() {  		;;  	*)  		THEN='' -		test -f "$GIT_DIR/BISECT_NAMES" || { +		test -s "$GIT_DIR/BISECT_START" || {  			echo >&2 'You need to start by "git bisect start".'  			THEN='then '  		} @@ -344,9 +366,7 @@ bisect_next() {  	exit_if_skipped_commits "$bisect_rev"  	echo "Bisecting: $bisect_nr revisions left to test after this" -	git branch -D new-bisect 2> /dev/null -	git checkout -q -b new-bisect "$bisect_rev" || exit -	git branch -M new-bisect bisect +	git checkout -q "$bisect_rev" || exit  	git show-branch "$bisect_rev"  } @@ -372,40 +392,35 @@ bisect_visualize() {  }  bisect_reset() { -	test -f "$GIT_DIR/BISECT_NAMES" || { +	test -s "$GIT_DIR/BISECT_START" || {  		echo "We are not bisecting."  		return  	}  	case "$#" in -	0) if [ -s "$GIT_DIR/BISECT_START" ]; then -	       branch=`cat "$GIT_DIR/BISECT_START"` -	   else -	       branch=master -	   fi ;; +	0) branch=$(cat "$GIT_DIR/BISECT_START") ;;  	1) git show-ref --verify --quiet -- "refs/heads/$1" ||  	       die "$1 does not seem to be a valid branch"  	   branch="$1" ;;  	*)  	    usage ;;  	esac -	if git checkout "$branch"; then -		# 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 +	git checkout "$branch" && bisect_clean_state  }  bisect_clean_state() {  	# 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  	do -		git update-ref -d $ref $hash +		git update-ref -d $ref $hash || exit  	done -	rm -f "$GIT_DIR/BISECT_LOG" -	rm -f "$GIT_DIR/BISECT_NAMES" -	rm -f "$GIT_DIR/BISECT_RUN" +	rm -f "$GIT_DIR/BISECT_LOG" && +	rm -f "$GIT_DIR/BISECT_NAMES" && +	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" && + +	rm -f "$GIT_DIR/BISECT_START"  }  bisect_replay () { @@ -487,6 +502,8 @@ case "$#" in      cmd="$1"      shift      case "$cmd" in +    help) +        git bisect -h ;;      start)          bisect_start "$@" ;;      bad|good|skip) | 
