Coverage Report

Created: 2025-12-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/bisect.c
Line
Count
Source
1
#define USE_THE_REPOSITORY_VARIABLE
2
#define DISABLE_SIGN_COMPARE_WARNINGS
3
4
#include "git-compat-util.h"
5
#include "config.h"
6
#include "commit.h"
7
#include "diff.h"
8
#include "environment.h"
9
#include "gettext.h"
10
#include "hex.h"
11
#include "revision.h"
12
#include "refs.h"
13
#include "list-objects.h"
14
#include "quote.h"
15
#include "run-command.h"
16
#include "log-tree.h"
17
#include "bisect.h"
18
#include "oid-array.h"
19
#include "strvec.h"
20
#include "commit-slab.h"
21
#include "commit-reach.h"
22
#include "object-name.h"
23
#include "odb.h"
24
#include "path.h"
25
#include "dir.h"
26
27
static struct oid_array good_revs;
28
static struct oid_array skipped_revs;
29
30
static struct object_id *current_bad_oid;
31
32
static char *term_bad;
33
static char *term_good;
34
35
/* Remember to update object flag allocation in object.h */
36
0
#define COUNTED   (1u<<16)
37
38
/*
39
 * This is a truly stupid algorithm, but it's only
40
 * used for bisection, and we just don't care enough.
41
 *
42
 * We care just barely enough to avoid recursing for
43
 * non-merge entries.
44
 */
45
static int count_distance(struct commit_list *entry)
46
0
{
47
0
  int nr = 0;
48
49
0
  while (entry) {
50
0
    struct commit *commit = entry->item;
51
0
    struct commit_list *p;
52
53
0
    if (commit->object.flags & (UNINTERESTING | COUNTED))
54
0
      break;
55
0
    if (!(commit->object.flags & TREESAME))
56
0
      nr++;
57
0
    commit->object.flags |= COUNTED;
58
0
    p = commit->parents;
59
0
    entry = p;
60
0
    if (p) {
61
0
      p = p->next;
62
0
      while (p) {
63
0
        nr += count_distance(p);
64
0
        p = p->next;
65
0
      }
66
0
    }
67
0
  }
68
69
0
  return nr;
70
0
}
71
72
static void clear_distance(struct commit_list *list)
73
0
{
74
0
  while (list) {
75
0
    struct commit *commit = list->item;
76
0
    commit->object.flags &= ~COUNTED;
77
0
    list = list->next;
78
0
  }
79
0
}
80
81
0
define_commit_slab(commit_weight, int *);
Unexecuted instantiation: bisect.c:init_commit_weight_with_stride
Unexecuted instantiation: bisect.c:commit_weight_at_peek
Unexecuted instantiation: bisect.c:clear_commit_weight
82
0
static struct commit_weight commit_weight;
83
0
84
0
#define DEBUG_BISECT 0
85
86
static inline int weight(struct commit_list *elem)
87
0
{
88
0
  return **commit_weight_at(&commit_weight, elem->item);
89
0
}
90
91
static inline void weight_set(struct commit_list *elem, int weight)
92
0
{
93
0
  **commit_weight_at(&commit_weight, elem->item) = weight;
94
0
}
95
96
static int count_interesting_parents(struct commit *commit, unsigned bisect_flags)
97
0
{
98
0
  struct commit_list *p;
99
0
  int count;
100
101
0
  for (count = 0, p = commit->parents; p; p = p->next) {
102
0
    if (!(p->item->object.flags & UNINTERESTING))
103
0
      count++;
104
0
    if (bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY)
105
0
      break;
106
0
  }
107
0
  return count;
108
0
}
109
110
static inline int approx_halfway(struct commit_list *p, int nr)
111
0
{
112
0
  int diff;
113
114
  /*
115
   * Don't short-cut something we are not going to return!
116
   */
117
0
  if (p->item->object.flags & TREESAME)
118
0
    return 0;
119
0
  if (DEBUG_BISECT)
120
0
    return 0;
121
  /*
122
   * For small number of commits 2 and 3 are halfway of 5, and
123
   * 3 is halfway of 6 but 2 and 4 are not.
124
   */
125
0
  diff = 2 * weight(p) - nr;
126
0
  switch (diff) {
127
0
  case -1: case 0: case 1:
128
0
    return 1;
129
0
  default:
130
    /*
131
     * For large number of commits we are not so strict, it's
132
     * good enough if it's within ~0.1% of the halfway point,
133
     * e.g. 5000 is exactly halfway of 10000, but we consider
134
     * the values [4996, 5004] as halfway as well.
135
     */
136
0
    if (abs(diff) < nr / 1024)
137
0
      return 1;
138
0
    return 0;
139
0
  }
140
0
}
141
142
static void show_list(const char *debug, int counted, int nr,
143
          struct commit_list *list)
144
0
{
145
0
  struct commit_list *p;
146
147
0
  if (!DEBUG_BISECT)
148
0
    return;
149
150
0
  fprintf(stderr, "%s (%d/%d)\n", debug, counted, nr);
151
152
0
  for (p = list; p; p = p->next) {
153
0
    struct commit_list *pp;
154
0
    struct commit *commit = p->item;
155
0
    unsigned commit_flags = commit->object.flags;
156
0
    enum object_type type;
157
0
    unsigned long size;
158
0
    char *buf = odb_read_object(the_repository->objects,
159
0
              &commit->object.oid, &type,
160
0
              &size);
161
0
    const char *subject_start;
162
0
    int subject_len;
163
164
0
    if (!buf)
165
0
      die(_("unable to read %s"), oid_to_hex(&commit->object.oid));
166
167
0
    fprintf(stderr, "%c%c%c ",
168
0
      (commit_flags & TREESAME) ? ' ' : 'T',
169
0
      (commit_flags & UNINTERESTING) ? 'U' : ' ',
170
0
      (commit_flags & COUNTED) ? 'C' : ' ');
171
0
    if (*commit_weight_at(&commit_weight, p->item))
172
0
      fprintf(stderr, "%3d", weight(p));
173
0
    else
174
0
      fprintf(stderr, "---");
175
0
    fprintf(stderr, " %.*s", 8, oid_to_hex(&commit->object.oid));
176
0
    for (pp = commit->parents; pp; pp = pp->next)
177
0
      fprintf(stderr, " %.*s", 8,
178
0
        oid_to_hex(&pp->item->object.oid));
179
180
0
    subject_len = find_commit_subject(buf, &subject_start);
181
0
    if (subject_len)
182
0
      fprintf(stderr, " %.*s", subject_len, subject_start);
183
0
    fprintf(stderr, "\n");
184
0
  }
185
0
}
186
187
static struct commit_list *best_bisection(struct commit_list *list, int nr)
188
0
{
189
0
  struct commit_list *p, *best;
190
0
  int best_distance = -1;
191
192
0
  best = list;
193
0
  for (p = list; p; p = p->next) {
194
0
    int distance;
195
0
    unsigned commit_flags = p->item->object.flags;
196
197
0
    if (commit_flags & TREESAME)
198
0
      continue;
199
0
    distance = weight(p);
200
0
    if (nr - distance < distance)
201
0
      distance = nr - distance;
202
0
    if (distance > best_distance) {
203
0
      best = p;
204
0
      best_distance = distance;
205
0
    }
206
0
  }
207
208
0
  return best;
209
0
}
210
211
struct commit_dist {
212
  struct commit *commit;
213
  int distance;
214
};
215
216
static int compare_commit_dist(const void *a_, const void *b_)
217
0
{
218
0
  struct commit_dist *a, *b;
219
220
0
  a = (struct commit_dist *)a_;
221
0
  b = (struct commit_dist *)b_;
222
0
  if (a->distance != b->distance)
223
0
    return b->distance - a->distance; /* desc sort */
224
0
  return oidcmp(&a->commit->object.oid, &b->commit->object.oid);
225
0
}
226
227
static struct commit_list *best_bisection_sorted(struct commit_list *list, int nr)
228
0
{
229
0
  struct commit_list *p;
230
0
  struct commit_dist *array = xcalloc(nr, sizeof(*array));
231
0
  struct strbuf buf = STRBUF_INIT;
232
0
  int cnt, i;
233
234
0
  for (p = list, cnt = 0; p; p = p->next) {
235
0
    int distance;
236
0
    unsigned commit_flags = p->item->object.flags;
237
238
0
    if (commit_flags & TREESAME)
239
0
      continue;
240
0
    distance = weight(p);
241
0
    if (nr - distance < distance)
242
0
      distance = nr - distance;
243
0
    array[cnt].commit = p->item;
244
0
    array[cnt].distance = distance;
245
0
    cnt++;
246
0
  }
247
0
  QSORT(array, cnt, compare_commit_dist);
248
0
  for (p = list, i = 0; i < cnt; i++) {
249
0
    struct object *obj = &(array[i].commit->object);
250
251
0
    strbuf_reset(&buf);
252
0
    strbuf_addf(&buf, "dist=%d", array[i].distance);
253
0
    add_name_decoration(DECORATION_NONE, buf.buf, obj);
254
255
0
    p->item = array[i].commit;
256
0
    if (i < cnt - 1)
257
0
      p = p->next;
258
0
  }
259
0
  if (p) {
260
0
    free_commit_list(p->next);
261
0
    p->next = NULL;
262
0
  }
263
0
  strbuf_release(&buf);
264
0
  free(array);
265
0
  return list;
266
0
}
267
268
/*
269
 * zero or positive weight is the number of interesting commits it can
270
 * reach, including itself.  Especially, weight = 0 means it does not
271
 * reach any tree-changing commits (e.g. just above uninteresting one
272
 * but traversal is with pathspec).
273
 *
274
 * weight = -1 means it has one parent and its distance is yet to
275
 * be computed.
276
 *
277
 * weight = -2 means it has more than one parent and its distance is
278
 * unknown.  After running count_distance() first, they will get zero
279
 * or positive distance.
280
 */
281
static struct commit_list *do_find_bisection(struct commit_list *list,
282
               int nr, int *weights,
283
               unsigned bisect_flags)
284
0
{
285
0
  int n, counted;
286
0
  struct commit_list *p;
287
288
0
  counted = 0;
289
290
0
  for (n = 0, p = list; p; p = p->next) {
291
0
    struct commit *commit = p->item;
292
0
    unsigned commit_flags = commit->object.flags;
293
294
0
    *commit_weight_at(&commit_weight, p->item) = &weights[n++];
295
0
    switch (count_interesting_parents(commit, bisect_flags)) {
296
0
    case 0:
297
0
      if (!(commit_flags & TREESAME)) {
298
0
        weight_set(p, 1);
299
0
        counted++;
300
0
        show_list("bisection 2 count one",
301
0
            counted, nr, list);
302
0
      }
303
      /*
304
       * otherwise, it is known not to reach any
305
       * tree-changing commit and gets weight 0.
306
       */
307
0
      break;
308
0
    case 1:
309
0
      weight_set(p, -1);
310
0
      break;
311
0
    default:
312
0
      weight_set(p, -2);
313
0
      break;
314
0
    }
315
0
  }
316
317
0
  show_list("bisection 2 initialize", counted, nr, list);
318
319
  /*
320
   * If you have only one parent in the resulting set
321
   * then you can reach one commit more than that parent
322
   * can reach.  So we do not have to run the expensive
323
   * count_distance() for single strand of pearls.
324
   *
325
   * However, if you have more than one parents, you cannot
326
   * just add their distance and one for yourself, since
327
   * they usually reach the same ancestor and you would
328
   * end up counting them twice that way.
329
   *
330
   * So we will first count distance of merges the usual
331
   * way, and then fill the blanks using cheaper algorithm.
332
   */
333
0
  for (p = list; p; p = p->next) {
334
0
    if (p->item->object.flags & UNINTERESTING)
335
0
      continue;
336
0
    if (weight(p) != -2)
337
0
      continue;
338
0
    if (bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY)
339
0
      BUG("shouldn't be calling count-distance in fp mode");
340
0
    weight_set(p, count_distance(p));
341
0
    clear_distance(list);
342
343
    /* Does it happen to be at half-way? */
344
0
    if (!(bisect_flags & FIND_BISECTION_ALL) &&
345
0
          approx_halfway(p, nr))
346
0
      return p;
347
0
    counted++;
348
0
  }
349
350
0
  show_list("bisection 2 count_distance", counted, nr, list);
351
352
0
  while (counted < nr) {
353
0
    for (p = list; p; p = p->next) {
354
0
      struct commit_list *q;
355
0
      unsigned commit_flags = p->item->object.flags;
356
357
0
      if (0 <= weight(p))
358
0
        continue;
359
360
0
      for (q = p->item->parents;
361
0
           q;
362
0
           q = bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY ? NULL : q->next) {
363
0
        if (q->item->object.flags & UNINTERESTING)
364
0
          continue;
365
0
        if (0 <= weight(q))
366
0
          break;
367
0
      }
368
0
      if (!q)
369
0
        continue;
370
371
      /*
372
       * weight for p is unknown but q is known.
373
       * add one for p itself if p is to be counted,
374
       * otherwise inherit it from q directly.
375
       */
376
0
      if (!(commit_flags & TREESAME)) {
377
0
        weight_set(p, weight(q)+1);
378
0
        counted++;
379
0
        show_list("bisection 2 count one",
380
0
            counted, nr, list);
381
0
      }
382
0
      else
383
0
        weight_set(p, weight(q));
384
385
      /* Does it happen to be at half-way? */
386
0
      if (!(bisect_flags & FIND_BISECTION_ALL) &&
387
0
            approx_halfway(p, nr))
388
0
        return p;
389
0
    }
390
0
  }
391
392
0
  show_list("bisection 2 counted all", counted, nr, list);
393
394
0
  if (!(bisect_flags & FIND_BISECTION_ALL))
395
0
    return best_bisection(list, nr);
396
0
  else
397
0
    return best_bisection_sorted(list, nr);
398
0
}
399
400
void find_bisection(struct commit_list **commit_list, int *reaches,
401
        int *all, unsigned bisect_flags)
402
0
{
403
0
  int nr, on_list;
404
0
  struct commit_list *list, *p, *best, *next, *last;
405
0
  int *weights;
406
407
0
  show_list("bisection 2 entry", 0, 0, *commit_list);
408
0
  init_commit_weight(&commit_weight);
409
410
  /*
411
   * Count the number of total and tree-changing items on the
412
   * list, while reversing the list.
413
   */
414
0
  for (nr = on_list = 0, last = NULL, p = *commit_list;
415
0
       p;
416
0
       p = next) {
417
0
    unsigned commit_flags = p->item->object.flags;
418
419
0
    next = p->next;
420
0
    if (commit_flags & UNINTERESTING) {
421
0
      free(p);
422
0
      continue;
423
0
    }
424
0
    p->next = last;
425
0
    last = p;
426
0
    if (!(commit_flags & TREESAME))
427
0
      nr++;
428
0
    on_list++;
429
0
  }
430
0
  list = last;
431
0
  show_list("bisection 2 sorted", 0, nr, list);
432
433
0
  *all = nr;
434
0
  CALLOC_ARRAY(weights, on_list);
435
436
  /* Do the real work of finding bisection commit. */
437
0
  best = do_find_bisection(list, nr, weights, bisect_flags);
438
0
  if (best) {
439
0
    if (!(bisect_flags & FIND_BISECTION_ALL)) {
440
0
      list->item = best->item;
441
0
      free_commit_list(list->next);
442
0
      best = list;
443
0
      best->next = NULL;
444
0
    }
445
0
    *reaches = weight(best);
446
0
  }
447
0
  *commit_list = best;
448
449
0
  free(weights);
450
0
  clear_commit_weight(&commit_weight);
451
0
}
452
453
static int register_ref(const struct reference *ref, void *cb_data UNUSED)
454
0
{
455
0
  struct strbuf good_prefix = STRBUF_INIT;
456
0
  strbuf_addstr(&good_prefix, term_good);
457
0
  strbuf_addstr(&good_prefix, "-");
458
459
0
  if (!strcmp(ref->name, term_bad)) {
460
0
    free(current_bad_oid);
461
0
    current_bad_oid = xmalloc(sizeof(*current_bad_oid));
462
0
    oidcpy(current_bad_oid, ref->oid);
463
0
  } else if (starts_with(ref->name, good_prefix.buf)) {
464
0
    oid_array_append(&good_revs, ref->oid);
465
0
  } else if (starts_with(ref->name, "skip-")) {
466
0
    oid_array_append(&skipped_revs, ref->oid);
467
0
  }
468
469
0
  strbuf_release(&good_prefix);
470
471
0
  return 0;
472
0
}
473
474
static int read_bisect_refs(void)
475
0
{
476
0
  return refs_for_each_ref_in(get_main_ref_store(the_repository),
477
0
            "refs/bisect/", register_ref, NULL);
478
0
}
479
480
static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES")
481
static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK")
482
static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN")
483
static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START")
484
static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG")
485
static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS")
486
static GIT_PATH_FUNC(git_path_bisect_first_parent, "BISECT_FIRST_PARENT")
487
488
static void read_bisect_paths(struct strvec *array)
489
0
{
490
0
  struct strbuf str = STRBUF_INIT;
491
0
  const char *filename = git_path_bisect_names();
492
0
  FILE *fp = xfopen(filename, "r");
493
494
0
  while (strbuf_getline_lf(&str, fp) != EOF) {
495
0
    strbuf_trim(&str);
496
0
    if (sq_dequote_to_strvec(str.buf, array))
497
0
      die(_("Badly quoted content in file '%s': %s"),
498
0
          filename, str.buf);
499
0
  }
500
501
0
  strbuf_release(&str);
502
0
  fclose(fp);
503
0
}
504
505
static char *join_oid_array_hex(struct oid_array *array, char delim)
506
0
{
507
0
  struct strbuf joined_hexs = STRBUF_INIT;
508
0
  int i;
509
510
0
  for (i = 0; i < array->nr; i++) {
511
0
    strbuf_addstr(&joined_hexs, oid_to_hex(array->oid + i));
512
0
    if (i + 1 < array->nr)
513
0
      strbuf_addch(&joined_hexs, delim);
514
0
  }
515
516
0
  return strbuf_detach(&joined_hexs, NULL);
517
0
}
518
519
/*
520
 * In this function, passing a not NULL skipped_first is very special.
521
 * It means that we want to know if the first commit in the list is
522
 * skipped because we will want to test a commit away from it if it is
523
 * indeed skipped.
524
 * So if the first commit is skipped, we cannot take the shortcut to
525
 * just "return list" when we find the first non skipped commit, we
526
 * have to return a fully filtered list.
527
 *
528
 * We use (*skipped_first == -1) to mean "it has been found that the
529
 * first commit is not skipped". In this case *skipped_first is set back
530
 * to 0 just before the function returns.
531
 */
532
struct commit_list *filter_skipped(struct commit_list *list,
533
           struct commit_list **tried,
534
           int show_all,
535
           int *count,
536
           int *skipped_first)
537
0
{
538
0
  struct commit_list *filtered = NULL, **f = &filtered;
539
540
0
  *tried = NULL;
541
542
0
  if (skipped_first)
543
0
    *skipped_first = 0;
544
0
  if (count)
545
0
    *count = 0;
546
547
0
  if (!skipped_revs.nr)
548
0
    return list;
549
550
0
  while (list) {
551
0
    struct commit_list *next = list->next;
552
0
    list->next = NULL;
553
0
    if (0 <= oid_array_lookup(&skipped_revs, &list->item->object.oid)) {
554
0
      if (skipped_first && !*skipped_first)
555
0
        *skipped_first = 1;
556
      /* Move current to tried list */
557
0
      *tried = list;
558
0
      tried = &list->next;
559
0
    } else {
560
0
      if (!show_all) {
561
0
        if (!skipped_first || !*skipped_first) {
562
0
          free_commit_list(next);
563
0
          free_commit_list(filtered);
564
0
          return list;
565
0
        }
566
0
      } else if (skipped_first && !*skipped_first) {
567
        /* This means we know it's not skipped */
568
0
        *skipped_first = -1;
569
0
      }
570
      /* Move current to filtered list */
571
0
      *f = list;
572
0
      f = &list->next;
573
0
      if (count)
574
0
        (*count)++;
575
0
    }
576
0
    list = next;
577
0
  }
578
579
0
  if (skipped_first && *skipped_first == -1)
580
0
    *skipped_first = 0;
581
582
0
  return filtered;
583
0
}
584
585
0
#define PRN_MODULO 32768
586
587
/*
588
 * This is a pseudo random number generator based on "man 3 rand".
589
 * It is not used properly because the seed is the argument and it
590
 * is increased by one between each call, but that should not matter
591
 * for this application.
592
 */
593
static unsigned get_prn(unsigned count)
594
0
{
595
0
  count = count * 1103515245 + 12345;
596
0
  return (count/65536) % PRN_MODULO;
597
0
}
598
599
/*
600
 * Custom integer square root from
601
 * https://en.wikipedia.org/wiki/Integer_square_root
602
 */
603
static int sqrti(int val)
604
0
{
605
0
  float d, x = val;
606
607
0
  if (!val)
608
0
    return 0;
609
610
0
  do {
611
0
    float y = (x + (float)val / x) / 2;
612
0
    d = (y > x) ? y - x : x - y;
613
0
    x = y;
614
0
  } while (d >= 0.5);
615
616
0
  return (int)x;
617
0
}
618
619
static struct commit_list *skip_away(struct commit_list *list, int count)
620
0
{
621
0
  struct commit_list *cur, *previous, *result = list;
622
0
  int prn, index, i;
623
624
0
  prn = get_prn(count);
625
0
  index = (count * prn / PRN_MODULO) * sqrti(prn) / sqrti(PRN_MODULO);
626
627
0
  cur = list;
628
0
  previous = NULL;
629
630
0
  for (i = 0; cur; cur = cur->next, i++) {
631
0
    if (i == index) {
632
0
      if (!oideq(&cur->item->object.oid, current_bad_oid))
633
0
        result = cur;
634
0
      else if (previous)
635
0
        result = previous;
636
0
      else
637
0
        result = list;
638
0
      break;
639
0
    }
640
0
    previous = cur;
641
0
  }
642
643
0
  for (cur = list; cur != result; ) {
644
0
    struct commit_list *next = cur->next;
645
0
    free(cur);
646
0
    cur = next;
647
0
  }
648
649
0
  return result;
650
0
}
651
652
static struct commit_list *managed_skipped(struct commit_list *list,
653
             struct commit_list **tried)
654
0
{
655
0
  int count, skipped_first;
656
657
0
  *tried = NULL;
658
659
0
  if (!skipped_revs.nr)
660
0
    return list;
661
662
0
  list = filter_skipped(list, tried, 0, &count, &skipped_first);
663
664
0
  if (!skipped_first)
665
0
    return list;
666
667
0
  return skip_away(list, count);
668
0
}
669
670
static void bisect_rev_setup(struct repository *r, struct rev_info *revs,
671
           struct strvec *rev_argv,
672
           const char *prefix,
673
           const char *bad_format, const char *good_format,
674
           int read_paths)
675
0
{
676
0
  int i;
677
678
0
  repo_init_revisions(r, revs, prefix);
679
0
  revs->abbrev = 0;
680
0
  revs->commit_format = CMIT_FMT_UNSPECIFIED;
681
682
  /* rev_argv.argv[0] will be ignored by setup_revisions */
683
0
  strvec_push(rev_argv, "bisect_rev_setup");
684
0
  strvec_pushf(rev_argv, bad_format, oid_to_hex(current_bad_oid));
685
0
  for (i = 0; i < good_revs.nr; i++)
686
0
    strvec_pushf(rev_argv, good_format,
687
0
           oid_to_hex(good_revs.oid + i));
688
0
  strvec_push(rev_argv, "--");
689
0
  if (read_paths)
690
0
    read_bisect_paths(rev_argv);
691
692
0
  setup_revisions_from_strvec(rev_argv, revs, NULL);
693
0
}
694
695
static void bisect_common(struct rev_info *revs)
696
0
{
697
0
  if (prepare_revision_walk(revs))
698
0
    die("revision walk setup failed");
699
0
  if (revs->tree_objects)
700
0
    mark_edges_uninteresting(revs, NULL, 0);
701
0
}
702
703
static enum bisect_error error_if_skipped_commits(struct commit_list *tried,
704
            const struct object_id *bad)
705
0
{
706
0
  if (!tried)
707
0
    return BISECT_OK;
708
709
0
  printf("There are only 'skip'ped commits left to test.\n"
710
0
         "The first %s commit could be any of:\n", term_bad);
711
712
0
  for ( ; tried; tried = tried->next)
713
0
    printf("%s\n", oid_to_hex(&tried->item->object.oid));
714
715
0
  if (bad)
716
0
    printf("%s\n", oid_to_hex(bad));
717
0
  printf(_("We cannot bisect more!\n"));
718
719
0
  return BISECT_ONLY_SKIPPED_LEFT;
720
0
}
721
722
static int is_expected_rev(const struct object_id *oid)
723
0
{
724
0
  struct object_id expected_oid;
725
0
  if (refs_read_ref(get_main_ref_store(the_repository), "BISECT_EXPECTED_REV", &expected_oid))
726
0
    return 0;
727
0
  return oideq(oid, &expected_oid);
728
0
}
729
730
enum bisect_error bisect_checkout(const struct object_id *bisect_rev,
731
          int no_checkout)
732
0
{
733
0
  struct commit *commit;
734
0
  struct pretty_print_context pp = {0};
735
0
  struct strbuf commit_msg = STRBUF_INIT;
736
737
0
  refs_update_ref(get_main_ref_store(the_repository), NULL,
738
0
      "BISECT_EXPECTED_REV", bisect_rev, NULL, 0,
739
0
      UPDATE_REFS_DIE_ON_ERR);
740
741
0
  if (no_checkout) {
742
0
    refs_update_ref(get_main_ref_store(the_repository), NULL,
743
0
        "BISECT_HEAD", bisect_rev, NULL, 0,
744
0
        UPDATE_REFS_DIE_ON_ERR);
745
0
  } else {
746
0
    struct child_process cmd = CHILD_PROCESS_INIT;
747
748
0
    cmd.git_cmd = 1;
749
0
    strvec_pushl(&cmd.args, "checkout", "-q",
750
0
           oid_to_hex(bisect_rev), "--", NULL);
751
0
    if (run_command(&cmd))
752
      /*
753
       * Errors in `run_command()` itself, signaled by res < 0,
754
       * and errors in the child process, signaled by res > 0
755
       * can both be treated as regular BISECT_FAILED (-1).
756
       */
757
0
      return BISECT_FAILED;
758
0
  }
759
760
0
  commit = lookup_commit_reference(the_repository, bisect_rev);
761
0
  repo_format_commit_message(the_repository, commit, "[%H] %s%n",
762
0
           &commit_msg, &pp);
763
0
  fputs(commit_msg.buf, stdout);
764
0
  strbuf_release(&commit_msg);
765
766
0
  return BISECT_OK;
767
0
}
768
769
static struct commit *get_commit_reference(struct repository *r,
770
             const struct object_id *oid)
771
0
{
772
0
  struct commit *c = lookup_commit_reference(r, oid);
773
0
  if (!c)
774
0
    die(_("Not a valid commit name %s"), oid_to_hex(oid));
775
0
  return c;
776
0
}
777
778
static struct commit **get_bad_and_good_commits(struct repository *r,
779
            size_t *rev_nr)
780
0
{
781
0
  struct commit **rev;
782
0
  size_t i, n = 0;
783
784
0
  ALLOC_ARRAY(rev, 1 + good_revs.nr);
785
0
  rev[n++] = get_commit_reference(r, current_bad_oid);
786
0
  for (i = 0; i < good_revs.nr; i++)
787
0
    rev[n++] = get_commit_reference(r, good_revs.oid + i);
788
0
  *rev_nr = n;
789
790
0
  return rev;
791
0
}
792
793
static enum bisect_error handle_bad_merge_base(void)
794
0
{
795
0
  if (is_expected_rev(current_bad_oid)) {
796
0
    char *bad_hex = oid_to_hex(current_bad_oid);
797
0
    char *good_hex = join_oid_array_hex(&good_revs, ' ');
798
0
    if (!strcmp(term_bad, "bad") && !strcmp(term_good, "good")) {
799
0
      fprintf(stderr, _("The merge base %s is bad.\n"
800
0
        "This means the bug has been fixed "
801
0
        "between %s and [%s].\n"),
802
0
        bad_hex, bad_hex, good_hex);
803
0
    } else if (!strcmp(term_bad, "new") && !strcmp(term_good, "old")) {
804
0
      fprintf(stderr, _("The merge base %s is new.\n"
805
0
        "The property has changed "
806
0
        "between %s and [%s].\n"),
807
0
        bad_hex, bad_hex, good_hex);
808
0
    } else {
809
0
      fprintf(stderr, _("The merge base %s is %s.\n"
810
0
        "This means the first '%s' commit is "
811
0
        "between %s and [%s].\n"),
812
0
        bad_hex, term_bad, term_good, bad_hex, good_hex);
813
0
    }
814
815
0
    free(good_hex);
816
0
    return BISECT_MERGE_BASE_CHECK;
817
0
  }
818
819
0
  fprintf(stderr, _("Some %s revs are not ancestors of the %s rev.\n"
820
0
    "git bisect cannot work properly in this case.\n"
821
0
    "Maybe you mistook %s and %s revs?\n"),
822
0
    term_good, term_bad, term_good, term_bad);
823
0
  return BISECT_FAILED;
824
0
}
825
826
static void handle_skipped_merge_base(const struct object_id *mb)
827
0
{
828
0
  char *mb_hex = oid_to_hex(mb);
829
0
  char *bad_hex = oid_to_hex(current_bad_oid);
830
0
  char *good_hex = join_oid_array_hex(&good_revs, ' ');
831
832
0
  warning(_("the merge base between %s and [%s] "
833
0
    "must be skipped.\n"
834
0
    "So we cannot be sure the first %s commit is "
835
0
    "between %s and %s.\n"
836
0
    "We continue anyway."),
837
0
    bad_hex, good_hex, term_bad, mb_hex, bad_hex);
838
0
  free(good_hex);
839
0
}
840
841
/*
842
 * "check_merge_bases" checks that merge bases are not "bad" (or "new").
843
 *
844
 * - If one is "bad" (or "new"), it means the user assumed something wrong
845
 * and we must return error with a non 0 error code.
846
 * - If one is "good" (or "old"), that's good, we have nothing to do.
847
 * - If one is "skipped", we can't know but we should warn.
848
 * - If we don't know, we should check it out and ask the user to test.
849
 * - If a merge base must be tested, on success return
850
 * BISECT_INTERNAL_SUCCESS_MERGE_BASE (-11) a special condition
851
 * for early success, this will be converted back to 0 in
852
 * check_good_are_ancestors_of_bad().
853
 */
854
static enum bisect_error check_merge_bases(size_t rev_nr, struct commit **rev, int no_checkout)
855
0
{
856
0
  enum bisect_error res = BISECT_OK;
857
0
  struct commit_list *result = NULL;
858
859
0
  if (repo_get_merge_bases_many(the_repository, rev[0], rev_nr - 1,
860
0
              rev + 1, &result) < 0)
861
0
    exit(128);
862
863
0
  for (struct commit_list *l = result; l; l = l->next) {
864
0
    const struct object_id *mb = &l->item->object.oid;
865
0
    if (oideq(mb, current_bad_oid)) {
866
0
      res = handle_bad_merge_base();
867
0
      break;
868
0
    } else if (0 <= oid_array_lookup(&good_revs, mb)) {
869
0
      continue;
870
0
    } else if (0 <= oid_array_lookup(&skipped_revs, mb)) {
871
0
      handle_skipped_merge_base(mb);
872
0
    } else {
873
0
      printf(_("Bisecting: a merge base must be tested\n"));
874
0
      res = bisect_checkout(mb, no_checkout);
875
0
      if (!res)
876
        /* indicate early success */
877
0
        res = BISECT_INTERNAL_SUCCESS_MERGE_BASE;
878
0
      break;
879
0
    }
880
0
  }
881
882
0
  free_commit_list(result);
883
0
  return res;
884
0
}
885
886
static int check_ancestors(struct repository *r, size_t rev_nr,
887
         struct commit **rev, const char *prefix)
888
0
{
889
0
  struct strvec rev_argv = STRVEC_INIT;
890
0
  struct rev_info revs;
891
0
  int res;
892
893
0
  bisect_rev_setup(r, &revs, &rev_argv, prefix, "^%s", "%s", 0);
894
895
0
  bisect_common(&revs);
896
0
  res = (revs.commits != NULL);
897
898
  /* Clean up objects used, as they will be reused. */
899
0
  clear_commit_marks_many(rev_nr, rev, ALL_REV_FLAGS);
900
901
0
  release_revisions(&revs);
902
0
  strvec_clear(&rev_argv);
903
0
  return res;
904
0
}
905
906
/*
907
 * "check_good_are_ancestors_of_bad" checks that all "good" revs are
908
 * ancestor of the "bad" rev.
909
 *
910
 * If that's not the case, we need to check the merge bases.
911
 * If a merge base must be tested by the user, its source code will be
912
 * checked out to be tested by the user and we will return.
913
 */
914
915
static enum bisect_error check_good_are_ancestors_of_bad(struct repository *r,
916
              const char *prefix,
917
              int no_checkout)
918
0
{
919
0
  char *filename;
920
0
  struct stat st;
921
0
  int fd;
922
0
  size_t rev_nr;
923
0
  enum bisect_error res = BISECT_OK;
924
0
  struct commit **rev;
925
926
0
  if (!current_bad_oid)
927
0
    return error(_("a %s revision is needed"), term_bad);
928
929
0
  filename = repo_git_path(the_repository, "BISECT_ANCESTORS_OK");
930
931
  /* Check if file BISECT_ANCESTORS_OK exists. */
932
0
  if (!stat(filename, &st) && S_ISREG(st.st_mode))
933
0
    goto done;
934
935
  /* Bisecting with no good rev is ok. */
936
0
  if (!good_revs.nr)
937
0
    goto done;
938
939
  /* Check if all good revs are ancestor of the bad rev. */
940
941
0
  rev = get_bad_and_good_commits(r, &rev_nr);
942
0
  if (check_ancestors(r, rev_nr, rev, prefix))
943
0
    res = check_merge_bases(rev_nr, rev, no_checkout);
944
0
  free(rev);
945
946
0
  if (!res) {
947
    /* Create file BISECT_ANCESTORS_OK. */
948
0
    fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
949
0
    if (fd < 0)
950
      /*
951
       * BISECT_ANCESTORS_OK file is not absolutely necessary,
952
       * the bisection process will continue at the next
953
       * bisection step.
954
       * So, just signal with a warning that something
955
       * might be wrong.
956
       */
957
0
      warning_errno(_("could not create file '%s'"),
958
0
        filename);
959
0
    else
960
0
      close(fd);
961
0
  }
962
0
 done:
963
0
  free(filename);
964
0
  return res;
965
0
}
966
967
/*
968
 * Display a commit summary to the user.
969
 */
970
static void show_commit(struct commit *commit)
971
0
{
972
0
  struct child_process show = CHILD_PROCESS_INIT;
973
974
  /*
975
   * Call git show with --no-pager, as it would otherwise
976
   * paginate the "git show" output only, not the output
977
   * from bisect_next_all(); this can be fixed by moving
978
   * it into a --format parameter, but that would override
979
   * the user's default options for "git show", which we
980
   * are trying to honour.
981
   */
982
0
  strvec_pushl(&show.args,
983
0
         "--no-pager",
984
0
         "show",
985
0
         "--stat",
986
0
         "--summary",
987
0
         "--no-abbrev-commit",
988
0
         "--diff-merges=first-parent",
989
0
         oid_to_hex(&commit->object.oid), NULL);
990
0
  show.git_cmd = 1;
991
0
  if (run_command(&show))
992
0
    die(_("unable to start 'show' for object '%s'"),
993
0
        oid_to_hex(&commit->object.oid));
994
0
}
995
996
/*
997
 * The terms used for this bisect session are stored in BISECT_TERMS.
998
 * We read them and store them to adapt the messages accordingly.
999
 * Default is bad/good.
1000
 */
1001
void read_bisect_terms(char **read_bad, char **read_good)
1002
0
{
1003
0
  struct strbuf str = STRBUF_INIT;
1004
0
  const char *filename = git_path_bisect_terms();
1005
0
  FILE *fp = fopen(filename, "r");
1006
1007
0
  if (!fp) {
1008
0
    if (errno == ENOENT) {
1009
0
      free(*read_bad);
1010
0
      *read_bad = xstrdup("bad");
1011
0
      free(*read_good);
1012
0
      *read_good = xstrdup("good");
1013
0
      return;
1014
0
    } else {
1015
0
      die_errno(_("could not read file '%s'"), filename);
1016
0
    }
1017
0
  } else {
1018
0
    strbuf_getline_lf(&str, fp);
1019
0
    free(*read_bad);
1020
0
    *read_bad = strbuf_detach(&str, NULL);
1021
0
    strbuf_getline_lf(&str, fp);
1022
0
    free(*read_good);
1023
0
    *read_good = strbuf_detach(&str, NULL);
1024
0
  }
1025
0
  strbuf_release(&str);
1026
0
  fclose(fp);
1027
0
}
1028
1029
/*
1030
 * We use the convention that return BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND (-10) means
1031
 * the bisection process finished successfully.
1032
 * In this case the calling function or command should not turn a
1033
 * BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND return code into an error or a non zero exit code.
1034
 *
1035
 * Checking BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND
1036
 * in bisect_helper::bisect_next() and only transforming it to 0 at
1037
 * the end of bisect_helper::cmd_bisect__helper() helps bypassing
1038
 * all the code related to finding a commit to test.
1039
 */
1040
enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
1041
0
{
1042
0
  struct strvec rev_argv = STRVEC_INIT;
1043
0
  struct rev_info revs = REV_INFO_INIT;
1044
0
  struct commit_list *tried = NULL;
1045
0
  int reaches = 0, all = 0, nr, steps;
1046
0
  enum bisect_error res = BISECT_OK;
1047
0
  struct object_id *bisect_rev;
1048
0
  char *steps_msg;
1049
  /*
1050
   * If no_checkout is non-zero, the bisection process does not
1051
   * checkout the trial commit but instead simply updates BISECT_HEAD.
1052
   */
1053
0
  int no_checkout = refs_ref_exists(get_main_ref_store(the_repository),
1054
0
            "BISECT_HEAD");
1055
0
  unsigned bisect_flags = 0;
1056
1057
0
  read_bisect_terms(&term_bad, &term_good);
1058
0
  if (read_bisect_refs())
1059
0
    die(_("reading bisect refs failed"));
1060
1061
0
  if (file_exists(git_path_bisect_first_parent()))
1062
0
    bisect_flags |= FIND_BISECTION_FIRST_PARENT_ONLY;
1063
1064
0
  if (skipped_revs.nr)
1065
0
    bisect_flags |= FIND_BISECTION_ALL;
1066
1067
0
  res = check_good_are_ancestors_of_bad(r, prefix, no_checkout);
1068
0
  if (res)
1069
0
    goto cleanup;
1070
1071
0
  bisect_rev_setup(r, &revs, &rev_argv, prefix, "%s", "^%s", 1);
1072
1073
0
  revs.first_parent_only = !!(bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY);
1074
0
  revs.limited = 1;
1075
1076
0
  bisect_common(&revs);
1077
1078
0
  find_bisection(&revs.commits, &reaches, &all, bisect_flags);
1079
0
  revs.commits = managed_skipped(revs.commits, &tried);
1080
1081
0
  if (!revs.commits) {
1082
    /*
1083
     * We should return error here only if the "bad"
1084
     * commit is also a "skip" commit.
1085
     */
1086
0
    res = error_if_skipped_commits(tried, NULL);
1087
0
    if (res < 0)
1088
0
      goto cleanup;
1089
0
    printf(_("%s was both %s and %s\n"),
1090
0
           oid_to_hex(current_bad_oid),
1091
0
           term_good,
1092
0
           term_bad);
1093
1094
0
    res = BISECT_FAILED;
1095
0
    goto cleanup;
1096
0
  }
1097
1098
0
  if (!all) {
1099
0
    fprintf(stderr, _("No testable commit found.\n"
1100
0
      "Maybe you started with bad path arguments?\n"));
1101
1102
0
    res = BISECT_NO_TESTABLE_COMMIT;
1103
0
    goto cleanup;
1104
0
  }
1105
1106
0
  bisect_rev = &revs.commits->item->object.oid;
1107
1108
0
  if (oideq(bisect_rev, current_bad_oid)) {
1109
0
    res = error_if_skipped_commits(tried, current_bad_oid);
1110
0
    if (res)
1111
0
      goto cleanup;
1112
0
    printf("%s is the first %s commit\n", oid_to_hex(bisect_rev),
1113
0
      term_bad);
1114
1115
0
    show_commit(revs.commits->item);
1116
    /*
1117
     * This means the bisection process succeeded.
1118
     * Using BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND (-10)
1119
     * so that the call chain can simply check
1120
     * for negative return values for early returns up
1121
     * until the cmd_bisect__helper() caller.
1122
     */
1123
0
    res = BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND;
1124
0
    goto cleanup;
1125
0
  }
1126
1127
0
  nr = all - reaches - 1;
1128
0
  steps = estimate_bisect_steps(all);
1129
1130
0
  steps_msg = xstrfmt(Q_("(roughly %d step)", "(roughly %d steps)",
1131
0
      steps), steps);
1132
  /*
1133
   * TRANSLATORS: the last %s will be replaced with "(roughly %d
1134
   * steps)" translation.
1135
   */
1136
0
  printf(Q_("Bisecting: %d revision left to test after this %s\n",
1137
0
      "Bisecting: %d revisions left to test after this %s\n",
1138
0
      nr), nr, steps_msg);
1139
0
  free(steps_msg);
1140
  /* Clean up objects used, as they will be reused. */
1141
0
  repo_clear_commit_marks(r, ALL_REV_FLAGS);
1142
1143
0
  res = bisect_checkout(bisect_rev, no_checkout);
1144
0
cleanup:
1145
0
  free_commit_list(tried);
1146
0
  release_revisions(&revs);
1147
0
  strvec_clear(&rev_argv);
1148
0
  return res;
1149
0
}
1150
1151
static inline int exp2i(int n)
1152
0
{
1153
0
  return 1 << n;
1154
0
}
1155
1156
/*
1157
 * Estimate the number of bisect steps left (after the current step)
1158
 *
1159
 * For any x between 0 included and 2^n excluded, the probability for
1160
 * n - 1 steps left looks like:
1161
 *
1162
 * P(2^n + x) == (2^n - x) / (2^n + x)
1163
 *
1164
 * and P(2^n + x) < 0.5 means 2^n < 3x
1165
 */
1166
int estimate_bisect_steps(int all)
1167
0
{
1168
0
  int n, x, e;
1169
1170
0
  if (all < 3)
1171
0
    return 0;
1172
1173
0
  n = log2u(all);
1174
0
  e = exp2i(n);
1175
0
  x = all - e;
1176
1177
0
  return (e < 3 * x) ? n : n - 1;
1178
0
}
1179
1180
static int mark_for_removal(const struct reference *ref, void *cb_data)
1181
0
{
1182
0
  struct string_list *refs = cb_data;
1183
0
  char *bisect_ref = xstrfmt("refs/bisect%s", ref->name);
1184
0
  string_list_append(refs, bisect_ref);
1185
0
  return 0;
1186
0
}
1187
1188
int bisect_clean_state(void)
1189
0
{
1190
0
  int result = 0;
1191
1192
  /* There may be some refs packed during bisection */
1193
0
  struct string_list refs_for_removal = STRING_LIST_INIT_NODUP;
1194
0
  refs_for_each_ref_in(get_main_ref_store(the_repository),
1195
0
           "refs/bisect", mark_for_removal,
1196
0
           (void *) &refs_for_removal);
1197
0
  string_list_append(&refs_for_removal, xstrdup("BISECT_HEAD"));
1198
0
  string_list_append(&refs_for_removal, xstrdup("BISECT_EXPECTED_REV"));
1199
0
  result = refs_delete_refs(get_main_ref_store(the_repository),
1200
0
          "bisect: remove", &refs_for_removal,
1201
0
          REF_NO_DEREF);
1202
0
  refs_for_removal.strdup_strings = 1;
1203
0
  string_list_clear(&refs_for_removal, 0);
1204
0
  unlink_or_warn(git_path_bisect_ancestors_ok());
1205
0
  unlink_or_warn(git_path_bisect_log());
1206
0
  unlink_or_warn(git_path_bisect_names());
1207
0
  unlink_or_warn(git_path_bisect_run());
1208
0
  unlink_or_warn(git_path_bisect_terms());
1209
0
  unlink_or_warn(git_path_bisect_first_parent());
1210
  /*
1211
   * Cleanup BISECT_START last to support the --no-checkout option
1212
   * introduced in the commit 4796e823a.
1213
   */
1214
0
  unlink_or_warn(git_path_bisect_start());
1215
1216
0
  return result;
1217
0
}