Coverage Report

Created: 2024-09-16 06:10

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