rev-list: move bisect related code into its own file
This patch creates new "bisect.c" and "bisect.h" files and move bisect related code into these files. While at it, we also remove some include directives that are not needed any more from the beginning of "builtin-rev-list.c". Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Christian Couder committed
Mar 26, 2009 at 05:55 UTC
a2ad79ced25e1b76fabec079549f521e8071ddd1
4 files changed
+398
-387
Makefile
+1
@@ -420,6 +420,7 @@ LIB_OBJS += archive-tar.o
420
LIB_OBJS += archive-zip.o
421
LIB_OBJS += attr.o
422
LIB_OBJS += base85.o
423
+LIB_OBJS += bisect.o
424
LIB_OBJS += blob.o
425
LIB_OBJS += branch.o
426
LIB_OBJS += bundle.o
bisect.c
new
+388
@@ -0,0 +1,388 @@
1
+#include "cache.h"
2
+#include "commit.h"
3
+#include "diff.h"
4
+#include "revision.h"
5
+#include "bisect.h"
6
+
7
+/* bits #0-15 in revision.h */
8
+
9
+#define COUNTED (1u<<16)
10
+
11
+/*
12
+ * This is a truly stupid algorithm, but it's only
13
+ * used for bisection, and we just don't care enough.
14
+ *
15
+ * We care just barely enough to avoid recursing for
16
+ * non-merge entries.
17
+ */
18
+static int count_distance(struct commit_list *entry)
19
+{
20
+ int nr = 0;
21
+
22
+ while (entry) {
23
+ struct commit *commit = entry->item;
24
+ struct commit_list *p;
25
+
26
+ if (commit->object.flags & (UNINTERESTING | COUNTED))
27
+ break;
28
+ if (!(commit->object.flags & TREESAME))
29
+ nr++;
30
+ commit->object.flags |= COUNTED;
31
+ p = commit->parents;
32
+ entry = p;
33
+ if (p) {
34
+ p = p->next;
35
+ while (p) {
36
+ nr += count_distance(p);
37
+ p = p->next;
38
+ }
39
+ }
40
+ }
41
+
42
+ return nr;
43
+}
44
+
45
+static void clear_distance(struct commit_list *list)
46
+{
47
+ while (list) {
48
+ struct commit *commit = list->item;
49
+ commit->object.flags &= ~COUNTED;
50
+ list = list->next;
51
+ }
52
+}
53
+
54
+#define DEBUG_BISECT 0
55
+
56
+static inline int weight(struct commit_list *elem)
57
+{
58
+ return *((int*)(elem->item->util));
59
+}
60
+
61
+static inline void weight_set(struct commit_list *elem, int weight)
62
+{
63
+ *((int*)(elem->item->util)) = weight;
64
+}
65
+
66
+static int count_interesting_parents(struct commit *commit)
67
+{
68
+ struct commit_list *p;
69
+ int count;
70
+
71
+ for (count = 0, p = commit->parents; p; p = p->next) {
72
+ if (p->item->object.flags & UNINTERESTING)
73
+ continue;
74
+ count++;
75
+ }
76
+ return count;
77
+}
78
+
79
+static inline int halfway(struct commit_list *p, int nr)
80
+{
81
+ /*
82
+ * Don't short-cut something we are not going to return!
83
+ */
84
+ if (p->item->object.flags & TREESAME)
85
+ return 0;
86
+ if (DEBUG_BISECT)
87
+ return 0;
88
+ /*
89
+ * 2 and 3 are halfway of 5.
90
+ * 3 is halfway of 6 but 2 and 4 are not.
91
+ */
92
+ switch (2 * weight(p) - nr) {
93
+ case -1: case 0: case 1:
94
+ return 1;
95
+ default:
96
+ return 0;
97
+ }
98
+}
99
+
100
+#if !DEBUG_BISECT
101
+#define show_list(a,b,c,d) do { ; } while (0)
102
+#else
103
+static void show_list(const char *debug, int counted, int nr,
104
+ struct commit_list *list)
105
+{
106
+ struct commit_list *p;
107
+
108
+ fprintf(stderr, "%s (%d/%d)\n", debug, counted, nr);
109
+
110
+ for (p = list; p; p = p->next) {
111
+ struct commit_list *pp;
112
+ struct commit *commit = p->item;
113
+ unsigned flags = commit->object.flags;
114
+ enum object_type type;
115
+ unsigned long size;
116
+ char *buf = read_sha1_file(commit->object.sha1, &type, &size);
117
+ char *ep, *sp;
118
+
119
+ fprintf(stderr, "%c%c%c ",
120
+ (flags & TREESAME) ? ' ' : 'T',
121
+ (flags & UNINTERESTING) ? 'U' : ' ',
122
+ (flags & COUNTED) ? 'C' : ' ');
123
+ if (commit->util)
124
+ fprintf(stderr, "%3d", weight(p));
125
+ else
126
+ fprintf(stderr, "---");
127
+ fprintf(stderr, " %.*s", 8, sha1_to_hex(commit->object.sha1));
128
+ for (pp = commit->parents; pp; pp = pp->next)
129
+ fprintf(stderr, " %.*s", 8,
130
+ sha1_to_hex(pp->item->object.sha1));
131
+
132
+ sp = strstr(buf, "\n\n");
133
+ if (sp) {
134
+ sp += 2;
135
+ for (ep = sp; *ep && *ep != '\n'; ep++)
136
+ ;
137
+ fprintf(stderr, " %.*s", (int)(ep - sp), sp);
138
+ }
139
+ fprintf(stderr, "\n");
140
+ }
141
+}
142
+#endif /* DEBUG_BISECT */
143
+
144
+static struct commit_list *best_bisection(struct commit_list *list, int nr)
145
+{
146
+ struct commit_list *p, *best;
147
+ int best_distance = -1;
148
+
149
+ best = list;
150
+ for (p = list; p; p = p->next) {
151
+ int distance;
152
+ unsigned flags = p->item->object.flags;
153
+
154
+ if (flags & TREESAME)
155
+ continue;
156
+ distance = weight(p);
157
+ if (nr - distance < distance)
158
+ distance = nr - distance;
159
+ if (distance > best_distance) {
160
+ best = p;
161
+ best_distance = distance;
162
+ }
163
+ }
164
+
165
+ return best;
166
+}
167
+
168
+struct commit_dist {
169
+ struct commit *commit;
170
+ int distance;
171
+};
172
+
173
+static int compare_commit_dist(const void *a_, const void *b_)
174
+{
175
+ struct commit_dist *a, *b;
176
+
177
+ a = (struct commit_dist *)a_;
178
+ b = (struct commit_dist *)b_;
179
+ if (a->distance != b->distance)
180
+ return b->distance - a->distance; /* desc sort */
181
+ return hashcmp(a->commit->object.sha1, b->commit->object.sha1);
182
+}
183
+
184
+static struct commit_list *best_bisection_sorted(struct commit_list *list, int nr)
185
+{
186
+ struct commit_list *p;
187
+ struct commit_dist *array = xcalloc(nr, sizeof(*array));
188
+ int cnt, i;
189
+
190
+ for (p = list, cnt = 0; p; p = p->next) {
191
+ int distance;
192
+ unsigned flags = p->item->object.flags;
193
+
194
+ if (flags & TREESAME)
195
+ continue;
196
+ distance = weight(p);
197
+ if (nr - distance < distance)
198
+ distance = nr - distance;
199
+ array[cnt].commit = p->item;
200
+ array[cnt].distance = distance;
201
+ cnt++;
202
+ }
203
+ qsort(array, cnt, sizeof(*array), compare_commit_dist);
204
+ for (p = list, i = 0; i < cnt; i++) {
205
+ struct name_decoration *r = xmalloc(sizeof(*r) + 100);
206
+ struct object *obj = &(array[i].commit->object);
207
+
208
+ sprintf(r->name, "dist=%d", array[i].distance);
209
+ r->next = add_decoration(&name_decoration, obj, r);
210
+ p->item = array[i].commit;
211
+ p = p->next;
212
+ }
213
+ if (p)
214
+ p->next = NULL;
215
+ free(array);
216
+ return list;
217
+}
218
+
219
+/*
220
+ * zero or positive weight is the number of interesting commits it can
221
+ * reach, including itself. Especially, weight = 0 means it does not
222
+ * reach any tree-changing commits (e.g. just above uninteresting one
223
+ * but traversal is with pathspec).
224
+ *
225
+ * weight = -1 means it has one parent and its distance is yet to
226
+ * be computed.
227
+ *
228
+ * weight = -2 means it has more than one parent and its distance is
229
+ * unknown. After running count_distance() first, they will get zero
230
+ * or positive distance.
231
+ */
232
+static struct commit_list *do_find_bisection(struct commit_list *list,
233
+ int nr, int *weights,
234
+ int find_all)
235
+{
236
+ int n, counted;
237
+ struct commit_list *p;
238
+
239
+ counted = 0;
240
+
241
+ for (n = 0, p = list; p; p = p->next) {
242
+ struct commit *commit = p->item;
243
+ unsigned flags = commit->object.flags;
244
+
245
+ p->item->util = &weights[n++];
246
+ switch (count_interesting_parents(commit)) {
247
+ case 0:
248
+ if (!(flags & TREESAME)) {
249
+ weight_set(p, 1);
250
+ counted++;
251
+ show_list("bisection 2 count one",
252
+ counted, nr, list);
253
+ }
254
+ /*
255
+ * otherwise, it is known not to reach any
256
+ * tree-changing commit and gets weight 0.
257
+ */
258
+ break;
259
+ case 1:
260
+ weight_set(p, -1);
261
+ break;
262
+ default:
263
+ weight_set(p, -2);
264
+ break;
265
+ }
266
+ }
267
+
268
+ show_list("bisection 2 initialize", counted, nr, list);
269
+
270
+ /*
271
+ * If you have only one parent in the resulting set
272
+ * then you can reach one commit more than that parent
273
+ * can reach. So we do not have to run the expensive
274
+ * count_distance() for single strand of pearls.
275
+ *
276
+ * However, if you have more than one parents, you cannot
277
+ * just add their distance and one for yourself, since
278
+ * they usually reach the same ancestor and you would
279
+ * end up counting them twice that way.
280
+ *
281
+ * So we will first count distance of merges the usual
282
+ * way, and then fill the blanks using cheaper algorithm.
283
+ */
284
+ for (p = list; p; p = p->next) {
285
+ if (p->item->object.flags & UNINTERESTING)
286
+ continue;
287
+ if (weight(p) != -2)
288
+ continue;
289
+ weight_set(p, count_distance(p));
290
+ clear_distance(list);
291
+
292
+ /* Does it happen to be at exactly half-way? */
293
+ if (!find_all && halfway(p, nr))
294
+ return p;
295
+ counted++;
296
+ }
297
+
298
+ show_list("bisection 2 count_distance", counted, nr, list);
299
+
300
+ while (counted < nr) {
301
+ for (p = list; p; p = p->next) {
302
+ struct commit_list *q;
303
+ unsigned flags = p->item->object.flags;
304
+
305
+ if (0 <= weight(p))
306
+ continue;
307
+ for (q = p->item->parents; q; q = q->next) {
308
+ if (q->item->object.flags & UNINTERESTING)
309
+ continue;
310
+ if (0 <= weight(q))
311
+ break;
312
+ }
313
+ if (!q)
314
+ continue;
315
+
316
+ /*
317
+ * weight for p is unknown but q is known.
318
+ * add one for p itself if p is to be counted,
319
+ * otherwise inherit it from q directly.
320
+ */
321
+ if (!(flags & TREESAME)) {
322
+ weight_set(p, weight(q)+1);
323
+ counted++;
324
+ show_list("bisection 2 count one",
325
+ counted, nr, list);
326
+ }
327
+ else
328
+ weight_set(p, weight(q));
329
+
330
+ /* Does it happen to be at exactly half-way? */
331
+ if (!find_all && halfway(p, nr))
332
+ return p;
333
+ }
334
+ }
335
+
336
+ show_list("bisection 2 counted all", counted, nr, list);
337
+
338
+ if (!find_all)
339
+ return best_bisection(list, nr);
340
+ else
341
+ return best_bisection_sorted(list, nr);
342
+}
343
+
344
+struct commit_list *find_bisection(struct commit_list *list,
345
+ int *reaches, int *all,
346
+ int find_all)
347
+{
348
+ int nr, on_list;
349
+ struct commit_list *p, *best, *next, *last;
350
+ int *weights;
351
+
352
+ show_list("bisection 2 entry", 0, 0, list);
353
+
354
+ /*
355
+ * Count the number of total and tree-changing items on the
356
+ * list, while reversing the list.
357
+ */
358
+ for (nr = on_list = 0, last = NULL, p = list;
359
+ p;
360
+ p = next) {
361
+ unsigned flags = p->item->object.flags;
362
+
363
+ next = p->next;
364
+ if (flags & UNINTERESTING)
365
+ continue;
366
+ p->next = last;
367
+ last = p;
368
+ if (!(flags & TREESAME))
369
+ nr++;
370
+ on_list++;
371
+ }
372
+ list = last;
373
+ show_list("bisection 2 sorted", 0, nr, list);
374
+
375
+ *all = nr;
376
+ weights = xcalloc(on_list, sizeof(*weights));
377
+
378
+ /* Do the real work of finding bisection commit. */
379
+ best = do_find_bisection(list, nr, weights, find_all);
380
+ if (best) {
381
+ if (!find_all)
382
+ best->next = NULL;
383
+ *reaches = weight(best);
384
+ }
385
+ free(weights);
386
+ return best;
387
+}
388
+
bisect.h
new
+8
@@ -0,0 +1,8 @@
1
+#ifndef BISECT_H
2
+#define BISECT_H
3
+
4
+extern struct commit_list *find_bisection(struct commit_list *list,
5
+ int *reaches, int *all,
6
+ int find_all);
7
+
8
+#endif
builtin-rev-list.c
+1
-387
@@ -1,20 +1,12 @@
1
#include "cache.h"
2
-#include "refs.h"
3
-#include "tag.h"
2
#include "commit.h"
5
-#include "tree.h"
6
-#include "blob.h"
7
-#include "tree-walk.h"
3
#include "diff.h"
4
#include "revision.h"
5
#include "list-objects.h"
6
#include "builtin.h"
7
#include "log-tree.h"
8
#include "graph.h"
14
-
15
-/* bits #0-15 in revision.h */
16
-
17
-#define COUNTED (1u<<16)
9
+#include "bisect.h"
10
11
static const char rev_list_usage[] =
12
"git rev-list [OPTION] <commit-id>... [ -- paths... ]\n"
@@ -195,384 +187,6 @@ static void show_edge(struct commit *commit)
187
printf("-%s\n", sha1_to_hex(commit->object.sha1));
188
}
189
198
-/*
199
- * This is a truly stupid algorithm, but it's only
200
- * used for bisection, and we just don't care enough.
201
- *
202
- * We care just barely enough to avoid recursing for
203
- * non-merge entries.
204
- */
205
-static int count_distance(struct commit_list *entry)
206
-{
207
- int nr = 0;
208
-
209
- while (entry) {
210
- struct commit *commit = entry->item;
211
- struct commit_list *p;
212
-
213
- if (commit->object.flags & (UNINTERESTING | COUNTED))
214
- break;
215
- if (!(commit->object.flags & TREESAME))
216
- nr++;
217
- commit->object.flags |= COUNTED;
218
- p = commit->parents;
219
- entry = p;
220
- if (p) {
221
- p = p->next;
222
- while (p) {
223
- nr += count_distance(p);
224
- p = p->next;
225
- }
226
- }
227
- }
228
-
229
- return nr;
230
-}
231
-
232
-static void clear_distance(struct commit_list *list)
233
-{
234
- while (list) {
235
- struct commit *commit = list->item;
236
- commit->object.flags &= ~COUNTED;
237
- list = list->next;
238
- }
239
-}
240
-
241
-#define DEBUG_BISECT 0
242
-
243
-static inline int weight(struct commit_list *elem)
244
-{
245
- return *((int*)(elem->item->util));
246
-}
247
-
248
-static inline void weight_set(struct commit_list *elem, int weight)
249
-{
250
- *((int*)(elem->item->util)) = weight;
251
-}
252
-
253
-static int count_interesting_parents(struct commit *commit)
254
-{
255
- struct commit_list *p;
256
- int count;
257
-
258
- for (count = 0, p = commit->parents; p; p = p->next) {
259
- if (p->item->object.flags & UNINTERESTING)
260
- continue;
261
- count++;
262
- }
263
- return count;
264
-}
265
-
266
-static inline int halfway(struct commit_list *p, int nr)
267
-{
268
- /*
269
- * Don't short-cut something we are not going to return!
270
- */
271
- if (p->item->object.flags & TREESAME)
272
- return 0;
273
- if (DEBUG_BISECT)
274
- return 0;
275
- /*
276
- * 2 and 3 are halfway of 5.
277
- * 3 is halfway of 6 but 2 and 4 are not.
278
- */
279
- switch (2 * weight(p) - nr) {
280
- case -1: case 0: case 1:
281
- return 1;
282
- default:
283
- return 0;
284
- }
285
-}
286
-
287
-#if !DEBUG_BISECT
288
-#define show_list(a,b,c,d) do { ; } while (0)
289
-#else
290
-static void show_list(const char *debug, int counted, int nr,
291
- struct commit_list *list)
292
-{
293
- struct commit_list *p;
294
-
295
- fprintf(stderr, "%s (%d/%d)\n", debug, counted, nr);
296
-
297
- for (p = list; p; p = p->next) {
298
- struct commit_list *pp;
299
- struct commit *commit = p->item;
300
- unsigned flags = commit->object.flags;
301
- enum object_type type;
302
- unsigned long size;
303
- char *buf = read_sha1_file(commit->object.sha1, &type, &size);
304
- char *ep, *sp;
305
-
306
- fprintf(stderr, "%c%c%c ",
307
- (flags & TREESAME) ? ' ' : 'T',
308
- (flags & UNINTERESTING) ? 'U' : ' ',
309
- (flags & COUNTED) ? 'C' : ' ');
310
- if (commit->util)
311
- fprintf(stderr, "%3d", weight(p));
312
- else
313
- fprintf(stderr, "---");
314
- fprintf(stderr, " %.*s", 8, sha1_to_hex(commit->object.sha1));
315
- for (pp = commit->parents; pp; pp = pp->next)
316
- fprintf(stderr, " %.*s", 8,
317
- sha1_to_hex(pp->item->object.sha1));
318
-
319
- sp = strstr(buf, "\n\n");
320
- if (sp) {
321
- sp += 2;
322
- for (ep = sp; *ep && *ep != '\n'; ep++)
323
- ;
324
- fprintf(stderr, " %.*s", (int)(ep - sp), sp);
325
- }
326
- fprintf(stderr, "\n");
327
- }
328
-}
329
-#endif /* DEBUG_BISECT */
330
-
331
-static struct commit_list *best_bisection(struct commit_list *list, int nr)
332
-{
333
- struct commit_list *p, *best;
334
- int best_distance = -1;
335
-
336
- best = list;
337
- for (p = list; p; p = p->next) {
338
- int distance;
339
- unsigned flags = p->item->object.flags;
340
-
341
- if (flags & TREESAME)
342
- continue;
343
- distance = weight(p);
344
- if (nr - distance < distance)
345
- distance = nr - distance;
346
- if (distance > best_distance) {
347
- best = p;
348
- best_distance = distance;
349
- }
350
- }
351
-
352
- return best;
353
-}
354
-
355
-struct commit_dist {
356
- struct commit *commit;
357
- int distance;
358
-};
359
-
360
-static int compare_commit_dist(const void *a_, const void *b_)
361
-{
362
- struct commit_dist *a, *b;
363
-
364
- a = (struct commit_dist *)a_;
365
- b = (struct commit_dist *)b_;
366
- if (a->distance != b->distance)
367
- return b->distance - a->distance; /* desc sort */
368
- return hashcmp(a->commit->object.sha1, b->commit->object.sha1);
369
-}
370
-
371
-static struct commit_list *best_bisection_sorted(struct commit_list *list, int nr)
372
-{
373
- struct commit_list *p;
374
- struct commit_dist *array = xcalloc(nr, sizeof(*array));
375
- int cnt, i;
376
-
377
- for (p = list, cnt = 0; p; p = p->next) {
378
- int distance;
379
- unsigned flags = p->item->object.flags;
380
-
381
- if (flags & TREESAME)
382
- continue;
383
- distance = weight(p);
384
- if (nr - distance < distance)
385
- distance = nr - distance;
386
- array[cnt].commit = p->item;
387
- array[cnt].distance = distance;
388
- cnt++;
389
- }
390
- qsort(array, cnt, sizeof(*array), compare_commit_dist);
391
- for (p = list, i = 0; i < cnt; i++) {
392
- struct name_decoration *r = xmalloc(sizeof(*r) + 100);
393
- struct object *obj = &(array[i].commit->object);
394
-
395
- sprintf(r->name, "dist=%d", array[i].distance);
396
- r->next = add_decoration(&name_decoration, obj, r);
397
- p->item = array[i].commit;
398
- p = p->next;
399
- }
400
- if (p)
401
- p->next = NULL;
402
- free(array);
403
- return list;
404
-}
405
-
406
-/*
407
- * zero or positive weight is the number of interesting commits it can
408
- * reach, including itself. Especially, weight = 0 means it does not
409
- * reach any tree-changing commits (e.g. just above uninteresting one
410
- * but traversal is with pathspec).
411
- *
412
- * weight = -1 means it has one parent and its distance is yet to
413
- * be computed.
414
- *
415
- * weight = -2 means it has more than one parent and its distance is
416
- * unknown. After running count_distance() first, they will get zero
417
- * or positive distance.
418
- */
419
-static struct commit_list *do_find_bisection(struct commit_list *list,
420
- int nr, int *weights,
421
- int find_all)
422
-{
423
- int n, counted;
424
- struct commit_list *p;
425
-
426
- counted = 0;
427
-
428
- for (n = 0, p = list; p; p = p->next) {
429
- struct commit *commit = p->item;
430
- unsigned flags = commit->object.flags;
431
-
432
- p->item->util = &weights[n++];
433
- switch (count_interesting_parents(commit)) {
434
- case 0:
435
- if (!(flags & TREESAME)) {
436
- weight_set(p, 1);
437
- counted++;
438
- show_list("bisection 2 count one",
439
- counted, nr, list);
440
- }
441
- /*
442
- * otherwise, it is known not to reach any
443
- * tree-changing commit and gets weight 0.
444
- */
445
- break;
446
- case 1:
447
- weight_set(p, -1);
448
- break;
449
- default:
450
- weight_set(p, -2);
451
- break;
452
- }
453
- }
454
-
455
- show_list("bisection 2 initialize", counted, nr, list);
456
-
457
- /*
458
- * If you have only one parent in the resulting set
459
- * then you can reach one commit more than that parent
460
- * can reach. So we do not have to run the expensive
461
- * count_distance() for single strand of pearls.
462
- *
463
- * However, if you have more than one parents, you cannot
464
- * just add their distance and one for yourself, since
465
- * they usually reach the same ancestor and you would
466
- * end up counting them twice that way.
467
- *
468
- * So we will first count distance of merges the usual
469
- * way, and then fill the blanks using cheaper algorithm.
470
- */
471
- for (p = list; p; p = p->next) {
472
- if (p->item->object.flags & UNINTERESTING)
473
- continue;
474
- if (weight(p) != -2)
475
- continue;
476
- weight_set(p, count_distance(p));
477
- clear_distance(list);
478
-
479
- /* Does it happen to be at exactly half-way? */
480
- if (!find_all && halfway(p, nr))
481
- return p;
482
- counted++;
483
- }
484
-
485
- show_list("bisection 2 count_distance", counted, nr, list);
486
-
487
- while (counted < nr) {
488
- for (p = list; p; p = p->next) {
489
- struct commit_list *q;
490
- unsigned flags = p->item->object.flags;
491
-
492
- if (0 <= weight(p))
493
- continue;
494
- for (q = p->item->parents; q; q = q->next) {
495
- if (q->item->object.flags & UNINTERESTING)
496
- continue;
497
- if (0 <= weight(q))
498
- break;
499
- }
500
- if (!q)
501
- continue;
502
-
503
- /*
504
- * weight for p is unknown but q is known.
505
- * add one for p itself if p is to be counted,
506
- * otherwise inherit it from q directly.
507
- */
508
- if (!(flags & TREESAME)) {
509
- weight_set(p, weight(q)+1);
510
- counted++;
511
- show_list("bisection 2 count one",
512
- counted, nr, list);
513
- }
514
- else
515
- weight_set(p, weight(q));
516
-
517
- /* Does it happen to be at exactly half-way? */
518
- if (!find_all && halfway(p, nr))
519
- return p;
520
- }
521
- }
522
-
523
- show_list("bisection 2 counted all", counted, nr, list);
524
-
525
- if (!find_all)
526
- return best_bisection(list, nr);
527
- else
528
- return best_bisection_sorted(list, nr);
529
-}
530
-
531
-static struct commit_list *find_bisection(struct commit_list *list,
532
- int *reaches, int *all,
533
- int find_all)
534
-{
535
- int nr, on_list;
536
- struct commit_list *p, *best, *next, *last;
537
- int *weights;
538
-
539
- show_list("bisection 2 entry", 0, 0, list);
540
-
541
- /*
542
- * Count the number of total and tree-changing items on the
543
- * list, while reversing the list.
544
- */
545
- for (nr = on_list = 0, last = NULL, p = list;
546
- p;
547
- p = next) {
548
- unsigned flags = p->item->object.flags;
549
-
550
- next = p->next;
551
- if (flags & UNINTERESTING)
552
- continue;
553
- p->next = last;
554
- last = p;
555
- if (!(flags & TREESAME))
556
- nr++;
557
- on_list++;
558
- }
559
- list = last;
560
- show_list("bisection 2 sorted", 0, nr, list);
561
-
562
- *all = nr;
563
- weights = xcalloc(on_list, sizeof(*weights));
564
-
565
- /* Do the real work of finding bisection commit. */
566
- best = do_find_bisection(list, nr, weights, find_all);
567
- if (best) {
568
- if (!find_all)
569
- best->next = NULL;
570
- *reaches = weight(best);
571
- }
572
- free(weights);
573
- return best;
574
-}
575
-
190
static inline int log2i(int n)
191
{
192
int log2 = 0;