aboutsummaryrefslogtreecommitdiff
path: root/git-bisect.sh
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2005-09-07 17:26:23 -0700
committerJunio C Hamano <junkio@cox.net>2005-09-07 17:45:20 -0700
commit215a7ad1ef790467a4cd3f0dcffbd6e5f04c38f7 (patch)
tree6bc7aa4f652d0ef49108d9e30a7ea7fbf8e44639 /git-bisect.sh
parent99977bd5fdeabbd0608a70e9411c243007ec4ea2 (diff)
downloadgit-215a7ad1ef790467a4cd3f0dcffbd6e5f04c38f7.tar.gz
git-215a7ad1ef790467a4cd3f0dcffbd6e5f04c38f7.tar.xz
Big tool rename.
As promised, this is the "big tool rename" patch. The primary differences since 0.99.6 are: (1) git-*-script are no more. The commands installed do not have any such suffix so users do not have to remember if something is implemented as a shell script or not. (2) Many command names with 'cache' in them are renamed with 'index' if that is what they mean. There are backward compatibility symblic links so that you and Porcelains can keep using the old names, but the backward compatibility support is expected to be removed in the near future. Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'git-bisect.sh')
-rwxr-xr-xgit-bisect.sh178
1 files changed, 178 insertions, 0 deletions
diff --git a/git-bisect.sh b/git-bisect.sh
new file mode 100755
index 000000000..605d58a2b
--- /dev/null
+++ b/git-bisect.sh
@@ -0,0 +1,178 @@
+#!/bin/sh
+. git-sh-setup || dir "Not a git archive"
+
+usage() {
+ echo >&2 'usage: git bisect [start|bad|good|next|reset|visualize]
+git bisect start reset bisect state and start bisection.
+git bisect bad [<rev>] mark <rev> a known-bad revision.
+git bisect good [<rev>...] mark <rev>... known-good revisions.
+git bisect next find next bisection to test and check it out.
+git bisect reset [<branch>] finish bisection search and go back to branch.
+git bisect visualize show bisect status in gitk.'
+ exit 1
+}
+
+bisect_autostart() {
+ test -d "$GIT_DIR/refs/bisect" || {
+ echo >&2 'You need to start by "git bisect start"'
+ if test -t 0
+ then
+ echo >&2 -n 'Do you want me to do it for you [Y/n]? '
+ read yesno
+ case "$yesno" in
+ [Nn]*)
+ exit ;;
+ esac
+ bisect_start
+ else
+ exit 1
+ fi
+ }
+}
+
+bisect_start() {
+ case "$#" in 0) ;; *) usage ;; esac
+ #
+ # Verify HEAD. If we were bisecting before this, reset to the
+ # top-of-line master first!
+ #
+ head=$(readlink $GIT_DIR/HEAD) || die "Bad HEAD - I need a symlink"
+ case "$head" in
+ refs/heads/bisect*)
+ git checkout master || exit
+ ;;
+ refs/heads/*)
+ ;;
+ *)
+ die "Bad HEAD - strange symlink"
+ ;;
+ esac
+
+ #
+ # Get rid of any old bisect state
+ #
+ rm -f "$GIT_DIR/refs/heads/bisect"
+ rm -rf "$GIT_DIR/refs/bisect/"
+ mkdir "$GIT_DIR/refs/bisect"
+}
+
+bisect_bad() {
+ bisect_autostart
+ case "$#" in
+ 0)
+ rev=$(git-rev-parse --verify HEAD) ;;
+ 1)
+ rev=$(git-rev-parse --verify "$1") ;;
+ *)
+ usage ;;
+ esac || exit
+ echo "$rev" > "$GIT_DIR/refs/bisect/bad"
+ bisect_auto_next
+}
+
+bisect_good() {
+ bisect_autostart
+ case "$#" in
+ 0) revs=$(git-rev-parse --verify HEAD) || exit ;;
+ *) revs=$(git-rev-parse --revs-only --no-flags "$@") &&
+ test '' != "$revs" || die "Bad rev input: $@" ;;
+ esac
+ for rev in $revs
+ do
+ rev=$(git-rev-parse --verify "$rev") || exit
+ echo "$rev" >"$GIT_DIR/refs/bisect/good-$rev"
+ done
+ bisect_auto_next
+}
+
+bisect_next_check() {
+ next_ok=no
+ test -f "$GIT_DIR/refs/bisect/bad" &&
+ case "$(cd "$GIT_DIR" && echo refs/bisect/good-*)" in
+ refs/bisect/good-\*) ;;
+ *) next_ok=yes ;;
+ esac
+ case "$next_ok,$1" in
+ no,) false ;;
+ no,fail)
+ echo >&2 'You need to give me at least one good and one bad revisions.'
+ exit 1 ;;
+ *)
+ true ;;
+ esac
+}
+
+bisect_auto_next() {
+ bisect_next_check && bisect_next
+}
+
+bisect_next() {
+ case "$#" in 0) ;; *) usage ;; esac
+ bisect_autostart
+ bisect_next_check fail
+ bad=$(git-rev-parse --verify refs/bisect/bad) &&
+ good=$(git-rev-parse --sq --revs-only --not \
+ $(cd "$GIT_DIR" && ls refs/bisect/good-*)) &&
+ rev=$(eval "git-rev-list --bisect $good $bad") || exit
+ if [ -z "$rev" ]; then
+ echo "$bad was both good and bad"
+ exit 1
+ fi
+ if [ "$rev" = "$bad" ]; then
+ echo "$rev is first bad commit"
+ git-diff-tree --pretty $rev
+ exit 0
+ fi
+ nr=$(eval "git-rev-list $rev $good" | wc -l) || exit
+ echo "Bisecting: $nr revisions left to test after this"
+ echo "$rev" > "$GIT_DIR/refs/heads/new-bisect"
+ git checkout new-bisect || exit
+ mv "$GIT_DIR/refs/heads/new-bisect" "$GIT_DIR/refs/heads/bisect" &&
+ ln -sf refs/heads/bisect "$GIT_DIR/HEAD"
+}
+
+bisect_visualize() {
+ bisect_next_check fail
+ gitk bisect/bad --not `cd "$GIT_DIR/refs" && echo bisect/good-*`
+}
+
+bisect_reset() {
+ case "$#" in
+ 0) branch=master ;;
+ 1) test -f "$GIT_DIR/refs/heads/$1" || {
+ echo >&2 "$1 does not seem to be a valid branch"
+ exit 1
+ }
+ branch="$1" ;;
+ *)
+ usage ;;
+ esac
+ git checkout "$branch" &&
+ rm -fr "$GIT_DIR/refs/bisect"
+ rm -f "$GIT_DIR/refs/reads/bisect"
+}
+
+case "$#" in
+0)
+ usage ;;
+*)
+ cmd="$1"
+ shift
+ case "$cmd" in
+ start)
+ bisect_start "$@" ;;
+ bad)
+ bisect_bad "$@" ;;
+ good)
+ bisect_good "$@" ;;
+ next)
+ # Not sure we want "next" at the UI level anymore.
+ bisect_next "$@" ;;
+ visualize)
+ bisect_visualize "$@" ;;
+ reset)
+ bisect_reset "$@" ;;
+ *)
+ usage ;;
+ esac
+esac