git
/
bisect.c
1212 строк · 30.8 Кб
1#define USE_THE_REPOSITORY_VARIABLE2
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
26static struct oid_array good_revs;27static struct oid_array skipped_revs;28
29static struct object_id *current_bad_oid;30
31static const char *term_bad;32static const char *term_good;33
34/* Remember to update object flag allocation in object.h */
35#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*/
44static int count_distance(struct commit_list *entry)45{
46int nr = 0;47
48while (entry) {49struct commit *commit = entry->item;50struct commit_list *p;51
52if (commit->object.flags & (UNINTERESTING | COUNTED))53break;54if (!(commit->object.flags & TREESAME))55nr++;56commit->object.flags |= COUNTED;57p = commit->parents;58entry = p;59if (p) {60p = p->next;61while (p) {62nr += count_distance(p);63p = p->next;64}65}66}67
68return nr;69}
70
71static void clear_distance(struct commit_list *list)72{
73while (list) {74struct commit *commit = list->item;75commit->object.flags &= ~COUNTED;76list = list->next;77}78}
79
80define_commit_slab(commit_weight, int *);81static struct commit_weight commit_weight;82
83#define DEBUG_BISECT 084
85static inline int weight(struct commit_list *elem)86{
87return **commit_weight_at(&commit_weight, elem->item);88}
89
90static inline void weight_set(struct commit_list *elem, int weight)91{
92**commit_weight_at(&commit_weight, elem->item) = weight;93}
94
95static int count_interesting_parents(struct commit *commit, unsigned bisect_flags)96{
97struct commit_list *p;98int count;99
100for (count = 0, p = commit->parents; p; p = p->next) {101if (!(p->item->object.flags & UNINTERESTING))102count++;103if (bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY)104break;105}106return count;107}
108
109static inline int approx_halfway(struct commit_list *p, int nr)110{
111int diff;112
113/*114* Don't short-cut something we are not going to return!
115*/
116if (p->item->object.flags & TREESAME)117return 0;118if (DEBUG_BISECT)119return 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*/
124diff = 2 * weight(p) - nr;125switch (diff) {126case -1: case 0: case 1:127return 1;128default: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*/
135if (abs(diff) < nr / 1024)136return 1;137return 0;138}139}
140
141static void show_list(const char *debug, int counted, int nr,142struct commit_list *list)143{
144struct commit_list *p;145
146if (!DEBUG_BISECT)147return;148
149fprintf(stderr, "%s (%d/%d)\n", debug, counted, nr);150
151for (p = list; p; p = p->next) {152struct commit_list *pp;153struct commit *commit = p->item;154unsigned commit_flags = commit->object.flags;155enum object_type type;156unsigned long size;157char *buf = repo_read_object_file(the_repository,158&commit->object.oid, &type,159&size);160const char *subject_start;161int subject_len;162
163if (!buf)164die(_("unable to read %s"), oid_to_hex(&commit->object.oid));165
166fprintf(stderr, "%c%c%c ",167(commit_flags & TREESAME) ? ' ' : 'T',168(commit_flags & UNINTERESTING) ? 'U' : ' ',169(commit_flags & COUNTED) ? 'C' : ' ');170if (*commit_weight_at(&commit_weight, p->item))171fprintf(stderr, "%3d", weight(p));172else173fprintf(stderr, "---");174fprintf(stderr, " %.*s", 8, oid_to_hex(&commit->object.oid));175for (pp = commit->parents; pp; pp = pp->next)176fprintf(stderr, " %.*s", 8,177oid_to_hex(&pp->item->object.oid));178
179subject_len = find_commit_subject(buf, &subject_start);180if (subject_len)181fprintf(stderr, " %.*s", subject_len, subject_start);182fprintf(stderr, "\n");183}184}
185
186static struct commit_list *best_bisection(struct commit_list *list, int nr)187{
188struct commit_list *p, *best;189int best_distance = -1;190
191best = list;192for (p = list; p; p = p->next) {193int distance;194unsigned commit_flags = p->item->object.flags;195
196if (commit_flags & TREESAME)197continue;198distance = weight(p);199if (nr - distance < distance)200distance = nr - distance;201if (distance > best_distance) {202best = p;203best_distance = distance;204}205}206
207return best;208}
209
210struct commit_dist {211struct commit *commit;212int distance;213};214
215static int compare_commit_dist(const void *a_, const void *b_)216{
217struct commit_dist *a, *b;218
219a = (struct commit_dist *)a_;220b = (struct commit_dist *)b_;221if (a->distance != b->distance)222return b->distance - a->distance; /* desc sort */223return oidcmp(&a->commit->object.oid, &b->commit->object.oid);224}
225
226static struct commit_list *best_bisection_sorted(struct commit_list *list, int nr)227{
228struct commit_list *p;229struct commit_dist *array = xcalloc(nr, sizeof(*array));230struct strbuf buf = STRBUF_INIT;231int cnt, i;232
233for (p = list, cnt = 0; p; p = p->next) {234int distance;235unsigned commit_flags = p->item->object.flags;236
237if (commit_flags & TREESAME)238continue;239distance = weight(p);240if (nr - distance < distance)241distance = nr - distance;242array[cnt].commit = p->item;243array[cnt].distance = distance;244cnt++;245}246QSORT(array, cnt, compare_commit_dist);247for (p = list, i = 0; i < cnt; i++) {248struct object *obj = &(array[i].commit->object);249
250strbuf_reset(&buf);251strbuf_addf(&buf, "dist=%d", array[i].distance);252add_name_decoration(DECORATION_NONE, buf.buf, obj);253
254p->item = array[i].commit;255if (i < cnt - 1)256p = p->next;257}258if (p) {259free_commit_list(p->next);260p->next = NULL;261}262strbuf_release(&buf);263free(array);264return list;265}
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*/
280static struct commit_list *do_find_bisection(struct commit_list *list,281int nr, int *weights,282unsigned bisect_flags)283{
284int n, counted;285struct commit_list *p;286
287counted = 0;288
289for (n = 0, p = list; p; p = p->next) {290struct commit *commit = p->item;291unsigned commit_flags = commit->object.flags;292
293*commit_weight_at(&commit_weight, p->item) = &weights[n++];294switch (count_interesting_parents(commit, bisect_flags)) {295case 0:296if (!(commit_flags & TREESAME)) {297weight_set(p, 1);298counted++;299show_list("bisection 2 count one",300counted, nr, list);301}302/*303* otherwise, it is known not to reach any
304* tree-changing commit and gets weight 0.
305*/
306break;307case 1:308weight_set(p, -1);309break;310default:311weight_set(p, -2);312break;313}314}315
316show_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*/
332for (p = list; p; p = p->next) {333if (p->item->object.flags & UNINTERESTING)334continue;335if (weight(p) != -2)336continue;337if (bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY)338BUG("shouldn't be calling count-distance in fp mode");339weight_set(p, count_distance(p));340clear_distance(list);341
342/* Does it happen to be at half-way? */343if (!(bisect_flags & FIND_BISECTION_ALL) &&344approx_halfway(p, nr))345return p;346counted++;347}348
349show_list("bisection 2 count_distance", counted, nr, list);350
351while (counted < nr) {352for (p = list; p; p = p->next) {353struct commit_list *q;354unsigned commit_flags = p->item->object.flags;355
356if (0 <= weight(p))357continue;358
359for (q = p->item->parents;360q;361q = bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY ? NULL : q->next) {362if (q->item->object.flags & UNINTERESTING)363continue;364if (0 <= weight(q))365break;366}367if (!q)368continue;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*/
375if (!(commit_flags & TREESAME)) {376weight_set(p, weight(q)+1);377counted++;378show_list("bisection 2 count one",379counted, nr, list);380}381else382weight_set(p, weight(q));383
384/* Does it happen to be at half-way? */385if (!(bisect_flags & FIND_BISECTION_ALL) &&386approx_halfway(p, nr))387return p;388}389}390
391show_list("bisection 2 counted all", counted, nr, list);392
393if (!(bisect_flags & FIND_BISECTION_ALL))394return best_bisection(list, nr);395else396return best_bisection_sorted(list, nr);397}
398
399void find_bisection(struct commit_list **commit_list, int *reaches,400int *all, unsigned bisect_flags)401{
402int nr, on_list;403struct commit_list *list, *p, *best, *next, *last;404int *weights;405
406show_list("bisection 2 entry", 0, 0, *commit_list);407init_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*/
413for (nr = on_list = 0, last = NULL, p = *commit_list;414p;415p = next) {416unsigned commit_flags = p->item->object.flags;417
418next = p->next;419if (commit_flags & UNINTERESTING) {420free(p);421continue;422}423p->next = last;424last = p;425if (!(commit_flags & TREESAME))426nr++;427on_list++;428}429list = last;430show_list("bisection 2 sorted", 0, nr, list);431
432*all = nr;433CALLOC_ARRAY(weights, on_list);434
435/* Do the real work of finding bisection commit. */436best = do_find_bisection(list, nr, weights, bisect_flags);437if (best) {438if (!(bisect_flags & FIND_BISECTION_ALL)) {439list->item = best->item;440free_commit_list(list->next);441best = list;442best->next = NULL;443}444*reaches = weight(best);445}446free(weights);447*commit_list = best;448clear_commit_weight(&commit_weight);449}
450
451static int register_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid,452int flags UNUSED, void *cb_data UNUSED)453{
454struct strbuf good_prefix = STRBUF_INIT;455strbuf_addstr(&good_prefix, term_good);456strbuf_addstr(&good_prefix, "-");457
458if (!strcmp(refname, term_bad)) {459current_bad_oid = xmalloc(sizeof(*current_bad_oid));460oidcpy(current_bad_oid, oid);461} else if (starts_with(refname, good_prefix.buf)) {462oid_array_append(&good_revs, oid);463} else if (starts_with(refname, "skip-")) {464oid_array_append(&skipped_revs, oid);465}466
467strbuf_release(&good_prefix);468
469return 0;470}
471
472static int read_bisect_refs(void)473{
474return refs_for_each_ref_in(get_main_ref_store(the_repository),475"refs/bisect/", register_ref, NULL);476}
477
478static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES")479static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK")480static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN")481static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START")482static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG")483static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS")484static GIT_PATH_FUNC(git_path_bisect_first_parent, "BISECT_FIRST_PARENT")485
486static void read_bisect_paths(struct strvec *array)487{
488struct strbuf str = STRBUF_INIT;489const char *filename = git_path_bisect_names();490FILE *fp = xfopen(filename, "r");491
492while (strbuf_getline_lf(&str, fp) != EOF) {493strbuf_trim(&str);494if (sq_dequote_to_strvec(str.buf, array))495die(_("Badly quoted content in file '%s': %s"),496filename, str.buf);497}498
499strbuf_release(&str);500fclose(fp);501}
502
503static char *join_oid_array_hex(struct oid_array *array, char delim)504{
505struct strbuf joined_hexs = STRBUF_INIT;506int i;507
508for (i = 0; i < array->nr; i++) {509strbuf_addstr(&joined_hexs, oid_to_hex(array->oid + i));510if (i + 1 < array->nr)511strbuf_addch(&joined_hexs, delim);512}513
514return strbuf_detach(&joined_hexs, NULL);515}
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*/
530struct commit_list *filter_skipped(struct commit_list *list,531struct commit_list **tried,532int show_all,533int *count,534int *skipped_first)535{
536struct commit_list *filtered = NULL, **f = &filtered;537
538*tried = NULL;539
540if (skipped_first)541*skipped_first = 0;542if (count)543*count = 0;544
545if (!skipped_revs.nr)546return list;547
548while (list) {549struct commit_list *next = list->next;550list->next = NULL;551if (0 <= oid_array_lookup(&skipped_revs, &list->item->object.oid)) {552if (skipped_first && !*skipped_first)553*skipped_first = 1;554/* Move current to tried list */555*tried = list;556tried = &list->next;557} else {558if (!show_all) {559if (!skipped_first || !*skipped_first)560return list;561} else if (skipped_first && !*skipped_first) {562/* This means we know it's not skipped */563*skipped_first = -1;564}565/* Move current to filtered list */566*f = list;567f = &list->next;568if (count)569(*count)++;570}571list = next;572}573
574if (skipped_first && *skipped_first == -1)575*skipped_first = 0;576
577return filtered;578}
579
580#define PRN_MODULO 32768581
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*/
588static unsigned get_prn(unsigned count)589{
590count = count * 1103515245 + 12345;591return (count/65536) % PRN_MODULO;592}
593
594/*
595* Custom integer square root from
596* https://en.wikipedia.org/wiki/Integer_square_root
597*/
598static int sqrti(int val)599{
600float d, x = val;601
602if (!val)603return 0;604
605do {606float y = (x + (float)val / x) / 2;607d = (y > x) ? y - x : x - y;608x = y;609} while (d >= 0.5);610
611return (int)x;612}
613
614static struct commit_list *skip_away(struct commit_list *list, int count)615{
616struct commit_list *cur, *previous;617int prn, index, i;618
619prn = get_prn(count);620index = (count * prn / PRN_MODULO) * sqrti(prn) / sqrti(PRN_MODULO);621
622cur = list;623previous = NULL;624
625for (i = 0; cur; cur = cur->next, i++) {626if (i == index) {627if (!oideq(&cur->item->object.oid, current_bad_oid))628return cur;629if (previous)630return previous;631return list;632}633previous = cur;634}635
636return list;637}
638
639static struct commit_list *managed_skipped(struct commit_list *list,640struct commit_list **tried)641{
642int count, skipped_first;643
644*tried = NULL;645
646if (!skipped_revs.nr)647return list;648
649list = filter_skipped(list, tried, 0, &count, &skipped_first);650
651if (!skipped_first)652return list;653
654return skip_away(list, count);655}
656
657static void bisect_rev_setup(struct repository *r, struct rev_info *revs,658struct strvec *rev_argv,659const char *prefix,660const char *bad_format, const char *good_format,661int read_paths)662{
663struct setup_revision_opt opt = {664.free_removed_argv_elements = 1,665};666int i;667
668repo_init_revisions(r, revs, prefix);669revs->abbrev = 0;670revs->commit_format = CMIT_FMT_UNSPECIFIED;671
672/* rev_argv.argv[0] will be ignored by setup_revisions */673strvec_push(rev_argv, "bisect_rev_setup");674strvec_pushf(rev_argv, bad_format, oid_to_hex(current_bad_oid));675for (i = 0; i < good_revs.nr; i++)676strvec_pushf(rev_argv, good_format,677oid_to_hex(good_revs.oid + i));678strvec_push(rev_argv, "--");679if (read_paths)680read_bisect_paths(rev_argv);681
682setup_revisions(rev_argv->nr, rev_argv->v, revs, &opt);683}
684
685static void bisect_common(struct rev_info *revs)686{
687if (prepare_revision_walk(revs))688die("revision walk setup failed");689if (revs->tree_objects)690mark_edges_uninteresting(revs, NULL, 0);691}
692
693static enum bisect_error error_if_skipped_commits(struct commit_list *tried,694const struct object_id *bad)695{
696if (!tried)697return BISECT_OK;698
699printf("There are only 'skip'ped commits left to test.\n"700"The first %s commit could be any of:\n", term_bad);701
702for ( ; tried; tried = tried->next)703printf("%s\n", oid_to_hex(&tried->item->object.oid));704
705if (bad)706printf("%s\n", oid_to_hex(bad));707printf(_("We cannot bisect more!\n"));708
709return BISECT_ONLY_SKIPPED_LEFT;710}
711
712static int is_expected_rev(const struct object_id *oid)713{
714struct object_id expected_oid;715if (refs_read_ref(get_main_ref_store(the_repository), "BISECT_EXPECTED_REV", &expected_oid))716return 0;717return oideq(oid, &expected_oid);718}
719
720enum bisect_error bisect_checkout(const struct object_id *bisect_rev,721int no_checkout)722{
723struct commit *commit;724struct pretty_print_context pp = {0};725struct strbuf commit_msg = STRBUF_INIT;726
727refs_update_ref(get_main_ref_store(the_repository), NULL,728"BISECT_EXPECTED_REV", bisect_rev, NULL, 0,729UPDATE_REFS_DIE_ON_ERR);730
731if (no_checkout) {732refs_update_ref(get_main_ref_store(the_repository), NULL,733"BISECT_HEAD", bisect_rev, NULL, 0,734UPDATE_REFS_DIE_ON_ERR);735} else {736struct child_process cmd = CHILD_PROCESS_INIT;737
738cmd.git_cmd = 1;739strvec_pushl(&cmd.args, "checkout", "-q",740oid_to_hex(bisect_rev), "--", NULL);741if (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*/
747return BISECT_FAILED;748}749
750commit = lookup_commit_reference(the_repository, bisect_rev);751repo_format_commit_message(the_repository, commit, "[%H] %s%n",752&commit_msg, &pp);753fputs(commit_msg.buf, stdout);754strbuf_release(&commit_msg);755
756return BISECT_OK;757}
758
759static struct commit *get_commit_reference(struct repository *r,760const struct object_id *oid)761{
762struct commit *c = lookup_commit_reference(r, oid);763if (!c)764die(_("Not a valid commit name %s"), oid_to_hex(oid));765return c;766}
767
768static struct commit **get_bad_and_good_commits(struct repository *r,769int *rev_nr)770{
771struct commit **rev;772int i, n = 0;773
774ALLOC_ARRAY(rev, 1 + good_revs.nr);775rev[n++] = get_commit_reference(r, current_bad_oid);776for (i = 0; i < good_revs.nr; i++)777rev[n++] = get_commit_reference(r, good_revs.oid + i);778*rev_nr = n;779
780return rev;781}
782
783static enum bisect_error handle_bad_merge_base(void)784{
785if (is_expected_rev(current_bad_oid)) {786char *bad_hex = oid_to_hex(current_bad_oid);787char *good_hex = join_oid_array_hex(&good_revs, ' ');788if (!strcmp(term_bad, "bad") && !strcmp(term_good, "good")) {789fprintf(stderr, _("The merge base %s is bad.\n"790"This means the bug has been fixed "791"between %s and [%s].\n"),792bad_hex, bad_hex, good_hex);793} else if (!strcmp(term_bad, "new") && !strcmp(term_good, "old")) {794fprintf(stderr, _("The merge base %s is new.\n"795"The property has changed "796"between %s and [%s].\n"),797bad_hex, bad_hex, good_hex);798} else {799fprintf(stderr, _("The merge base %s is %s.\n"800"This means the first '%s' commit is "801"between %s and [%s].\n"),802bad_hex, term_bad, term_good, bad_hex, good_hex);803}804return BISECT_MERGE_BASE_CHECK;805}806
807fprintf(stderr, _("Some %s revs are not ancestors of the %s rev.\n"808"git bisect cannot work properly in this case.\n"809"Maybe you mistook %s and %s revs?\n"),810term_good, term_bad, term_good, term_bad);811return BISECT_FAILED;812}
813
814static void handle_skipped_merge_base(const struct object_id *mb)815{
816char *mb_hex = oid_to_hex(mb);817char *bad_hex = oid_to_hex(current_bad_oid);818char *good_hex = join_oid_array_hex(&good_revs, ' ');819
820warning(_("the merge base between %s and [%s] "821"must be skipped.\n"822"So we cannot be sure the first %s commit is "823"between %s and %s.\n"824"We continue anyway."),825bad_hex, good_hex, term_bad, mb_hex, bad_hex);826free(good_hex);827}
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*/
842static enum bisect_error check_merge_bases(int rev_nr, struct commit **rev, int no_checkout)843{
844enum bisect_error res = BISECT_OK;845struct commit_list *result = NULL;846
847if (repo_get_merge_bases_many(the_repository, rev[0], rev_nr - 1,848rev + 1, &result) < 0)849exit(128);850
851for (; result; result = result->next) {852const struct object_id *mb = &result->item->object.oid;853if (oideq(mb, current_bad_oid)) {854res = handle_bad_merge_base();855break;856} else if (0 <= oid_array_lookup(&good_revs, mb)) {857continue;858} else if (0 <= oid_array_lookup(&skipped_revs, mb)) {859handle_skipped_merge_base(mb);860} else {861printf(_("Bisecting: a merge base must be tested\n"));862res = bisect_checkout(mb, no_checkout);863if (!res)864/* indicate early success */865res = BISECT_INTERNAL_SUCCESS_MERGE_BASE;866break;867}868}869
870free_commit_list(result);871return res;872}
873
874static int check_ancestors(struct repository *r, int rev_nr,875struct commit **rev, const char *prefix)876{
877struct strvec rev_argv = STRVEC_INIT;878struct rev_info revs;879int res;880
881bisect_rev_setup(r, &revs, &rev_argv, prefix, "^%s", "%s", 0);882
883bisect_common(&revs);884res = (revs.commits != NULL);885
886/* Clean up objects used, as they will be reused. */887clear_commit_marks_many(rev_nr, rev, ALL_REV_FLAGS);888
889release_revisions(&revs);890strvec_clear(&rev_argv);891return res;892}
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
903static enum bisect_error check_good_are_ancestors_of_bad(struct repository *r,904const char *prefix,905int no_checkout)906{
907char *filename;908struct stat st;909int fd, rev_nr;910enum bisect_error res = BISECT_OK;911struct commit **rev;912
913if (!current_bad_oid)914return error(_("a %s revision is needed"), term_bad);915
916filename = git_pathdup("BISECT_ANCESTORS_OK");917
918/* Check if file BISECT_ANCESTORS_OK exists. */919if (!stat(filename, &st) && S_ISREG(st.st_mode))920goto done;921
922/* Bisecting with no good rev is ok. */923if (!good_revs.nr)924goto done;925
926/* Check if all good revs are ancestor of the bad rev. */927
928rev = get_bad_and_good_commits(r, &rev_nr);929if (check_ancestors(r, rev_nr, rev, prefix))930res = check_merge_bases(rev_nr, rev, no_checkout);931free(rev);932
933if (!res) {934/* Create file BISECT_ANCESTORS_OK. */935fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);936if (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*/
944warning_errno(_("could not create file '%s'"),945filename);946else947close(fd);948}949done:950free(filename);951return res;952}
953
954/*
955* Display a commit summary to the user.
956*/
957static void show_commit(struct commit *commit)958{
959struct 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*/
969strvec_pushl(&show.args,970"--no-pager",971"show",972"--stat",973"--summary",974"--no-abbrev-commit",975"--diff-merges=first-parent",976oid_to_hex(&commit->object.oid), NULL);977show.git_cmd = 1;978if (run_command(&show))979die(_("unable to start 'show' for object '%s'"),980oid_to_hex(&commit->object.oid));981}
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*/
988void read_bisect_terms(const char **read_bad, const char **read_good)989{
990struct strbuf str = STRBUF_INIT;991const char *filename = git_path_bisect_terms();992FILE *fp = fopen(filename, "r");993
994if (!fp) {995if (errno == ENOENT) {996*read_bad = "bad";997*read_good = "good";998return;999} else {1000die_errno(_("could not read file '%s'"), filename);1001}1002} else {1003strbuf_getline_lf(&str, fp);1004*read_bad = strbuf_detach(&str, NULL);1005strbuf_getline_lf(&str, fp);1006*read_good = strbuf_detach(&str, NULL);1007}1008strbuf_release(&str);1009fclose(fp);1010}
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*/
1023enum bisect_error bisect_next_all(struct repository *r, const char *prefix)1024{
1025struct strvec rev_argv = STRVEC_INIT;1026struct rev_info revs = REV_INFO_INIT;1027struct commit_list *tried;1028int reaches = 0, all = 0, nr, steps;1029enum bisect_error res = BISECT_OK;1030struct object_id *bisect_rev;1031char *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*/
1036int no_checkout = refs_ref_exists(get_main_ref_store(the_repository),1037"BISECT_HEAD");1038unsigned bisect_flags = 0;1039
1040read_bisect_terms(&term_bad, &term_good);1041if (read_bisect_refs())1042die(_("reading bisect refs failed"));1043
1044if (file_exists(git_path_bisect_first_parent()))1045bisect_flags |= FIND_BISECTION_FIRST_PARENT_ONLY;1046
1047if (skipped_revs.nr)1048bisect_flags |= FIND_BISECTION_ALL;1049
1050res = check_good_are_ancestors_of_bad(r, prefix, no_checkout);1051if (res)1052goto cleanup;1053
1054bisect_rev_setup(r, &revs, &rev_argv, prefix, "%s", "^%s", 1);1055
1056revs.first_parent_only = !!(bisect_flags & FIND_BISECTION_FIRST_PARENT_ONLY);1057revs.limited = 1;1058
1059bisect_common(&revs);1060
1061find_bisection(&revs.commits, &reaches, &all, bisect_flags);1062revs.commits = managed_skipped(revs.commits, &tried);1063
1064if (!revs.commits) {1065/*1066* We should return error here only if the "bad"
1067* commit is also a "skip" commit.
1068*/
1069res = error_if_skipped_commits(tried, NULL);1070if (res < 0)1071goto cleanup;1072printf(_("%s was both %s and %s\n"),1073oid_to_hex(current_bad_oid),1074term_good,1075term_bad);1076
1077res = BISECT_FAILED;1078goto cleanup;1079}1080
1081if (!all) {1082fprintf(stderr, _("No testable commit found.\n"1083"Maybe you started with bad path arguments?\n"));1084
1085res = BISECT_NO_TESTABLE_COMMIT;1086goto cleanup;1087}1088
1089bisect_rev = &revs.commits->item->object.oid;1090
1091if (oideq(bisect_rev, current_bad_oid)) {1092res = error_if_skipped_commits(tried, current_bad_oid);1093if (res)1094return res;1095printf("%s is the first %s commit\n", oid_to_hex(bisect_rev),1096term_bad);1097
1098show_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*/
1106res = BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND;1107goto cleanup;1108}1109
1110nr = all - reaches - 1;1111steps = estimate_bisect_steps(all);1112
1113steps_msg = xstrfmt(Q_("(roughly %d step)", "(roughly %d steps)",1114steps), steps);1115/*1116* TRANSLATORS: the last %s will be replaced with "(roughly %d
1117* steps)" translation.
1118*/
1119printf(Q_("Bisecting: %d revision left to test after this %s\n",1120"Bisecting: %d revisions left to test after this %s\n",1121nr), nr, steps_msg);1122free(steps_msg);1123/* Clean up objects used, as they will be reused. */1124repo_clear_commit_marks(r, ALL_REV_FLAGS);1125
1126res = bisect_checkout(bisect_rev, no_checkout);1127cleanup:1128release_revisions(&revs);1129strvec_clear(&rev_argv);1130return res;1131}
1132
1133static inline int log2i(int n)1134{
1135int log2 = 0;1136
1137for (; n > 1; n >>= 1)1138log2++;1139
1140return log2;1141}
1142
1143static inline int exp2i(int n)1144{
1145return 1 << n;1146}
1147
1148/*
1149* Estimate the number of bisect steps left (after the current step)
1150*
1151* For any x between 0 included and 2^n excluded, the probability for
1152* n - 1 steps left looks like:
1153*
1154* P(2^n + x) == (2^n - x) / (2^n + x)
1155*
1156* and P(2^n + x) < 0.5 means 2^n < 3x
1157*/
1158int estimate_bisect_steps(int all)1159{
1160int n, x, e;1161
1162if (all < 3)1163return 0;1164
1165n = log2i(all);1166e = exp2i(n);1167x = all - e;1168
1169return (e < 3 * x) ? n : n - 1;1170}
1171
1172static int mark_for_removal(const char *refname,1173const char *referent UNUSED,1174const struct object_id *oid UNUSED,1175int flag UNUSED, void *cb_data)1176{
1177struct string_list *refs = cb_data;1178char *ref = xstrfmt("refs/bisect%s", refname);1179string_list_append(refs, ref);1180return 0;1181}
1182
1183int bisect_clean_state(void)1184{
1185int result = 0;1186
1187/* There may be some refs packed during bisection */1188struct string_list refs_for_removal = STRING_LIST_INIT_NODUP;1189refs_for_each_ref_in(get_main_ref_store(the_repository),1190"refs/bisect", mark_for_removal,1191(void *) &refs_for_removal);1192string_list_append(&refs_for_removal, xstrdup("BISECT_HEAD"));1193string_list_append(&refs_for_removal, xstrdup("BISECT_EXPECTED_REV"));1194result = refs_delete_refs(get_main_ref_store(the_repository),1195"bisect: remove", &refs_for_removal,1196REF_NO_DEREF);1197refs_for_removal.strdup_strings = 1;1198string_list_clear(&refs_for_removal, 0);1199unlink_or_warn(git_path_bisect_ancestors_ok());1200unlink_or_warn(git_path_bisect_log());1201unlink_or_warn(git_path_bisect_names());1202unlink_or_warn(git_path_bisect_run());1203unlink_or_warn(git_path_bisect_terms());1204unlink_or_warn(git_path_bisect_first_parent());1205/*1206* Cleanup BISECT_START last to support the --no-checkout option
1207* introduced in the commit 4796e823a.
1208*/
1209unlink_or_warn(git_path_bisect_start());1210
1211return result;1212}
1213