Merge branch 'jk/diff-files-assume-unchanged' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 25 Jun 2014 18:47:09 +0000 (11:47 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 25 Jun 2014 18:47:09 +0000 (11:47 -0700)
"git diff --find-copies-harder" sometimes pretended as if the mode
bits have changed for paths that are marked with assume-unchanged
bit.

* jk/diff-files-assume-unchanged:
run_diff_files: do not look at uninitialized stat data

1  2 
diff-lib.c
diff --combined diff-lib.c
index 044872935c30d84affb1955a7ae03c0986c90bda,73eedca9c8f874123f1f1bdc424a67ee422ef377..875aff864391ed037627462ac39c314f248b5ae6
@@@ -11,7 -11,6 +11,7 @@@
  #include "unpack-trees.h"
  #include "refs.h"
  #include "submodule.h"
 +#include "dir.h"
  
  /*
   * diff-files
@@@ -91,13 -90,15 +91,12 @@@ int run_diff_files(struct rev_info *rev
        unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
                              ? CE_MATCH_RACY_IS_DIRTY : 0);
  
 -      if (option & DIFF_SILENT_ON_REMOVED)
 -              handle_deprecated_show_diff_q(&revs->diffopt);
 -
        diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");
  
        if (diff_unmerged_stage < 0)
                diff_unmerged_stage = 2;
        entries = active_nr;
        for (i = 0; i < entries; i++) {
-               struct stat st;
                unsigned int oldmode, newmode;
                struct cache_entry *ce = active_cache[i];
                int changed;
                if (diff_can_quit_early(&revs->diffopt))
                        break;
  
 -              if (!ce_path_match(ce, &revs->prune_data))
 +              if (!ce_path_match(ce, &revs->prune_data, NULL))
                        continue;
  
                if (ce_stage(ce)) {
                        unsigned int wt_mode = 0;
                        int num_compare_stages = 0;
                        size_t path_len;
+                       struct stat st;
  
                        path_len = ce_namelen(ce);
  
                        dpath->path = (char *) &(dpath->parent[5]);
  
                        dpath->next = NULL;
 -                      dpath->len = path_len;
                        memcpy(dpath->path, ce->name, path_len);
                        dpath->path[path_len] = '\0';
                        hashclr(dpath->sha1);
                        continue;
  
                /* If CE_VALID is set, don't look at workdir for file removal */
-               changed = (ce->ce_flags & CE_VALID) ? 0 : check_removed(ce, &st);
-               if (changed) {
-                       if (changed < 0) {
-                               perror(ce->name);
+               if (ce->ce_flags & CE_VALID) {
+                       changed = 0;
+                       newmode = ce->ce_mode;
+               } else {
+                       struct stat st;
+                       changed = check_removed(ce, &st);
+                       if (changed) {
+                               if (changed < 0) {
+                                       perror(ce->name);
+                                       continue;
+                               }
+                               diff_addremove(&revs->diffopt, '-', ce->ce_mode,
+                                              ce->sha1, !is_null_sha1(ce->sha1),
+                                              ce->name, 0);
                                continue;
                        }
-                       diff_addremove(&revs->diffopt, '-', ce->ce_mode,
-                                      ce->sha1, !is_null_sha1(ce->sha1),
-                                      ce->name, 0);
-                       continue;
+                       changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
+                                                           ce_option, &dirty_submodule);
+                       newmode = ce_mode_from_stat(ce, st.st_mode);
                }
-               changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
-                                                   ce_option, &dirty_submodule);
                if (!changed && !dirty_submodule) {
                        ce_mark_uptodate(ce);
                        if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
                                continue;
                }
                oldmode = ce->ce_mode;
-               newmode = ce_mode_from_stat(ce, st.st_mode);
                diff_change(&revs->diffopt, oldmode, newmode,
                            ce->sha1, (changed ? null_sha1 : ce->sha1),
                            !is_null_sha1(ce->sha1), (changed ? 0 : !is_null_sha1(ce->sha1)),
@@@ -323,6 -335,7 +332,6 @@@ static int show_modified(struct rev_inf
                p = xmalloc(combine_diff_path_size(2, pathlen));
                p->path = (char *) &p->parent[2];
                p->next = NULL;
 -              p->len = pathlen;
                memcpy(p->path, new->name, pathlen);
                p->path[pathlen] = 0;
                p->mode = mode;
@@@ -434,7 -447,7 +443,7 @@@ static int oneway_diff(const struct cac
        if (tree == o->df_conflict_entry)
                tree = NULL;
  
 -      if (ce_path_match(idx ? idx : tree, &revs->prune_data)) {
 +      if (ce_path_match(idx ? idx : tree, &revs->prune_data, NULL)) {
                do_oneway_diff(o, idx, tree);
                if (diff_can_quit_early(&revs->diffopt)) {
                        o->exiting_early = 1;