mirror of
https://github.com/git/git.git
synced 2024-11-27 20:14:30 +08:00
bisect: limit the searchspace by pathspecs
It was surprisingly easy to do. git bisect start <pathspec> followed by all the normal "git bisect good/bad" stuff. Almost totally untested, and I guarantee that if your pathnames have spaces in them (or your GIT_DIR has spaces in it) this won't work. I don't know how to fix that, my shell programming isn't good enough. This involves small changes to make "git-rev-list --bisect" work in the presense of a pathspec limiter, and then truly trivial (and that's the broken part) changes to make "git bisect" save away and use the pathspec. I tried one bisection, and a "git bisect visualize", and it all looked correct. But hey, don't be surprised if it has problems. Linus Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
9ef2b3cbf6
commit
b3cfd939c3
@ -33,7 +33,6 @@ bisect_autostart() {
|
||||
}
|
||||
|
||||
bisect_start() {
|
||||
case "$#" in 0) ;; *) usage ;; esac
|
||||
#
|
||||
# Verify HEAD. If we were bisecting before this, reset to the
|
||||
# top-of-line master first!
|
||||
@ -57,7 +56,8 @@ bisect_start() {
|
||||
rm -f "$GIT_DIR/refs/heads/bisect"
|
||||
rm -rf "$GIT_DIR/refs/bisect/"
|
||||
mkdir "$GIT_DIR/refs/bisect"
|
||||
echo "git-bisect start" >"$GIT_DIR/BISECT_LOG"
|
||||
echo "git-bisect start $@" >"$GIT_DIR/BISECT_LOG"
|
||||
echo "$@" > "$GIT_DIR/BISECT_NAMES"
|
||||
}
|
||||
|
||||
bisect_bad() {
|
||||
@ -121,7 +121,7 @@ bisect_next() {
|
||||
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
|
||||
rev=$(eval "git-rev-list --bisect $good $bad -- $(cat $GIT_DIR/BISECT_NAMES)") || exit
|
||||
if [ -z "$rev" ]; then
|
||||
echo "$bad was both good and bad"
|
||||
exit 1
|
||||
@ -131,7 +131,7 @@ bisect_next() {
|
||||
git-diff-tree --pretty $rev
|
||||
exit 0
|
||||
fi
|
||||
nr=$(eval "git-rev-list $rev $good" | wc -l) || exit
|
||||
nr=$(eval "git-rev-list $rev $good -- $(cat $GIT_DIR/BISECT_NAMES)" | 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
|
||||
@ -142,7 +142,7 @@ bisect_next() {
|
||||
|
||||
bisect_visualize() {
|
||||
bisect_next_check fail
|
||||
gitk bisect/bad --not `cd "$GIT_DIR/refs" && echo bisect/good-*`
|
||||
gitk bisect/bad --not `cd "$GIT_DIR/refs" && echo bisect/good-*` -- $(cat $GIT_DIR/BISECT_NAMES)
|
||||
}
|
||||
|
||||
bisect_reset() {
|
||||
|
18
rev-list.c
18
rev-list.c
@ -350,7 +350,8 @@ static int count_distance(struct commit_list *entry)
|
||||
|
||||
if (commit->object.flags & (UNINTERESTING | COUNTED))
|
||||
break;
|
||||
nr++;
|
||||
if (!paths || (commit->object.flags & TREECHANGE))
|
||||
nr++;
|
||||
commit->object.flags |= COUNTED;
|
||||
p = commit->parents;
|
||||
entry = p;
|
||||
@ -362,6 +363,7 @@ static int count_distance(struct commit_list *entry)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nr;
|
||||
}
|
||||
|
||||
@ -382,15 +384,20 @@ static struct commit_list *find_bisection(struct commit_list *list)
|
||||
nr = 0;
|
||||
p = list;
|
||||
while (p) {
|
||||
nr++;
|
||||
if (!paths || (p->item->object.flags & TREECHANGE))
|
||||
nr++;
|
||||
p = p->next;
|
||||
}
|
||||
closest = 0;
|
||||
best = list;
|
||||
|
||||
p = list;
|
||||
while (p) {
|
||||
int distance = count_distance(p);
|
||||
for (p = list; p; p = p->next) {
|
||||
int distance;
|
||||
|
||||
if (paths && !(p->item->object.flags & TREECHANGE))
|
||||
continue;
|
||||
|
||||
distance = count_distance(p);
|
||||
clear_distance(list);
|
||||
if (nr - distance < distance)
|
||||
distance = nr - distance;
|
||||
@ -398,7 +405,6 @@ static struct commit_list *find_bisection(struct commit_list *list)
|
||||
best = p;
|
||||
closest = distance;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
if (best)
|
||||
best->next = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user