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() {
|
bisect_start() {
|
||||||
case "$#" in 0) ;; *) usage ;; esac
|
|
||||||
#
|
#
|
||||||
# Verify HEAD. If we were bisecting before this, reset to the
|
# Verify HEAD. If we were bisecting before this, reset to the
|
||||||
# top-of-line master first!
|
# top-of-line master first!
|
||||||
@ -57,7 +56,8 @@ bisect_start() {
|
|||||||
rm -f "$GIT_DIR/refs/heads/bisect"
|
rm -f "$GIT_DIR/refs/heads/bisect"
|
||||||
rm -rf "$GIT_DIR/refs/bisect/"
|
rm -rf "$GIT_DIR/refs/bisect/"
|
||||||
mkdir "$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() {
|
bisect_bad() {
|
||||||
@ -121,7 +121,7 @@ bisect_next() {
|
|||||||
bad=$(git-rev-parse --verify refs/bisect/bad) &&
|
bad=$(git-rev-parse --verify refs/bisect/bad) &&
|
||||||
good=$(git-rev-parse --sq --revs-only --not \
|
good=$(git-rev-parse --sq --revs-only --not \
|
||||||
$(cd "$GIT_DIR" && ls refs/bisect/good-*)) &&
|
$(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
|
if [ -z "$rev" ]; then
|
||||||
echo "$bad was both good and bad"
|
echo "$bad was both good and bad"
|
||||||
exit 1
|
exit 1
|
||||||
@ -131,7 +131,7 @@ bisect_next() {
|
|||||||
git-diff-tree --pretty $rev
|
git-diff-tree --pretty $rev
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
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 "Bisecting: $nr revisions left to test after this"
|
||||||
echo "$rev" > "$GIT_DIR/refs/heads/new-bisect"
|
echo "$rev" > "$GIT_DIR/refs/heads/new-bisect"
|
||||||
git checkout new-bisect || exit
|
git checkout new-bisect || exit
|
||||||
@ -142,7 +142,7 @@ bisect_next() {
|
|||||||
|
|
||||||
bisect_visualize() {
|
bisect_visualize() {
|
||||||
bisect_next_check fail
|
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() {
|
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))
|
if (commit->object.flags & (UNINTERESTING | COUNTED))
|
||||||
break;
|
break;
|
||||||
nr++;
|
if (!paths || (commit->object.flags & TREECHANGE))
|
||||||
|
nr++;
|
||||||
commit->object.flags |= COUNTED;
|
commit->object.flags |= COUNTED;
|
||||||
p = commit->parents;
|
p = commit->parents;
|
||||||
entry = p;
|
entry = p;
|
||||||
@ -362,6 +363,7 @@ static int count_distance(struct commit_list *entry)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nr;
|
return nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,15 +384,20 @@ static struct commit_list *find_bisection(struct commit_list *list)
|
|||||||
nr = 0;
|
nr = 0;
|
||||||
p = list;
|
p = list;
|
||||||
while (p) {
|
while (p) {
|
||||||
nr++;
|
if (!paths || (p->item->object.flags & TREECHANGE))
|
||||||
|
nr++;
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
closest = 0;
|
closest = 0;
|
||||||
best = list;
|
best = list;
|
||||||
|
|
||||||
p = list;
|
for (p = list; p; p = p->next) {
|
||||||
while (p) {
|
int distance;
|
||||||
int distance = count_distance(p);
|
|
||||||
|
if (paths && !(p->item->object.flags & TREECHANGE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
distance = count_distance(p);
|
||||||
clear_distance(list);
|
clear_distance(list);
|
||||||
if (nr - distance < distance)
|
if (nr - distance < distance)
|
||||||
distance = nr - distance;
|
distance = nr - distance;
|
||||||
@ -398,7 +405,6 @@ static struct commit_list *find_bisection(struct commit_list *list)
|
|||||||
best = p;
|
best = p;
|
||||||
closest = distance;
|
closest = distance;
|
||||||
}
|
}
|
||||||
p = p->next;
|
|
||||||
}
|
}
|
||||||
if (best)
|
if (best)
|
||||||
best->next = NULL;
|
best->next = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user