Merge branch 'tk/diffcore-delta-remove-unused' into maint
authorJunio C Hamano <gitster@pobox.com>
Tue, 29 Nov 2016 21:28:03 +0000 (13:28 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 29 Nov 2016 21:28:03 +0000 (13:28 -0800)
Code cleanup.

* tk/diffcore-delta-remove-unused:
diffcore-delta: remove unused parameter to diffcore_count_changes()

1  2 
diff.c
diffcore-break.c
diffcore-rename.c
diffcore.h
diff --combined diff.c
index fe6f59160fd70a6dc801d3a67c61484dda521fb1,bbb8977539ed4986084b845f5f1a0549dafa9ef7..8c78fce49dc5fa9e1215eb3bdb88e1f5e7f9d2c6
--- 1/diff.c
--- 2/diff.c
+++ b/diff.c
@@@ -26,7 -26,6 +26,7 @@@
  #endif
  
  static int diff_detect_rename_default;
 +static int diff_compaction_heuristic; /* experimental */
  static int diff_rename_limit_default = 400;
  static int diff_suppress_blank_empty;
  static int diff_use_color_default = -1;
@@@ -169,11 -168,6 +169,11 @@@ long parse_algorithm_value(const char *
   * never be affected by the setting of diff.renames
   * the user happens to have in the configuration file.
   */
 +void init_diff_ui_defaults(void)
 +{
 +      diff_detect_rename_default = 1;
 +}
 +
  int git_diff_ui_config(const char *var, const char *value, void *cb)
  {
        if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
                diff_detect_rename_default = git_config_rename(var, value);
                return 0;
        }
 +      if (!strcmp(var, "diff.compactionheuristic")) {
 +              diff_compaction_heuristic = git_config_bool(var, value);
 +              return 0;
 +      }
        if (!strcmp(var, "diff.autorefreshindex")) {
                diff_auto_refresh_index = git_config_bool(var, value);
                return 0;
@@@ -354,6 -344,7 +354,6 @@@ struct emit_callback 
        const char **label_path;
        struct diff_words_data *diff_words;
        struct diff_options *opt;
 -      int *found_changesp;
        struct strbuf *header;
  };
  
@@@ -721,6 -712,7 +721,6 @@@ static void emit_rewrite_diff(const cha
  
        memset(&ecbdata, 0, sizeof(ecbdata));
        ecbdata.color_diff = want_color(o->use_color);
 -      ecbdata.found_changesp = &o->found_changes;
        ecbdata.ws_rule = whitespace_rule(name_b);
        ecbdata.opt = o;
        if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
@@@ -949,8 -941,7 +949,8 @@@ static int find_word_boundaries(mmfile_
  {
        if (word_regex && *begin < buffer->size) {
                regmatch_t match[1];
 -              if (!regexec(word_regex, buffer->ptr + *begin, 1, match, 0)) {
 +              if (!regexec_buf(word_regex, buffer->ptr + *begin,
 +                               buffer->size - *begin, 1, match, 0)) {
                        char *p = memchr(buffer->ptr + *begin + match[0].rm_so,
                                        '\n', match[0].rm_eo - match[0].rm_so);
                        *end = p ? p - buffer->ptr : match[0].rm_eo + *begin;
@@@ -1215,13 -1206,12 +1215,13 @@@ static void fn_out_consume(void *priv, 
        struct diff_options *o = ecbdata->opt;
        const char *line_prefix = diff_line_prefix(o);
  
 +      o->found_changes = 1;
 +
        if (ecbdata->header) {
 -              fprintf(ecbdata->opt->file, "%s", ecbdata->header->buf);
 +              fprintf(o->file, "%s", ecbdata->header->buf);
                strbuf_reset(ecbdata->header);
                ecbdata->header = NULL;
        }
 -      *(ecbdata->found_changesp) = 1;
  
        if (ecbdata->label_path[0]) {
                const char *name_a_tab, *name_b_tab;
                name_a_tab = strchr(ecbdata->label_path[0], ' ') ? "\t" : "";
                name_b_tab = strchr(ecbdata->label_path[1], ' ') ? "\t" : "";
  
 -              fprintf(ecbdata->opt->file, "%s%s--- %s%s%s\n",
 +              fprintf(o->file, "%s%s--- %s%s%s\n",
                        line_prefix, meta, ecbdata->label_path[0], reset, name_a_tab);
 -              fprintf(ecbdata->opt->file, "%s%s+++ %s%s%s\n",
 +              fprintf(o->file, "%s%s+++ %s%s%s\n",
                        line_prefix, meta, ecbdata->label_path[1], reset, name_b_tab);
                ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
        }
                find_lno(line, ecbdata);
                emit_hunk_header(ecbdata, line, len);
                if (line[len-1] != '\n')
 -                      putc('\n', ecbdata->opt->file);
 -              return;
 -      }
 -
 -      if (len < 1) {
 -              emit_line(ecbdata->opt, reset, reset, line, len);
 -              if (ecbdata->diff_words
 -                  && ecbdata->diff_words->type == DIFF_WORDS_PORCELAIN)
 -                      fputs("~\n", ecbdata->opt->file);
 +                      putc('\n', o->file);
                return;
        }
  
                }
                diff_words_flush(ecbdata);
                if (ecbdata->diff_words->type == DIFF_WORDS_PORCELAIN) {
 -                      emit_line(ecbdata->opt, context, reset, line, len);
 -                      fputs("~\n", ecbdata->opt->file);
 +                      emit_line(o, context, reset, line, len);
 +                      fputs("~\n", o->file);
                } else {
                        /*
                         * Skip the prefix character, if any.  With
                              line++;
                              len--;
                        }
 -                      emit_line(ecbdata->opt, context, reset, line, len);
 +                      emit_line(o, context, reset, line, len);
                }
                return;
        }
        default:
                /* incomplete line at the end */
                ecbdata->lno_in_preimage++;
 -              emit_line(ecbdata->opt,
 -                        diff_get_color(ecbdata->color_diff, DIFF_CONTEXT),
 +              emit_line(o, diff_get_color(ecbdata->color_diff, DIFF_CONTEXT),
                          reset, line, len);
                break;
        }
@@@ -1924,8 -1923,8 +1924,8 @@@ static void show_dirstat(struct diff_op
  
                name = p->two->path ? p->two->path : p->one->path;
  
 -              if (p->one->sha1_valid && p->two->sha1_valid)
 -                      content_changed = hashcmp(p->one->sha1, p->two->sha1);
 +              if (p->one->oid_valid && p->two->oid_valid)
 +                      content_changed = oidcmp(&p->one->oid, &p->two->oid);
                else
                        content_changed = 1;
  
                if (DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
                        diff_populate_filespec(p->one, 0);
                        diff_populate_filespec(p->two, 0);
-                       diffcore_count_changes(p->one, p->two, NULL, NULL, 0,
+                       diffcore_count_changes(p->one, p->two, NULL, NULL,
                                               &copied, &added);
                        diff_free_filespec_data(p->one);
                        diff_free_filespec_data(p->two);
@@@ -2297,8 -2296,7 +2297,8 @@@ static void builtin_diff(const char *na
                const char *add = diff_get_color_opt(o, DIFF_FILE_NEW);
                show_submodule_summary(o->file, one->path ? one->path : two->path,
                                line_prefix,
 -                              one->sha1, two->sha1, two->dirty_submodule,
 +                              one->oid.hash, two->oid.hash,
 +                              two->dirty_submodule,
                                meta, del, add, reset);
                return;
        }
                if (!one->data && !two->data &&
                    S_ISREG(one->mode) && S_ISREG(two->mode) &&
                    !DIFF_OPT_TST(o, BINARY)) {
 -                      if (!hashcmp(one->sha1, two->sha1)) {
 +                      if (!oidcmp(&one->oid, &two->oid)) {
                                if (must_show_header)
                                        fprintf(o->file, "%s", header.buf);
                                goto free_ab_and_return;
                memset(&ecbdata, 0, sizeof(ecbdata));
                ecbdata.label_path = lbl;
                ecbdata.color_diff = want_color(o->use_color);
 -              ecbdata.found_changesp = &o->found_changes;
                ecbdata.ws_rule = whitespace_rule(name_b);
                if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
                        check_blank_at_eof(&mf1, &mf2, &ecbdata);
@@@ -2496,7 -2495,7 +2496,7 @@@ static void builtin_diffstat(const cha
                return;
        }
  
 -      same_contents = !hashcmp(one->sha1, two->sha1);
 +      same_contents = !oidcmp(&one->oid, &two->oid);
  
        if (diff_filespec_is_binary(one) || diff_filespec_is_binary(two)) {
                data->is_binary = 1;
@@@ -2629,8 -2628,8 +2629,8 @@@ void fill_filespec(struct diff_filespe
  {
        if (mode) {
                spec->mode = canon_mode(mode);
 -              hashcpy(spec->sha1, sha1);
 -              spec->sha1_valid = sha1_valid;
 +              hashcpy(spec->oid.hash, sha1);
 +              spec->oid_valid = sha1_valid;
        }
  }
  
@@@ -2673,13 -2672,6 +2673,13 @@@ static int reuse_worktree_file(const ch
        if (!FAST_WORKING_DIRECTORY && !want_file && has_sha1_pack(sha1))
                return 0;
  
 +      /*
 +       * Similarly, if we'd have to convert the file contents anyway, that
 +       * makes the optimization not worthwhile.
 +       */
 +      if (!want_file && would_convert_to_git(name))
 +              return 0;
 +
        len = strlen(name);
        pos = cache_name_pos(name, len);
        if (pos < 0)
@@@ -2719,8 -2711,7 +2719,8 @@@ static int diff_populate_gitlink(struc
        if (s->dirty_submodule)
                dirty = "-dirty";
  
 -      strbuf_addf(&buf, "Subproject commit %s%s\n", sha1_to_hex(s->sha1), dirty);
 +      strbuf_addf(&buf, "Subproject commit %s%s\n",
 +                  oid_to_hex(&s->oid), dirty);
        s->size = buf.len;
        if (size_only) {
                s->data = NULL;
@@@ -2763,8 -2754,8 +2763,8 @@@ int diff_populate_filespec(struct diff_
        if (S_ISGITLINK(s->mode))
                return diff_populate_gitlink(s, size_only);
  
 -      if (!s->sha1_valid ||
 -          reuse_worktree_file(s->path, s->sha1, 0)) {
 +      if (!s->oid_valid ||
 +          reuse_worktree_file(s->path, s->oid.hash, 0)) {
                struct strbuf buf = STRBUF_INIT;
                struct stat st;
                int fd;
        else {
                enum object_type type;
                if (size_only || (flags & CHECK_BINARY)) {
 -                      type = sha1_object_info(s->sha1, &s->size);
 +                      type = sha1_object_info(s->oid.hash, &s->size);
                        if (type < 0)
 -                              die("unable to read %s", sha1_to_hex(s->sha1));
 +                              die("unable to read %s",
 +                                  oid_to_hex(&s->oid));
                        if (size_only)
                                return 0;
                        if (s->size > big_file_threshold && s->is_binary == -1) {
                                return 0;
                        }
                }
 -              s->data = read_sha1_file(s->sha1, &type, &s->size);
 +              s->data = read_sha1_file(s->oid.hash, &type, &s->size);
                if (!s->data)
 -                      die("unable to read %s", sha1_to_hex(s->sha1));
 +                      die("unable to read %s", oid_to_hex(&s->oid));
                s->should_free = 1;
        }
        return 0;
@@@ -2863,7 -2853,7 +2863,7 @@@ void diff_free_filespec_data(struct dif
  static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
                           void *blob,
                           unsigned long size,
 -                         const unsigned char *sha1,
 +                         const struct object_id *oid,
                           int mode)
  {
        int fd;
                die_errno("unable to write temp-file");
        close_tempfile(&temp->tempfile);
        temp->name = get_tempfile_path(&temp->tempfile);
 -      sha1_to_hex_r(temp->hex, sha1);
 +      oid_to_hex_r(temp->hex, oid);
        xsnprintf(temp->mode, sizeof(temp->mode), "%06o", mode);
        strbuf_release(&buf);
        strbuf_release(&template);
@@@ -2912,8 -2902,8 +2912,8 @@@ static struct diff_tempfile *prepare_te
        }
  
        if (!S_ISGITLINK(one->mode) &&
 -          (!one->sha1_valid ||
 -           reuse_worktree_file(name, one->sha1, 1))) {
 +          (!one->oid_valid ||
 +           reuse_worktree_file(name, one->oid.hash, 1))) {
                struct stat st;
                if (lstat(name, &st) < 0) {
                        if (errno == ENOENT)
                        if (strbuf_readlink(&sb, name, st.st_size) < 0)
                                die_errno("readlink(%s)", name);
                        prep_temp_blob(name, temp, sb.buf, sb.len,
 -                                     (one->sha1_valid ?
 -                                      one->sha1 : null_sha1),
 -                                     (one->sha1_valid ?
 +                                     (one->oid_valid ?
 +                                      &one->oid : &null_oid),
 +                                     (one->oid_valid ?
                                        one->mode : S_IFLNK));
                        strbuf_release(&sb);
                }
                else {
                        /* we can borrow from the file in the work tree */
                        temp->name = name;
 -                      if (!one->sha1_valid)
 +                      if (!one->oid_valid)
                                sha1_to_hex_r(temp->hex, null_sha1);
                        else
 -                              sha1_to_hex_r(temp->hex, one->sha1);
 +                              sha1_to_hex_r(temp->hex, one->oid.hash);
                        /* Even though we may sometimes borrow the
                         * contents from the work tree, we always want
                         * one->mode.  mode is trustworthy even when
                if (diff_populate_filespec(one, 0))
                        die("cannot read data blob for %s", one->path);
                prep_temp_blob(name, temp, one->data, one->size,
 -                             one->sha1, one->mode);
 +                             &one->oid, one->mode);
        }
        return temp;
  }
@@@ -3065,7 -3055,7 +3065,7 @@@ static void fill_metainfo(struct strbu
        default:
                *must_show_header = 0;
        }
 -      if (one && two && hashcmp(one->sha1, two->sha1)) {
 +      if (one && two && oidcmp(&one->oid, &two->oid)) {
                int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
  
                if (DIFF_OPT_TST(o, BINARY)) {
                                abbrev = 40;
                }
                strbuf_addf(msg, "%s%sindex %s..", line_prefix, set,
 -                          find_unique_abbrev(one->sha1, abbrev));
 -              strbuf_addstr(msg, find_unique_abbrev(two->sha1, abbrev));
 +                          find_unique_abbrev(one->oid.hash, abbrev));
 +              strbuf_add_unique_abbrev(msg, two->oid.hash, abbrev);
                if (one->mode == two->mode)
                        strbuf_addf(msg, " %06o", one->mode);
                strbuf_addf(msg, "%s\n", reset);
@@@ -3131,20 -3121,20 +3131,20 @@@ static void run_diff_cmd(const char *pg
  static void diff_fill_sha1_info(struct diff_filespec *one)
  {
        if (DIFF_FILE_VALID(one)) {
 -              if (!one->sha1_valid) {
 +              if (!one->oid_valid) {
                        struct stat st;
                        if (one->is_stdin) {
 -                              hashcpy(one->sha1, null_sha1);
 +                              oidclr(&one->oid);
                                return;
                        }
                        if (lstat(one->path, &st) < 0)
                                die_errno("stat '%s'", one->path);
 -                      if (index_path(one->sha1, one->path, &st, 0))
 +                      if (index_path(one->oid.hash, one->path, &st, 0))
                                die("cannot hash %s", one->path);
                }
        }
        else
 -              hashclr(one->sha1);
 +              oidclr(&one->oid);
  }
  
  static void strip_prefix(int prefix_length, const char **namep, const char **otherp)
@@@ -3283,8 -3273,6 +3283,8 @@@ void diff_setup(struct diff_options *op
        options->use_color = diff_use_color_default;
        options->detect_rename = diff_detect_rename_default;
        options->xdl_opts |= diff_algorithm;
 +      if (diff_compaction_heuristic)
 +              DIFF_XDL_SET(options, COMPACTION_HEURISTIC);
  
        options->orderfile = diff_order_file_cfg;
  
@@@ -3805,10 -3793,6 +3805,10 @@@ int diff_opt_parse(struct diff_options 
                DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
        else if (!strcmp(arg, "--ignore-blank-lines"))
                DIFF_XDL_SET(options, IGNORE_BLANK_LINES);
 +      else if (!strcmp(arg, "--compaction-heuristic"))
 +              DIFF_XDL_SET(options, COMPACTION_HEURISTIC);
 +      else if (!strcmp(arg, "--no-compaction-heuristic"))
 +              DIFF_XDL_CLR(options, COMPACTION_HEURISTIC);
        else if (!strcmp(arg, "--patience"))
                options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
        else if (!strcmp(arg, "--histogram"))
                if (!options->file)
                        die_errno("Could not open '%s'", path);
                options->close_file = 1;
 +              if (options->use_color != GIT_COLOR_ALWAYS)
 +                      options->use_color = GIT_COLOR_NEVER;
                return argcount;
        } else
                return 0;
@@@ -4089,8 -4071,7 +4089,8 @@@ void diff_free_filepair(struct diff_fil
        free(p);
  }
  
 -/* This is different from find_unique_abbrev() in that
 +/*
 + * This is different from find_unique_abbrev() in that
   * it stuffs the result with dots for alignment.
   */
  const char *diff_unique_abbrev(const unsigned char *sha1, int len)
  
        abbrev = find_unique_abbrev(sha1, len);
        abblen = strlen(abbrev);
 +
 +      /*
 +       * In well-behaved cases, where the abbbreviated result is the
 +       * same as the requested length, append three dots after the
 +       * abbreviation (hence the whole logic is limited to the case
 +       * where abblen < 37); when the actual abbreviated result is a
 +       * bit longer than the requested length, we reduce the number
 +       * of dots so that they match the well-behaved ones.  However,
 +       * if the actual abbreviation is longer than the requested
 +       * length by more than three, we give up on aligning, and add
 +       * three dots anyway, to indicate that the output is not the
 +       * full object name.  Yes, this may be suboptimal, but this
 +       * appears only in "diff --raw --abbrev" output and it is not
 +       * worth the effort to change it now.  Note that this would
 +       * likely to work fine when the automatic sizing of default
 +       * abbreviation length is used--we would be fed -1 in "len" in
 +       * that case, and will end up always appending three-dots, but
 +       * the automatic sizing is supposed to give abblen that ensures
 +       * uniqueness across all objects (statistically speaking).
 +       */
        if (abblen < 37) {
                static char hex[41];
                if (len < abblen && abblen <= len + 2)
@@@ -4141,9 -4102,8 +4141,9 @@@ static void diff_flush_raw(struct diff_
        fprintf(opt->file, "%s", diff_line_prefix(opt));
        if (!(opt->output_format & DIFF_FORMAT_NAME_STATUS)) {
                fprintf(opt->file, ":%06o %06o %s ", p->one->mode, p->two->mode,
 -                      diff_unique_abbrev(p->one->sha1, opt->abbrev));
 -              fprintf(opt->file, "%s ", diff_unique_abbrev(p->two->sha1, opt->abbrev));
 +                      diff_unique_abbrev(p->one->oid.hash, opt->abbrev));
 +              fprintf(opt->file, "%s ",
 +                      diff_unique_abbrev(p->two->oid.hash, opt->abbrev));
        }
        if (p->score) {
                fprintf(opt->file, "%c%03d%c", p->status, similarity_index(p),
@@@ -4192,11 -4152,11 +4192,11 @@@ int diff_unmodified_pair(struct diff_fi
        /* both are valid and point at the same path.  that is, we are
         * dealing with a change.
         */
 -      if (one->sha1_valid && two->sha1_valid &&
 -          !hashcmp(one->sha1, two->sha1) &&
 +      if (one->oid_valid && two->oid_valid &&
 +          !oidcmp(&one->oid, &two->oid) &&
            !one->dirty_submodule && !two->dirty_submodule)
                return 1; /* no change */
 -      if (!one->sha1_valid && !two->sha1_valid)
 +      if (!one->oid_valid && !two->oid_valid)
                return 1; /* both look at the same file on the filesystem. */
        return 0;
  }
@@@ -4257,7 -4217,7 +4257,7 @@@ void diff_debug_filespec(struct diff_fi
                s->path,
                DIFF_FILE_VALID(s) ? "valid" : "invalid",
                s->mode,
 -              s->sha1_valid ? sha1_to_hex(s->sha1) : "");
 +              s->oid_valid ? oid_to_hex(&s->oid) : "");
        fprintf(stderr, "queue[%d] %s size %lu\n",
                x, one ? one : "",
                s->size);
@@@ -4327,11 -4287,11 +4327,11 @@@ static void diff_resolve_rename_copy(vo
                        else
                                p->status = DIFF_STATUS_RENAMED;
                }
 -              else if (hashcmp(p->one->sha1, p->two->sha1) ||
 +              else if (oidcmp(&p->one->oid, &p->two->oid) ||
                         p->one->mode != p->two->mode ||
                         p->one->dirty_submodule ||
                         p->two->dirty_submodule ||
 -                       is_null_sha1(p->one->sha1))
 +                       is_null_oid(&p->one->oid))
                        p->status = DIFF_STATUS_MODIFIED;
                else {
                        /* This is a "no-change" entry and should not
@@@ -4473,7 -4433,7 +4473,7 @@@ static void patch_id_consume(void *priv
  }
  
  /* returns 0 upon success, and writes result into sha1 */
 -static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1)
 +static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1, int diff_header_only)
  {
        struct diff_queue_struct *q = &diff_queued_diff;
        int i;
  
                diff_fill_sha1_info(p->one);
                diff_fill_sha1_info(p->two);
 -              if (fill_mmfile(&mf1, p->one) < 0 ||
 -                              fill_mmfile(&mf2, p->two) < 0)
 -                      return error("unable to read files to diff");
  
                len1 = remove_space(p->one->path, strlen(p->one->path));
                len2 = remove_space(p->two->path, strlen(p->two->path));
                                        len2, p->two->path);
                git_SHA1_Update(&ctx, buffer, len1);
  
 +              if (diff_header_only)
 +                      continue;
 +
 +              if (fill_mmfile(&mf1, p->one) < 0 ||
 +                  fill_mmfile(&mf2, p->two) < 0)
 +                      return error("unable to read files to diff");
 +
                if (diff_filespec_is_binary(p->one) ||
                    diff_filespec_is_binary(p->two)) {
 -                      git_SHA1_Update(&ctx, sha1_to_hex(p->one->sha1), 40);
 -                      git_SHA1_Update(&ctx, sha1_to_hex(p->two->sha1), 40);
 +                      git_SHA1_Update(&ctx, oid_to_hex(&p->one->oid),
 +                                      40);
 +                      git_SHA1_Update(&ctx, oid_to_hex(&p->two->oid),
 +                                      40);
                        continue;
                }
  
        return 0;
  }
  
 -int diff_flush_patch_id(struct diff_options *options, unsigned char *sha1)
 +int diff_flush_patch_id(struct diff_options *options, unsigned char *sha1, int diff_header_only)
  {
        struct diff_queue_struct *q = &diff_queued_diff;
        int i;
 -      int result = diff_get_patch_id(options, sha1);
 +      int result = diff_get_patch_id(options, sha1, diff_header_only);
  
        for (i = 0; i < q->nr; i++)
                diff_free_filepair(q->queue[i]);
@@@ -4846,7 -4800,7 +4846,7 @@@ static int diff_filespec_check_stat_unm
         */
        if (!DIFF_FILE_VALID(p->one) || /* (1) */
            !DIFF_FILE_VALID(p->two) ||
 -          (p->one->sha1_valid && p->two->sha1_valid) ||
 +          (p->one->oid_valid && p->two->oid_valid) ||
            (p->one->mode != p->two->mode) ||
            diff_populate_filespec(p->one, CHECK_SIZE_ONLY) ||
            diff_populate_filespec(p->two, CHECK_SIZE_ONLY) ||
@@@ -5142,9 -5096,8 +5142,9 @@@ size_t fill_textconv(struct userdiff_dr
        if (!driver->textconv)
                die("BUG: fill_textconv called with non-textconv driver");
  
 -      if (driver->textconv_cache && df->sha1_valid) {
 -              *outbuf = notes_cache_get(driver->textconv_cache, df->sha1,
 +      if (driver->textconv_cache && df->oid_valid) {
 +              *outbuf = notes_cache_get(driver->textconv_cache,
 +                                        df->oid.hash,
                                          &size);
                if (*outbuf)
                        return size;
        if (!*outbuf)
                die("unable to read files to diff");
  
 -      if (driver->textconv_cache && df->sha1_valid) {
 +      if (driver->textconv_cache && df->oid_valid) {
                /* ignore errors, as we might be in a readonly repository */
 -              notes_cache_put(driver->textconv_cache, df->sha1, *outbuf,
 +              notes_cache_put(driver->textconv_cache, df->oid.hash, *outbuf,
                                size);
                /*
                 * we could save up changes and flush them all at the end,
diff --combined diffcore-break.c
index 881a74f29e4f6033a2547f2558a5ad8a3eaad584,904156d92ed6796bf277dda0be17fe20b580ccf4..c64359f489c87910b9d41756918dacda49276004
@@@ -57,8 -57,8 +57,8 @@@ static int should_break(struct diff_fil
                return 1; /* even their types are different */
        }
  
 -      if (src->sha1_valid && dst->sha1_valid &&
 -          !hashcmp(src->sha1, dst->sha1))
 +      if (src->oid_valid && dst->oid_valid &&
 +          !oidcmp(&src->oid, &dst->oid))
                return 0; /* they are the same */
  
        if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0))
@@@ -73,7 -73,6 +73,6 @@@
  
        if (diffcore_count_changes(src, dst,
                                   &src->cnt_data, &dst->cnt_data,
-                                  0,
                                   &src_copied, &literal_added))
                return 0;
  
diff --combined diffcore-rename.c
index 73d003a08ae72d0c8f18b16172bc09c86022eb8f,8ce3b7d661d356955eee8c179850c2d933fd9694..15c014d864c65e2a6dd17523bacf1681a276db01
@@@ -60,8 -60,7 +60,8 @@@ static int add_rename_dst(struct diff_f
                memmove(rename_dst + first + 1, rename_dst + first,
                        (rename_dst_nr - first - 1) * sizeof(*rename_dst));
        rename_dst[first].two = alloc_filespec(two->path);
 -      fill_filespec(rename_dst[first].two, two->sha1, two->sha1_valid, two->mode);
 +      fill_filespec(rename_dst[first].two, two->oid.hash, two->oid_valid,
 +                    two->mode);
        rename_dst[first].pair = NULL;
        return 0;
  }
@@@ -145,7 -144,6 +145,6 @@@ static int estimate_similarity(struct d
         * call into this function in that case.
         */
        unsigned long max_size, delta_size, base_size, src_copied, literal_added;
-       unsigned long delta_limit;
        int score;
  
        /* We deal only with regular files.  Symlink renames are handled
        if (!dst->cnt_data && diff_populate_filespec(dst, 0))
                return 0;
  
-       delta_limit = (unsigned long)
-               (base_size * (MAX_SCORE-minimum_score) / MAX_SCORE);
        if (diffcore_count_changes(src, dst,
                                   &src->cnt_data, &dst->cnt_data,
-                                  delta_limit,
                                   &src_copied, &literal_added))
                return 0;
  
@@@ -261,13 -256,12 +257,13 @@@ struct file_similarity 
  
  static unsigned int hash_filespec(struct diff_filespec *filespec)
  {
 -      if (!filespec->sha1_valid) {
 +      if (!filespec->oid_valid) {
                if (diff_populate_filespec(filespec, 0))
                        return 0;
 -              hash_sha1_file(filespec->data, filespec->size, "blob", filespec->sha1);
 +              hash_sha1_file(filespec->data, filespec->size, "blob",
 +                             filespec->oid.hash);
        }
 -      return sha1hash(filespec->sha1);
 +      return sha1hash(filespec->oid.hash);
  }
  
  static int find_identical_files(struct hashmap *srcs,
                struct diff_filespec *source = p->filespec;
  
                /* False hash collision? */
 -              if (hashcmp(source->sha1, target->sha1))
 +              if (oidcmp(&source->oid, &target->oid))
                        continue;
                /* Non-regular files? If so, the modes must match! */
                if (!S_ISREG(source->mode) || !S_ISREG(target->mode)) {
@@@ -468,7 -462,7 +464,7 @@@ void diffcore_rename(struct diff_option
                                 strcmp(options->single_follow, p->two->path))
                                continue; /* not interested */
                        else if (!DIFF_OPT_TST(options, RENAME_EMPTY) &&
 -                               is_empty_blob_sha1(p->two->sha1))
 +                               is_empty_blob_sha1(p->two->oid.hash))
                                continue;
                        else if (add_rename_dst(p->two) < 0) {
                                warning("skipping rename detection, detected"
                        }
                }
                else if (!DIFF_OPT_TST(options, RENAME_EMPTY) &&
 -                       is_empty_blob_sha1(p->one->sha1))
 +                       is_empty_blob_sha1(p->one->oid.hash))
                        continue;
                else if (!DIFF_PAIR_UNMERGED(p) && !DIFF_FILE_VALID(p->two)) {
                        /*
                                rename_dst_nr * rename_src_nr, 50, 1);
        }
  
 -      mx = xcalloc(st_mult(num_create, NUM_CANDIDATE_PER_DST), sizeof(*mx));
 +      mx = xcalloc(st_mult(NUM_CANDIDATE_PER_DST, num_create), sizeof(*mx));
        for (dst_cnt = i = 0; i < rename_dst_nr; i++) {
                struct diff_filespec *two = rename_dst[i].two;
                struct diff_score *m;
diff --combined diffcore.h
index c11b8465fc8ef9e54f12130e490c00bd2fb63616,8a9c9d781a835e2412d0d30fb384062b4dd48a59..623024135478088028cd42b8c6a744ebb04bf0a7
@@@ -25,7 -25,7 +25,7 @@@
  struct userdiff_driver;
  
  struct diff_filespec {
 -      unsigned char sha1[20];
 +      struct object_id oid;
        char *path;
        void *data;
        void *cnt_data;
@@@ -33,7 -33,7 +33,7 @@@
        int count;               /* Reference count */
        int rename_used;         /* Count of rename users */
        unsigned short mode;     /* file mode */
 -      unsigned sha1_valid : 1; /* if true, use sha1 and trust mode;
 +      unsigned oid_valid : 1;  /* if true, use oid and trust mode;
                                  * if false, use the name and read from
                                  * the filesystem.
                                  */
@@@ -142,7 -142,6 +142,6 @@@ extern int diffcore_count_changes(struc
                                  struct diff_filespec *dst,
                                  void **src_count_p,
                                  void **dst_count_p,
-                                 unsigned long delta_limit,
                                  unsigned long *src_copied,
                                  unsigned long *literal_added);