Skip to content

Commit 457f08a

Browse files
author
Junio C Hamano
committed
git-rev-list: add --bisect-vars option.
This adds --bisect-vars option to rev-list. The output is suitable for `eval` in shell and defines five variables: - bisect_rev is the next revision to test. - bisect_nr is the expected number of commits to test after bisect_rev is tested. - bisect_good is the expected number of commits to test if bisect_rev turns out to be good. - bisect_bad is the expected number of commits to test if bisect_rev turns out to be bad. - bisect_all is the number of commits we are bisecting right now. The documentation text was partly stolen from Johannes Schindelin's patch. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7054b60 commit 457f08a

File tree

2 files changed

+61
-6
lines changed

2 files changed

+61
-6
lines changed

Documentation/git-rev-list.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ SYNOPSIS
2626
[ [\--objects | \--objects-edge] [ \--unpacked ] ]
2727
[ \--pretty | \--header ]
2828
[ \--bisect ]
29+
[ \--bisect-vars ]
2930
[ \--merge ]
3031
[ \--reverse ]
3132
[ \--walk-reflogs ]
@@ -249,6 +250,18 @@ introduces a regression is thus reduced to a binary search: repeatedly
249250
generate and test new 'midpoint's until the commit chain is of length
250251
one.
251252

253+
--bisect-vars::
254+
255+
This calculates the same as `--bisect`, but outputs text ready
256+
to be eval'ed by the shell. These lines will assign the name of
257+
the midpoint revision to the variable `bisect_rev`, and the
258+
expected number of commits to be tested after `bisect_rev` is
259+
tested to `bisect_nr`, the expected number of commits to be
260+
tested if `bisect_rev` turns out to be good to `bisect_good`,
261+
the expected number of commits to be tested if `bisect_rev`
262+
turns out to be bad to `bisect_bad`, and the number of commits
263+
we are bisecting right now to `bisect_all`.
264+
252265
--
253266

254267
Commit Ordering

builtin-rev-list.c

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ static const char rev_list_usage[] =
3636
" --abbrev=nr | --no-abbrev\n"
3737
" --abbrev-commit\n"
3838
" special purpose:\n"
39-
" --bisect"
39+
" --bisect\n"
40+
" --bisect-vars"
4041
;
4142

4243
static struct rev_info revs;
@@ -168,7 +169,8 @@ static void clear_distance(struct commit_list *list)
168169
}
169170
}
170171

171-
static struct commit_list *find_bisection(struct commit_list *list)
172+
static struct commit_list *find_bisection(struct commit_list *list,
173+
int *reaches, int *all)
172174
{
173175
int nr, closest;
174176
struct commit_list *p, *best;
@@ -180,21 +182,23 @@ static struct commit_list *find_bisection(struct commit_list *list)
180182
nr++;
181183
p = p->next;
182184
}
185+
*all = nr;
183186
closest = 0;
184187
best = list;
185188

186189
for (p = list; p; p = p->next) {
187-
int distance;
190+
int distance, reach;
188191

189192
if (revs.prune_fn && !(p->item->object.flags & TREECHANGE))
190193
continue;
191194

192-
distance = count_distance(p);
195+
distance = reach = count_distance(p);
193196
clear_distance(list);
194197
if (nr - distance < distance)
195198
distance = nr - distance;
196199
if (distance > closest) {
197200
best = p;
201+
*reaches = reach;
198202
closest = distance;
199203
}
200204
}
@@ -225,6 +229,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
225229
struct commit_list *list;
226230
int i;
227231
int read_from_stdin = 0;
232+
int bisect_show_vars = 0;
228233

229234
git_config(git_default_config);
230235
init_revisions(&revs, prefix);
@@ -247,6 +252,11 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
247252
bisect_list = 1;
248253
continue;
249254
}
255+
if (!strcmp(arg, "--bisect-vars")) {
256+
bisect_list = 1;
257+
bisect_show_vars = 1;
258+
continue;
259+
}
250260
if (!strcmp(arg, "--stdin")) {
251261
if (read_from_stdin++)
252262
die("--stdin given twice?");
@@ -285,8 +295,40 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
285295
if (revs.tree_objects)
286296
mark_edges_uninteresting(revs.commits, &revs, show_edge);
287297

288-
if (bisect_list)
289-
revs.commits = find_bisection(revs.commits);
298+
if (bisect_list) {
299+
int reaches = reaches, all = all;
300+
301+
revs.commits = find_bisection(revs.commits,
302+
&reaches, &all);
303+
if (bisect_show_vars) {
304+
int cnt;
305+
if (!revs.commits)
306+
return 1;
307+
/*
308+
* revs.commits can reach "reaches" commits among
309+
* "all" commits. If it is good, then there are
310+
* (all-reaches) commits left to be bisected.
311+
* On the other hand, if it is bad, then the set
312+
* to bisect is "reaches".
313+
* A bisect set of size N has (N-1) commits further
314+
* to test, as we already know one bad one.
315+
*/
316+
cnt = all-reaches;
317+
if (cnt < reaches)
318+
cnt = reaches;
319+
printf("bisect_rev=%s\n"
320+
"bisect_nr=%d\n"
321+
"bisect_good=%d\n"
322+
"bisect_bad=%d\n"
323+
"bisect_all=%d\n",
324+
sha1_to_hex(revs.commits->item->object.sha1),
325+
cnt - 1,
326+
all - reaches - 1,
327+
reaches - 1,
328+
all);
329+
return 0;
330+
}
331+
}
290332

291333
traverse_commit_list(&revs, show_commit, show_object);
292334

0 commit comments

Comments
 (0)