Merge branch 'jc/blame-abbrev'
authorJunio C Hamano <gitster@pobox.com>
Thu, 6 Oct 2016 21:53:10 +0000 (14:53 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 6 Oct 2016 21:53:10 +0000 (14:53 -0700)
Almost everybody uses DEFAULT_ABBREV to refer to the default
setting for the abbreviation, but "git blame" peeked into
underlying variable bypassing the macro for no good reason.

* jc/blame-abbrev:
blame: use DEFAULT_ABBREV macro

1  2 
builtin/blame.c
diff --combined builtin/blame.c
index a7bd7a6fd80f7d68f58d094bdc5cd6c288fb0e29,f618392e55f70966accc49aa7ff22de2d16f189f..da44b36ff5eab12a442e5299ff8b98c2505b16f4
@@@ -120,7 -120,7 +120,7 @@@ struct origin 
         */
        struct blame_entry *suspects;
        mmfile_t file;
 -      unsigned char blob_sha1[20];
 +      struct object_id blob_oid;
        unsigned mode;
        /* guilty gets set when shipping any suspects to the final
         * blame list instead of other commits
@@@ -154,8 -154,8 +154,8 @@@ static int diff_hunks(mmfile_t *file_a
   */
  int textconv_object(const char *path,
                    unsigned mode,
 -                  const unsigned char *sha1,
 -                  int sha1_valid,
 +                  const struct object_id *oid,
 +                  int oid_valid,
                    char **buf,
                    unsigned long *buf_size)
  {
        struct userdiff_driver *textconv;
  
        df = alloc_filespec(path);
 -      fill_filespec(df, sha1, sha1_valid, mode);
 +      fill_filespec(df, oid->hash, oid_valid, mode);
        textconv = get_textconv(df);
        if (!textconv) {
                free_filespec(df);
@@@ -188,16 -188,15 +188,16 @@@ static void fill_origin_blob(struct dif
  
                num_read_blob++;
                if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) &&
 -                  textconv_object(o->path, o->mode, o->blob_sha1, 1, &file->ptr, &file_size))
 +                  textconv_object(o->path, o->mode, &o->blob_oid, 1, &file->ptr, &file_size))
                        ;
                else
 -                      file->ptr = read_sha1_file(o->blob_sha1, &type, &file_size);
 +                      file->ptr = read_sha1_file(o->blob_oid.hash, &type,
 +                                                 &file_size);
                file->size = file_size;
  
                if (!file->ptr)
                        die("Cannot read blob %s for path %s",
 -                          sha1_to_hex(o->blob_sha1),
 +                          oid_to_hex(&o->blob_oid),
                            o->path);
                o->file = *file;
        }
@@@ -509,17 -508,17 +509,17 @@@ static struct origin *get_origin(struc
   */
  static int fill_blob_sha1_and_mode(struct origin *origin)
  {
 -      if (!is_null_sha1(origin->blob_sha1))
 +      if (!is_null_oid(&origin->blob_oid))
                return 0;
        if (get_tree_entry(origin->commit->object.oid.hash,
                           origin->path,
 -                         origin->blob_sha1, &origin->mode))
 +                         origin->blob_oid.hash, &origin->mode))
                goto error_out;
 -      if (sha1_object_info(origin->blob_sha1, NULL) != OBJ_BLOB)
 +      if (sha1_object_info(origin->blob_oid.hash, NULL) != OBJ_BLOB)
                goto error_out;
        return 0;
   error_out:
 -      hashclr(origin->blob_sha1);
 +      oidclr(&origin->blob_oid);
        origin->mode = S_IFINVALID;
        return -1;
  }
@@@ -573,7 -572,7 +573,7 @@@ static struct origin *find_origin(struc
        if (!diff_queued_diff.nr) {
                /* The path is the same as parent */
                porigin = get_origin(sb, parent, origin->path);
 -              hashcpy(porigin->blob_sha1, origin->blob_sha1);
 +              oidcpy(&porigin->blob_oid, &origin->blob_oid);
                porigin->mode = origin->mode;
        } else {
                /*
                            p->status);
                case 'M':
                        porigin = get_origin(sb, parent, origin->path);
 -                      hashcpy(porigin->blob_sha1, p->one->oid.hash);
 +                      oidcpy(&porigin->blob_oid, &p->one->oid);
                        porigin->mode = p->one->mode;
                        break;
                case 'A':
@@@ -645,7 -644,7 +645,7 @@@ static struct origin *find_rename(struc
                if ((p->status == 'R' || p->status == 'C') &&
                    !strcmp(p->two->path, origin->path)) {
                        porigin = get_origin(sb, parent, p->one->path);
 -                      hashcpy(porigin->blob_sha1, p->one->oid.hash);
 +                      oidcpy(&porigin->blob_oid, &p->one->oid);
                        porigin->mode = p->one->mode;
                        break;
                }
@@@ -1309,7 -1308,7 +1309,7 @@@ static void find_copy_in_parent(struct 
                                continue;
  
                        norigin = get_origin(sb, parent, p->one->path);
 -                      hashcpy(norigin->blob_sha1, p->one->oid.hash);
 +                      oidcpy(&norigin->blob_oid, &p->one->oid);
                        norigin->mode = p->one->mode;
                        fill_origin_blob(&sb->revs->diffopt, norigin, &file_p);
                        if (!file_p.ptr)
@@@ -1459,14 -1458,15 +1459,14 @@@ static void pass_blame(struct scoreboar
                        porigin = find(sb, p, origin);
                        if (!porigin)
                                continue;
 -                      if (!hashcmp(porigin->blob_sha1, origin->blob_sha1)) {
 +                      if (!oidcmp(&porigin->blob_oid, &origin->blob_oid)) {
                                pass_whole_blame(sb, origin, porigin);
                                origin_decref(porigin);
                                goto finish;
                        }
                        for (j = same = 0; j < i; j++)
                                if (sg_origin[j] &&
 -                                  !hashcmp(sg_origin[j]->blob_sha1,
 -                                           porigin->blob_sha1)) {
 +                                  !oidcmp(&sg_origin[j]->blob_oid, &porigin->blob_oid)) {
                                        same = 1;
                                        break;
                                }
@@@ -1941,7 -1941,7 +1941,7 @@@ static void emit_other(struct scoreboar
        cp = nth_line(sb, ent->lno);
        for (cnt = 0; cnt < ent->num_lines; cnt++) {
                char ch;
 -              int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? 40 : abbrev;
 +              int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? GIT_SHA1_HEXSZ : abbrev;
  
                if (suspect->commit->object.flags & UNINTERESTING) {
                        if (blank_boundary)
@@@ -2111,7 -2111,7 +2111,7 @@@ static void find_alignment(struct score
        unsigned largest_score = 0;
        struct blame_entry *e;
        int compute_auto_abbrev = (abbrev < 0);
-       int auto_abbrev = default_abbrev;
+       int auto_abbrev = DEFAULT_ABBREV;
  
        for (e = sb->ent; e; e = e->next) {
                struct origin *suspect = e->suspect;
@@@ -2220,8 -2220,6 +2220,8 @@@ static int git_blame_config(const char 
                return 0;
        }
  
 +      if (git_diff_heuristic_config(var, value, cb) < 0)
 +              return -1;
        if (userdiff_config(var, value) < 0)
                return -1;
  
@@@ -2234,12 -2232,12 +2234,12 @@@ static void verify_working_tree_path(st
        int pos;
  
        for (parents = work_tree->parents; parents; parents = parents->next) {
 -              const unsigned char *commit_sha1 = parents->item->object.oid.hash;
 -              unsigned char blob_sha1[20];
 +              const struct object_id *commit_oid = &parents->item->object.oid;
 +              struct object_id blob_oid;
                unsigned mode;
  
 -              if (!get_tree_entry(commit_sha1, path, blob_sha1, &mode) &&
 -                  sha1_object_info(blob_sha1, NULL) == OBJ_BLOB)
 +              if (!get_tree_entry(commit_oid->hash, path, blob_oid.hash, &mode) &&
 +                  sha1_object_info(blob_oid.hash, NULL) == OBJ_BLOB)
                        return;
        }
  
                die("no such path '%s' in HEAD", path);
  }
  
 -static struct commit_list **append_parent(struct commit_list **tail, const unsigned char *sha1)
 +static struct commit_list **append_parent(struct commit_list **tail, const struct object_id *oid)
  {
        struct commit *parent;
  
 -      parent = lookup_commit_reference(sha1);
 +      parent = lookup_commit_reference(oid->hash);
        if (!parent)
 -              die("no such commit %s", sha1_to_hex(sha1));
 +              die("no such commit %s", oid_to_hex(oid));
        return &commit_list_insert(parent, tail)->next;
  }
  
@@@ -2276,10 -2274,10 +2276,10 @@@ static void append_merge_parents(struc
        }
  
        while (!strbuf_getwholeline_fd(&line, merge_head, '\n')) {
 -              unsigned char sha1[20];
 -              if (line.len < 40 || get_sha1_hex(line.buf, sha1))
 +              struct object_id oid;
 +              if (line.len < GIT_SHA1_HEXSZ || get_oid_hex(line.buf, &oid))
                        die("unknown line in '%s': %s", git_path_merge_head(), line.buf);
 -              tail = append_parent(tail, sha1);
 +              tail = append_parent(tail, &oid);
        }
        close(merge_head);
        strbuf_release(&line);
@@@ -2308,7 -2306,7 +2308,7 @@@ static struct commit *fake_working_tree
        struct commit *commit;
        struct origin *origin;
        struct commit_list **parent_tail, *parent;
 -      unsigned char head_sha1[20];
 +      struct object_id head_oid;
        struct strbuf buf = STRBUF_INIT;
        const char *ident;
        time_t now;
        commit->date = now;
        parent_tail = &commit->parents;
  
 -      if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_sha1, NULL))
 +      if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_oid.hash, NULL))
                die("no such ref: HEAD");
  
 -      parent_tail = append_parent(parent_tail, head_sha1);
 +      parent_tail = append_parent(parent_tail, &head_oid);
        append_merge_parents(parent_tail);
        verify_working_tree_path(commit, path);
  
                switch (st.st_mode & S_IFMT) {
                case S_IFREG:
                        if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) &&
 -                          textconv_object(read_from, mode, null_sha1, 0, &buf_ptr, &buf_len))
 +                          textconv_object(read_from, mode, &null_oid, 0, &buf_ptr, &buf_len))
                                strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1);
                        else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
                                die_errno("cannot open or read '%s'", read_from);
        convert_to_git(path, buf.buf, buf.len, &buf, 0);
        origin->file.ptr = buf.buf;
        origin->file.size = buf.len;
 -      pretend_sha1_file(buf.buf, buf.len, OBJ_BLOB, origin->blob_sha1);
 +      pretend_sha1_file(buf.buf, buf.len, OBJ_BLOB, origin->blob_oid.hash);
  
        /*
         * Read the current index, replace the path entry with
        }
        size = cache_entry_size(len);
        ce = xcalloc(1, size);
 -      hashcpy(ce->sha1, origin->blob_sha1);
 +      oidcpy(&ce->oid, &origin->blob_oid);
        memcpy(ce->name, path, len);
        ce->ce_flags = create_ce_flags(0);
        ce->ce_namelen = len;
@@@ -2552,15 -2550,6 +2552,15 @@@ int cmd_blame(int argc, const char **ar
                OPT_BIT('s', NULL, &output_option, N_("Suppress author name and timestamp (Default: off)"), OUTPUT_NO_AUTHOR),
                OPT_BIT('e', "show-email", &output_option, N_("Show author email instead of name (Default: off)"), OUTPUT_SHOW_EMAIL),
                OPT_BIT('w', NULL, &xdl_opts, N_("Ignore whitespace differences"), XDF_IGNORE_WHITESPACE),
 +
 +              /*
 +               * The following two options are parsed by parse_revision_opt()
 +               * and are only included here to get included in the "-h"
 +               * output:
 +               */
 +              { OPTION_LOWLEVEL_CALLBACK, 0, "indent-heuristic", NULL, NULL, N_("Use an experimental indent-based heuristic to improve diffs"), PARSE_OPT_NOARG, parse_opt_unknown_cb },
 +              { OPTION_LOWLEVEL_CALLBACK, 0, "compaction-heuristic", NULL, NULL, N_("Use an experimental blank-line-based heuristic to improve diffs"), PARSE_OPT_NOARG, parse_opt_unknown_cb },
 +
                OPT_BIT(0, "minimal", &xdl_opts, N_("Spend extra cycles to find better match"), XDF_NEED_MINIMAL),
                OPT_STRING('S', NULL, &revs_file, N_("file"), N_("Use revisions from <file> instead of calling git-rev-list")),
                OPT_STRING(0, "contents", &contents_from, N_("file"), N_("Use <file>'s contents as the final image")),
        }
  parse_done:
        no_whole_file_rename = !DIFF_OPT_TST(&revs.diffopt, FOLLOW_RENAMES);
 +      xdl_opts |= revs.diffopt.xdl_opts & (XDF_COMPACTION_HEURISTIC | XDF_INDENT_HEURISTIC);
        DIFF_OPT_CLR(&revs.diffopt, FOLLOW_RENAMES);
        argc = parse_options_end(&ctx);
  
        if (incremental || (output_option & OUTPUT_PORCELAIN)) {
                if (show_progress > 0)
 -                      die("--progress can't be used with --incremental or porcelain formats");
 +                      die(_("--progress can't be used with --incremental or porcelain formats"));
                show_progress = 0;
        } else if (show_progress < 0)
                show_progress = isatty(2);
                sb.commits.compare = compare_commits_by_commit_date;
        }
        else if (contents_from)
 -              die("--contents and --reverse do not blend well.");
 +              die(_("--contents and --reverse do not blend well."));
        else {
                final_commit_name = prepare_initial(&sb);
                sb.commits.compare = compare_commits_by_reverse_commit_date;
                add_pending_object(&revs, &(sb.final->object), ":");
        }
        else if (contents_from)
 -              die("Cannot use --contents with final commit object name");
 +              die(_("cannot use --contents with final commit object name"));
  
        if (reverse && revs.first_parent_only) {
                final_commit = find_single_final(sb.revs, NULL);
                if (!final_commit)
 -                      die("--reverse and --first-parent together require specified latest commit");
 +                      die(_("--reverse and --first-parent together require specified latest commit"));
        }
  
        /*
                }
  
                if (oidcmp(&c->object.oid, &sb.final->object.oid))
 -                      die("--reverse --first-parent together require range along first-parent chain");
 +                      die(_("--reverse --first-parent together require range along first-parent chain"));
        }
  
        if (is_null_oid(&sb.final->object.oid)) {
        else {
                o = get_origin(&sb, sb.final, path);
                if (fill_blob_sha1_and_mode(o))
 -                      die("no such path %s in %s", path, final_commit_name);
 +                      die(_("no such path %s in %s"), path, final_commit_name);
  
                if (DIFF_OPT_TST(&sb.revs->diffopt, ALLOW_TEXTCONV) &&
 -                  textconv_object(path, o->mode, o->blob_sha1, 1, (char **) &sb.final_buf,
 +                  textconv_object(path, o->mode, &o->blob_oid, 1, (char **) &sb.final_buf,
                                    &sb.final_buf_size))
                        ;
                else
 -                      sb.final_buf = read_sha1_file(o->blob_sha1, &type,
 +                      sb.final_buf = read_sha1_file(o->blob_oid.hash, &type,
                                                      &sb.final_buf_size);
  
                if (!sb.final_buf)
 -                      die("Cannot read blob %s for path %s",
 -                          sha1_to_hex(o->blob_sha1),
 +                      die(_("cannot read blob %s for path %s"),
 +                          oid_to_hex(&o->blob_oid),
                            path);
        }
        num_read_blob++;
                                    &bottom, &top, sb.path))
                        usage(blame_usage);
                if (lno < top || ((lno || bottom) && lno < bottom))
 -                      die("file %s has only %lu lines", path, lno);
 +                      die(Q_("file %s has only %lu line",
 +                             "file %s has only %lu lines",
 +                             lno), path, lno);
                if (bottom < 1)
                        bottom = 1;
                if (top < 1)