Merge branch 'ys/bisect-object-id-missing-conversion-fix' into maint
authorJunio C Hamano <gitster@pobox.com>
Tue, 27 Feb 2018 18:43:55 +0000 (10:43 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 27 Feb 2018 18:43:55 +0000 (10:43 -0800)
Fix for a commented-out code to adjust it to a rather old API change.

* ys/bisect-object-id-missing-conversion-fix:
bisect: debug: convert struct object to object_id

1  2 
bisect.c
diff --combined bisect.c
index 0d9e731b72692103aa17ee2e28e0126fcdf32228,6feed853374c0a92db9b4d21722facb38b20284b..f6d05bd66f42bd9874a08f5585ae99337d22dad5
+++ b/bisect.c
@@@ -1,5 -1,4 +1,5 @@@
  #include "cache.h"
 +#include "config.h"
  #include "commit.h"
  #include "diff.h"
  #include "revision.h"
@@@ -13,8 -12,8 +13,8 @@@
  #include "sha1-array.h"
  #include "argv-array.h"
  
 -static struct sha1_array good_revs;
 -static struct sha1_array skipped_revs;
 +static struct oid_array good_revs;
 +static struct oid_array skipped_revs;
  
  static struct object_id *current_bad_oid;
  
@@@ -132,7 -131,7 +132,7 @@@ static void show_list(const char *debug
                unsigned flags = commit->object.flags;
                enum object_type type;
                unsigned long size;
-               char *buf = read_sha1_file(commit->object.sha1, &type, &size);
+               char *buf = read_sha1_file(commit->object.oid.hash, &type, &size);
                const char *subject_start;
                int subject_len;
  
                        fprintf(stderr, "%3d", weight(p));
                else
                        fprintf(stderr, "---");
-               fprintf(stderr, " %.*s", 8, sha1_to_hex(commit->object.sha1));
+               fprintf(stderr, " %.*s", 8, sha1_to_hex(commit->object.oid.hash));
                for (pp = commit->parents; pp; pp = pp->next)
                        fprintf(stderr, " %.*s", 8,
-                               sha1_to_hex(pp->item->object.sha1));
+                               sha1_to_hex(pp->item->object.oid.hash));
  
                subject_len = find_commit_subject(buf, &subject_start);
                if (subject_len)
@@@ -201,7 -200,6 +201,7 @@@ static struct commit_list *best_bisecti
  {
        struct commit_list *p;
        struct commit_dist *array = xcalloc(nr, sizeof(*array));
 +      struct strbuf buf = STRBUF_INIT;
        int cnt, i;
  
        for (p = list, cnt = 0; p; p = p->next) {
        }
        QSORT(array, cnt, compare_commit_dist);
        for (p = list, i = 0; i < cnt; i++) {
 -              char buf[100]; /* enough for dist=%d */
                struct object *obj = &(array[i].commit->object);
  
 -              snprintf(buf, sizeof(buf), "dist=%d", array[i].distance);
 -              add_name_decoration(DECORATION_NONE, buf, obj);
 +              strbuf_reset(&buf);
 +              strbuf_addf(&buf, "dist=%d", array[i].distance);
 +              add_name_decoration(DECORATION_NONE, buf.buf, obj);
  
                p->item = array[i].commit;
 -              p = p->next;
 +              if (i < cnt - 1)
 +                      p = p->next;
        }
 -      if (p)
 +      if (p) {
 +              free_commit_list(p->next);
                p->next = NULL;
 +      }
 +      strbuf_release(&buf);
        free(array);
        return list;
  }
@@@ -363,29 -357,28 +363,29 @@@ static struct commit_list *do_find_bise
                return best_bisection_sorted(list, nr);
  }
  
 -struct commit_list *find_bisection(struct commit_list *list,
 -                                        int *reaches, int *all,
 -                                        int find_all)
 +void find_bisection(struct commit_list **commit_list, int *reaches,
 +                  int *all, int find_all)
  {
        int nr, on_list;
 -      struct commit_list *p, *best, *next, *last;
 +      struct commit_list *list, *p, *best, *next, *last;
        int *weights;
  
 -      show_list("bisection 2 entry", 0, 0, list);
 +      show_list("bisection 2 entry", 0, 0, *commit_list);
  
        /*
         * Count the number of total and tree-changing items on the
         * list, while reversing the list.
         */
 -      for (nr = on_list = 0, last = NULL, p = list;
 +      for (nr = on_list = 0, last = NULL, p = *commit_list;
             p;
             p = next) {
                unsigned flags = p->item->object.flags;
  
                next = p->next;
 -              if (flags & UNINTERESTING)
 +              if (flags & UNINTERESTING) {
 +                      free(p);
                        continue;
 +              }
                p->next = last;
                last = p;
                if (!(flags & TREESAME))
        /* Do the real work of finding bisection commit. */
        best = do_find_bisection(list, nr, weights, find_all);
        if (best) {
 -              if (!find_all)
 +              if (!find_all) {
 +                      list->item = best->item;
 +                      free_commit_list(list->next);
 +                      best = list;
                        best->next = NULL;
 +              }
                *reaches = weight(best);
        }
        free(weights);
 -      return best;
 +      *commit_list = best;
  }
  
  static int register_ref(const char *refname, const struct object_id *oid,
                current_bad_oid = xmalloc(sizeof(*current_bad_oid));
                oidcpy(current_bad_oid, oid);
        } else if (starts_with(refname, good_prefix.buf)) {
 -              sha1_array_append(&good_revs, oid->hash);
 +              oid_array_append(&good_revs, oid);
        } else if (starts_with(refname, "skip-")) {
 -              sha1_array_append(&skipped_revs, oid->hash);
 +              oid_array_append(&skipped_revs, oid);
        }
  
        strbuf_release(&good_prefix);
@@@ -441,18 -430,15 +441,18 @@@ static int read_bisect_refs(void
  
  static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES")
  static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV")
 +static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK")
 +static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN")
 +static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START")
 +static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG")
 +static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS")
 +static GIT_PATH_FUNC(git_path_head_name, "head-name")
  
  static void read_bisect_paths(struct argv_array *array)
  {
        struct strbuf str = STRBUF_INIT;
        const char *filename = git_path_bisect_names();
 -      FILE *fp = fopen(filename, "r");
 -
 -      if (!fp)
 -              die_errno(_("Could not open file '%s'"), filename);
 +      FILE *fp = xfopen(filename, "r");
  
        while (strbuf_getline_lf(&str, fp) != EOF) {
                strbuf_trim(&str);
        fclose(fp);
  }
  
 -static char *join_sha1_array_hex(struct sha1_array *array, char delim)
 +static char *join_sha1_array_hex(struct oid_array *array, char delim)
  {
        struct strbuf joined_hexs = STRBUF_INIT;
        int i;
  
        for (i = 0; i < array->nr; i++) {
 -              strbuf_addstr(&joined_hexs, sha1_to_hex(array->sha1[i]));
 +              strbuf_addstr(&joined_hexs, oid_to_hex(array->oid + i));
                if (i + 1 < array->nr)
                        strbuf_addch(&joined_hexs, delim);
        }
@@@ -513,7 -499,8 +513,7 @@@ struct commit_list *filter_skipped(stru
        while (list) {
                struct commit_list *next = list->next;
                list->next = NULL;
 -              if (0 <= sha1_array_lookup(&skipped_revs,
 -                                         list->item->object.oid.hash)) {
 +              if (0 <= oid_array_lookup(&skipped_revs, &list->item->object.oid)) {
                        if (skipped_first && !*skipped_first)
                                *skipped_first = 1;
                        /* Move current to tried list */
@@@ -557,7 -544,7 +557,7 @@@ static unsigned get_prn(unsigned count
  
  /*
   * Custom integer square root from
 - * http://en.wikipedia.org/wiki/Integer_square_root
 + * https://en.wikipedia.org/wiki/Integer_square_root
   */
  static int sqrti(int val)
  {
@@@ -634,7 -621,7 +634,7 @@@ static void bisect_rev_setup(struct rev
        argv_array_pushf(&rev_argv, bad_format, oid_to_hex(current_bad_oid));
        for (i = 0; i < good_revs.nr; i++)
                argv_array_pushf(&rev_argv, good_format,
 -                               sha1_to_hex(good_revs.sha1[i]));
 +                               oid_to_hex(good_revs.oid + i));
        argv_array_push(&rev_argv, "--");
        if (read_paths)
                read_bisect_paths(&rev_argv);
@@@ -680,7 -667,7 +680,7 @@@ static int is_expected_rev(const struc
        if (stat(filename, &st) || !S_ISREG(st.st_mode))
                return 0;
  
 -      fp = fopen(filename, "r");
 +      fp = fopen_or_warn(filename, "r");
        if (!fp)
                return 0;
  
        return res;
  }
  
 -static int bisect_checkout(const unsigned char *bisect_rev, int no_checkout)
 +static int bisect_checkout(const struct object_id *bisect_rev, int no_checkout)
  {
 -      char bisect_rev_hex[GIT_SHA1_HEXSZ + 1];
 +      char bisect_rev_hex[GIT_MAX_HEXSZ + 1];
  
 -      memcpy(bisect_rev_hex, sha1_to_hex(bisect_rev), GIT_SHA1_HEXSZ + 1);
 +      memcpy(bisect_rev_hex, oid_to_hex(bisect_rev), GIT_SHA1_HEXSZ + 1);
        update_ref(NULL, "BISECT_EXPECTED_REV", bisect_rev, NULL, 0, UPDATE_REFS_DIE_ON_ERR);
  
        argv_checkout[2] = bisect_rev_hex;
        if (no_checkout) {
 -              update_ref(NULL, "BISECT_HEAD", bisect_rev, NULL, 0, UPDATE_REFS_DIE_ON_ERR);
 +              update_ref(NULL, "BISECT_HEAD", bisect_rev, NULL, 0,
 +                         UPDATE_REFS_DIE_ON_ERR);
        } else {
                int res;
                res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
        return run_command_v_opt(argv_show_branch, RUN_GIT_CMD);
  }
  
 -static struct commit *get_commit_reference(const unsigned char *sha1)
 +static struct commit *get_commit_reference(const struct object_id *oid)
  {
 -      struct commit *r = lookup_commit_reference(sha1);
 +      struct commit *r = lookup_commit_reference(oid);
        if (!r)
 -              die(_("Not a valid commit name %s"), sha1_to_hex(sha1));
 +              die(_("Not a valid commit name %s"), oid_to_hex(oid));
        return r;
  }
  
@@@ -729,9 -715,9 +729,9 @@@ static struct commit **get_bad_and_good
        int i, n = 0;
  
        ALLOC_ARRAY(rev, 1 + good_revs.nr);
 -      rev[n++] = get_commit_reference(current_bad_oid->hash);
 +      rev[n++] = get_commit_reference(current_bad_oid);
        for (i = 0; i < good_revs.nr; i++)
 -              rev[n++] = get_commit_reference(good_revs.sha1[i]);
 +              rev[n++] = get_commit_reference(good_revs.oid + i);
        *rev_nr = n;
  
        return rev;
@@@ -768,9 -754,9 +768,9 @@@ static void handle_bad_merge_base(void
        exit(1);
  }
  
 -static void handle_skipped_merge_base(const unsigned char *mb)
 +static void handle_skipped_merge_base(const struct object_id *mb)
  {
 -      char *mb_hex = sha1_to_hex(mb);
 +      char *mb_hex = oid_to_hex(mb);
        char *bad_hex = oid_to_hex(current_bad_oid);
        char *good_hex = join_sha1_array_hex(&good_revs, ' ');
  
   * - If one is "skipped", we can't know but we should warn.
   * - If we don't know, we should check it out and ask the user to test.
   */
 -static void check_merge_bases(int no_checkout)
 +static void check_merge_bases(int rev_nr, struct commit **rev, int no_checkout)
  {
        struct commit_list *result;
 -      int rev_nr;
 -      struct commit **rev = get_bad_and_good_commits(&rev_nr);
  
        result = get_merge_bases_many(rev[0], rev_nr - 1, rev + 1);
  
        for (; result; result = result->next) {
 -              const unsigned char *mb = result->item->object.oid.hash;
 -              if (!hashcmp(mb, current_bad_oid->hash)) {
 +              const struct object_id *mb = &result->item->object.oid;
 +              if (!oidcmp(mb, current_bad_oid)) {
                        handle_bad_merge_base();
 -              } else if (0 <= sha1_array_lookup(&good_revs, mb)) {
 +              } else if (0 <= oid_array_lookup(&good_revs, mb)) {
                        continue;
 -              } else if (0 <= sha1_array_lookup(&skipped_revs, mb)) {
 +              } else if (0 <= oid_array_lookup(&skipped_revs, mb)) {
                        handle_skipped_merge_base(mb);
                } else {
                        printf(_("Bisecting: a merge base must be tested\n"));
                }
        }
  
 -      free(rev);
        free_commit_list(result);
  }
  
 -static int check_ancestors(const char *prefix)
 +static int check_ancestors(int rev_nr, struct commit **rev, const char *prefix)
  {
        struct rev_info revs;
 -      struct object_array pending_copy;
        int res;
  
        bisect_rev_setup(&revs, prefix, "^%s", "%s", 0);
  
 -      /* Save pending objects, so they can be cleaned up later. */
 -      pending_copy = revs.pending;
 -      revs.leak_pending = 1;
 -
 -      /*
 -       * bisect_common calls prepare_revision_walk right away, which
 -       * (together with .leak_pending = 1) makes us the sole owner of
 -       * the list of pending objects.
 -       */
        bisect_common(&revs);
        res = (revs.commits != NULL);
  
        /* Clean up objects used, as they will be reused. */
 -      clear_commit_marks_for_object_array(&pending_copy, ALL_REV_FLAGS);
 -      free(pending_copy.objects);
 +      clear_commit_marks_many(rev_nr, rev, ALL_REV_FLAGS);
  
        return res;
  }
@@@ -843,8 -843,7 +843,8 @@@ static void check_good_are_ancestors_of
  {
        char *filename = git_pathdup("BISECT_ANCESTORS_OK");
        struct stat st;
 -      int fd;
 +      int fd, rev_nr;
 +      struct commit **rev;
  
        if (!current_bad_oid)
                die(_("a %s revision is needed"), term_bad);
                goto done;
  
        /* Check if all good revs are ancestor of the bad rev. */
 -      if (check_ancestors(prefix))
 -              check_merge_bases(no_checkout);
 +      rev = get_bad_and_good_commits(&rev_nr);
 +      if (check_ancestors(rev_nr, rev, prefix))
 +              check_merge_bases(rev_nr, rev, no_checkout);
 +      free(rev);
  
        /* Create file BISECT_ANCESTORS_OK. */
        fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
@@@ -908,7 -905,7 +908,7 @@@ static void show_diff_tree(const char *
  void read_bisect_terms(const char **read_bad, const char **read_good)
  {
        struct strbuf str = STRBUF_INIT;
 -      const char *filename = git_path("BISECT_TERMS");
 +      const char *filename = git_path_bisect_terms();
        FILE *fp = fopen(filename, "r");
  
        if (!fp) {
@@@ -942,7 -939,7 +942,7 @@@ int bisect_next_all(const char *prefix
        struct rev_info revs;
        struct commit_list *tried;
        int reaches = 0, all = 0, nr, steps;
 -      const unsigned char *bisect_rev;
 +      struct object_id *bisect_rev;
        char *steps_msg;
  
        read_bisect_terms(&term_bad, &term_good);
  
        bisect_common(&revs);
  
 -      revs.commits = find_bisection(revs.commits, &reaches, &all,
 -                                     !!skipped_revs.nr);
 +      find_bisection(&revs.commits, &reaches, &all, !!skipped_revs.nr);
        revs.commits = managed_skipped(revs.commits, &tried);
  
        if (!revs.commits) {
                exit(4);
        }
  
 -      bisect_rev = revs.commits->item->object.oid.hash;
 +      bisect_rev = &revs.commits->item->object.oid;
  
 -      if (!hashcmp(bisect_rev, current_bad_oid->hash)) {
 +      if (!oidcmp(bisect_rev, current_bad_oid)) {
                exit_if_skipped_commits(tried, current_bad_oid);
 -              printf("%s is the first %s commit\n", sha1_to_hex(bisect_rev),
 +              printf("%s is the first %s commit\n", oid_to_hex(bisect_rev),
                        term_bad);
                show_diff_tree(prefix, revs.commits->item);
                /* This means the bisection process succeeded. */
  
        steps_msg = xstrfmt(Q_("(roughly %d step)", "(roughly %d steps)",
                  steps), steps);
 -      /* TRANSLATORS: the last %s will be replaced with
 -         "(roughly %d steps)" translation */
 +      /*
 +       * TRANSLATORS: the last %s will be replaced with "(roughly %d
 +       * steps)" translation.
 +       */
        printf(Q_("Bisecting: %d revision left to test after this %s\n",
                  "Bisecting: %d revisions left to test after this %s\n",
                  nr), nr, steps_msg);
@@@ -1045,40 -1041,3 +1045,40 @@@ int estimate_bisect_steps(int all
  
        return (e < 3 * x) ? n : n - 1;
  }
 +
 +static int mark_for_removal(const char *refname, const struct object_id *oid,
 +                          int flag, void *cb_data)
 +{
 +      struct string_list *refs = cb_data;
 +      char *ref = xstrfmt("refs/bisect%s", refname);
 +      string_list_append(refs, ref);
 +      return 0;
 +}
 +
 +int bisect_clean_state(void)
 +{
 +      int result = 0;
 +
 +      /* There may be some refs packed during bisection */
 +      struct string_list refs_for_removal = STRING_LIST_INIT_NODUP;
 +      for_each_ref_in("refs/bisect", mark_for_removal, (void *) &refs_for_removal);
 +      string_list_append(&refs_for_removal, xstrdup("BISECT_HEAD"));
 +      result = delete_refs("bisect: remove", &refs_for_removal, REF_NO_DEREF);
 +      refs_for_removal.strdup_strings = 1;
 +      string_list_clear(&refs_for_removal, 0);
 +      unlink_or_warn(git_path_bisect_expected_rev());
 +      unlink_or_warn(git_path_bisect_ancestors_ok());
 +      unlink_or_warn(git_path_bisect_log());
 +      unlink_or_warn(git_path_bisect_names());
 +      unlink_or_warn(git_path_bisect_run());
 +      unlink_or_warn(git_path_bisect_terms());
 +      /* Cleanup head-name if it got left by an old version of git-bisect */
 +      unlink_or_warn(git_path_head_name());
 +      /*
 +       * Cleanup BISECT_START last to support the --no-checkout option
 +       * introduced in the commit 4796e823a.
 +       */
 +      unlink_or_warn(git_path_bisect_start());
 +
 +      return result;
 +}