rev-list: call new "filter_skip" function
This patch implements a new "filter_skip" function in C in "bisect.c" that will later replace the existing implementation in shell in "git-bisect.sh". An array is used to store the skipped commits. But the array is not yet fed anything. 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
951886481668b97485640a1b24fc73fccff0d629
3 files changed
+93
-6
bisect.c
+63
@@ -4,6 +4,9 @@
4
#include "revision.h"
5
#include "bisect.h"
6
7
+static unsigned char (*skipped_sha1)[20];
8
+static int skipped_sha1_nr;
9
+
10
/* bits #0-15 in revision.h */
11
12
#define COUNTED (1u<<16)
@@ -386,3 +389,63 @@ struct commit_list *find_bisection(struct commit_list *list,
389
return best;
390
}
391
392
+static int skipcmp(const void *a, const void *b)
393
+{
394
+ return hashcmp(a, b);
395
+}
396
+
397
+static void prepare_skipped(void)
398
+{
399
+ qsort(skipped_sha1, skipped_sha1_nr, sizeof(*skipped_sha1), skipcmp);
400
+}
401
+
402
+static int lookup_skipped(unsigned char *sha1)
403
+{
404
+ int lo, hi;
405
+ lo = 0;
406
+ hi = skipped_sha1_nr;
407
+ while (lo < hi) {
408
+ int mi = (lo + hi) / 2;
409
+ int cmp = hashcmp(sha1, skipped_sha1[mi]);
410
+ if (!cmp)
411
+ return mi;
412
+ if (cmp < 0)
413
+ hi = mi;
414
+ else
415
+ lo = mi + 1;
416
+ }
417
+ return -lo - 1;
418
+}
419
+
420
+struct commit_list *filter_skipped(struct commit_list *list,
421
+ struct commit_list **tried,
422
+ int show_all)
423
+{
424
+ struct commit_list *filtered = NULL, **f = &filtered;
425
+
426
+ *tried = NULL;
427
+
428
+ if (!skipped_sha1_nr)
429
+ return list;
430
+
431
+ prepare_skipped();
432
+
433
+ while (list) {
434
+ struct commit_list *next = list->next;
435
+ list->next = NULL;
436
+ if (0 <= lookup_skipped(list->item->object.sha1)) {
437
+ /* Move current to tried list */
438
+ *tried = list;
439
+ tried = &list->next;
440
+ } else {
441
+ if (!show_all)
442
+ return list;
443
+ /* Move current to filtered list */
444
+ *f = list;
445
+ f = &list->next;
446
+ }
447
+ list = next;
448
+ }
449
+
450
+ return filtered;
451
+}
bisect.h
+5
-1
@@ -5,7 +5,11 @@ extern struct commit_list *find_bisection(struct commit_list *list,
5
int *reaches, int *all,
6
int find_all);
7
8
+extern struct commit_list *filter_skipped(struct commit_list *list,
9
+ struct commit_list **tried,
10
+ int show_all);
11
+
12
extern int show_bisect_vars(struct rev_info *revs, int reaches, int all,
9
- int show_all);
13
+ int show_all, int show_tried);
14
15
#endif
builtin-rev-list.c
+25
-5
@@ -226,14 +226,28 @@ static int estimate_bisect_steps(int all)
226
return (e < 3 * x) ? n : n - 1;
227
}
228
229
-int show_bisect_vars(struct rev_info *revs, int reaches, int all, int show_all)
229
+static void show_tried_revs(struct commit_list *tried)
230
+{
231
+ printf("bisect_tried='");
232
+ for (;tried; tried = tried->next) {
233
+ char *format = tried->next ? "%s|" : "%s";
234
+ printf(format, sha1_to_hex(tried->item->object.sha1));
235
+ }
236
+ printf("'\n");
237
+}
238
+
239
+int show_bisect_vars(struct rev_info *revs, int reaches, int all,
240
+ int show_all, int show_tried)
241
{
242
int cnt;
232
- char hex[41];
243
+ char hex[41] = "";
244
+ struct commit_list *tried;
245
234
- if (!revs->commits)
246
+ if (!revs->commits && !show_tried)
247
return 1;
248
249
+ revs->commits = filter_skipped(revs->commits, &tried, show_all);
250
+
251
/*
252
* revs->commits can reach "reaches" commits among
253
* "all" commits. If it is good, then there are
@@ -247,13 +261,16 @@ int show_bisect_vars(struct rev_info *revs, int reaches, int all, int show_all)
261
if (cnt < reaches)
262
cnt = reaches;
263
250
- strcpy(hex, sha1_to_hex(revs->commits->item->object.sha1));
264
+ if (revs->commits)
265
+ strcpy(hex, sha1_to_hex(revs->commits->item->object.sha1));
266
267
if (show_all) {
268
traverse_commit_list(revs, show_commit, show_object);
269
printf("------\n");
270
}
271
272
+ if (show_tried)
273
+ show_tried_revs(tried);
274
printf("bisect_rev=%s\n"
275
"bisect_nr=%d\n"
276
"bisect_good=%d\n"
@@ -278,6 +295,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
295
int bisect_list = 0;
296
int bisect_show_vars = 0;
297
int bisect_find_all = 0;
298
+ int bisect_show_all = 0;
299
int quiet = 0;
300
301
git_config(git_default_config, NULL);
@@ -305,6 +323,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
323
if (!strcmp(arg, "--bisect-all")) {
324
bisect_list = 1;
325
bisect_find_all = 1;
326
+ bisect_show_all = 1;
327
revs.show_decorations = 1;
328
continue;
329
}
@@ -357,9 +376,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
376
377
revs.commits = find_bisection(revs.commits, &reaches, &all,
378
bisect_find_all);
379
+
380
if (bisect_show_vars)
381
return show_bisect_vars(&revs, reaches, all,
362
- bisect_find_all);
382
+ bisect_show_all, 0);
383
}
384
385
traverse_commit_list(&revs,