Merge branch 'ms/core-icase-doc'
[gitweb.git] / diff-lib.c
index 4e0980caa80fb980938f68c8d350ec00cc24398b..a9f38eb5a3e0e17d111301b581d06876ce5fd510 100644 (file)
@@ -12,6 +12,7 @@
 #include "refs.h"
 #include "submodule.h"
 #include "dir.h"
+#include "fsmonitor.h"
 
 /*
  * diff-files
@@ -36,7 +37,7 @@ static int check_removed(const struct cache_entry *ce, struct stat *st)
        if (has_symlink_leading_path(ce->name, ce_namelen(ce)))
                return 1;
        if (S_ISDIR(st->st_mode)) {
-               unsigned char sub[20];
+               struct object_id sub;
 
                /*
                 * If ce is already a gitlink, we can have a plain
@@ -50,7 +51,7 @@ static int check_removed(const struct cache_entry *ce, struct stat *st)
                 * a directory --- the blob was removed!
                 */
                if (!S_ISGITLINK(ce->ce_mode) &&
-                   resolve_gitlink_ref(ce->name, "HEAD", sub))
+                   resolve_gitlink_ref(ce->name, "HEAD", &sub))
                        return 1;
        }
        return 0;
@@ -71,14 +72,15 @@ static int match_stat_with_submodule(struct diff_options *diffopt,
 {
        int changed = ce_match_stat(ce, st, ce_option);
        if (S_ISGITLINK(ce->ce_mode)) {
-               unsigned orig_flags = diffopt->flags;
-               if (!DIFF_OPT_TST(diffopt, OVERRIDE_SUBMODULE_CONFIG))
+               struct diff_flags orig_flags = diffopt->flags;
+               if (!diffopt->flags.override_submodule_config)
                        set_diffopt_flags_from_submodule_config(diffopt, ce->name);
-               if (DIFF_OPT_TST(diffopt, IGNORE_SUBMODULES))
+               if (diffopt->flags.ignore_submodules)
                        changed = 0;
-               else if (!DIFF_OPT_TST(diffopt, IGNORE_DIRTY_SUBMODULES)
-                   && (!changed || DIFF_OPT_TST(diffopt, DIRTY_SUBMODULES)))
-                       *dirty_submodule = is_submodule_modified(ce->name, DIFF_OPT_TST(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES));
+               else if (!diffopt->flags.ignore_dirty_submodules &&
+                        (!changed || diffopt->flags.dirty_submodules))
+                       *dirty_submodule = is_submodule_modified(ce->name,
+                                                                diffopt->flags.ignore_untracked_in_submodules);
                diffopt->flags = orig_flags;
        }
        return changed;
@@ -90,6 +92,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
        int diff_unmerged_stage = revs->max_count;
        unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
                              ? CE_MATCH_RACY_IS_DIRTY : 0);
+       uint64_t start = getnanotime();
 
        diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");
 
@@ -216,7 +219,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                        } else if (revs->diffopt.ita_invisible_in_index &&
                                   ce_intent_to_add(ce)) {
                                diff_addremove(&revs->diffopt, '+', ce->ce_mode,
-                                              &empty_tree_oid, 0,
+                                              the_hash_algo->empty_tree, 0,
                                               ce->name, 0);
                                continue;
                        }
@@ -228,7 +231,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
 
                if (!changed && !dirty_submodule) {
                        ce_mark_uptodate(ce);
-                       if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
+                       mark_fsmonitor_valid(ce);
+                       if (!revs->diffopt.flags.find_copies_harder)
                                continue;
                }
                oldmode = ce->ce_mode;
@@ -243,6 +247,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
        }
        diffcore_std(&revs->diffopt);
        diff_flush(&revs->diffopt);
+       trace_performance_since(start, "diff-files");
        return 0;
 }
 
@@ -299,7 +304,7 @@ static int get_stat_data(const struct cache_entry *ce,
 }
 
 static void show_new_file(struct rev_info *revs,
-                         const struct cache_entry *new,
+                         const struct cache_entry *new_file,
                          int cached, int match_missing)
 {
        const struct object_id *oid;
@@ -310,16 +315,16 @@ static void show_new_file(struct rev_info *revs,
         * New file in the index: it might actually be different in
         * the working tree.
         */
-       if (get_stat_data(new, &oid, &mode, cached, match_missing,
+       if (get_stat_data(new_file, &oid, &mode, cached, match_missing,
            &dirty_submodule, &revs->diffopt) < 0)
                return;
 
-       diff_index_show_file(revs, "+", new, oid, !is_null_oid(oid), mode, dirty_submodule);
+       diff_index_show_file(revs, "+", new_file, oid, !is_null_oid(oid), mode, dirty_submodule);
 }
 
 static int show_modified(struct rev_info *revs,
-                        const struct cache_entry *old,
-                        const struct cache_entry *new,
+                        const struct cache_entry *old_entry,
+                        const struct cache_entry *new_entry,
                         int report_missing,
                         int cached, int match_missing)
 {
@@ -327,47 +332,47 @@ static int show_modified(struct rev_info *revs,
        const struct object_id *oid;
        unsigned dirty_submodule = 0;
 
-       if (get_stat_data(new, &oid, &mode, cached, match_missing,
+       if (get_stat_data(new_entry, &oid, &mode, cached, match_missing,
                          &dirty_submodule, &revs->diffopt) < 0) {
                if (report_missing)
-                       diff_index_show_file(revs, "-", old,
-                                            &old->oid, 1, old->ce_mode,
+                       diff_index_show_file(revs, "-", old_entry,
+                                            &old_entry->oid, 1, old_entry->ce_mode,
                                             0);
                return -1;
        }
 
        if (revs->combine_merges && !cached &&
-           (oidcmp(oid, &old->oid) || oidcmp(&old->oid, &new->oid))) {
+           (oidcmp(oid, &old_entry->oid) || oidcmp(&old_entry->oid, &new_entry->oid))) {
                struct combine_diff_path *p;
-               int pathlen = ce_namelen(new);
+               int pathlen = ce_namelen(new_entry);
 
                p = xmalloc(combine_diff_path_size(2, pathlen));
                p->path = (char *) &p->parent[2];
                p->next = NULL;
-               memcpy(p->path, new->name, pathlen);
+               memcpy(p->path, new_entry->name, pathlen);
                p->path[pathlen] = 0;
                p->mode = mode;
                oidclr(&p->oid);
                memset(p->parent, 0, 2 * sizeof(struct combine_diff_parent));
                p->parent[0].status = DIFF_STATUS_MODIFIED;
-               p->parent[0].mode = new->ce_mode;
-               oidcpy(&p->parent[0].oid, &new->oid);
+               p->parent[0].mode = new_entry->ce_mode;
+               oidcpy(&p->parent[0].oid, &new_entry->oid);
                p->parent[1].status = DIFF_STATUS_MODIFIED;
-               p->parent[1].mode = old->ce_mode;
-               oidcpy(&p->parent[1].oid, &old->oid);
+               p->parent[1].mode = old_entry->ce_mode;
+               oidcpy(&p->parent[1].oid, &old_entry->oid);
                show_combined_diff(p, 2, revs->dense_combined_merges, revs);
                free(p);
                return 0;
        }
 
-       oldmode = old->ce_mode;
-       if (mode == oldmode && !oidcmp(oid, &old->oid) && !dirty_submodule &&
-           !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
+       oldmode = old_entry->ce_mode;
+       if (mode == oldmode && !oidcmp(oid, &old_entry->oid) && !dirty_submodule &&
+           !revs->diffopt.flags.find_copies_harder)
                return 0;
 
        diff_change(&revs->diffopt, oldmode, mode,
-                   &old->oid, oid, 1, !is_null_oid(oid),
-                   old->name, 0, dirty_submodule);
+                   &old_entry->oid, oid, 1, !is_null_oid(oid),
+                   old_entry->name, 0, dirty_submodule);
        return 0;
 }
 
@@ -384,8 +389,12 @@ static void do_oneway_diff(struct unpack_trees_options *o,
        struct rev_info *revs = o->unpack_data;
        int match_missing, cached;
 
-       /* i-t-a entries do not actually exist in the index */
-       if (revs->diffopt.ita_invisible_in_index &&
+       /*
+        * i-t-a entries do not actually exist in the index (if we're
+        * looking at its content)
+        */
+       if (o->index_only &&
+           revs->diffopt.ita_invisible_in_index &&
            idx && ce_intent_to_add(idx)) {
                idx = NULL;
                if (!tree)
@@ -493,7 +502,7 @@ static int diff_cache(struct rev_info *revs,
        opts.head_idx = 1;
        opts.index_only = cached;
        opts.diff_index_cached = (cached &&
-                                 !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER));
+                                 !revs->diffopt.flags.find_copies_harder);
        opts.merge = 1;
        opts.fn = oneway_diff;
        opts.unpack_data = revs;
@@ -509,6 +518,7 @@ static int diff_cache(struct rev_info *revs,
 int run_diff_index(struct rev_info *revs, int cached)
 {
        struct object_array_entry *ent;
+       uint64_t start = getnanotime();
 
        ent = revs->pending.objects;
        if (diff_cache(revs, &ent->item->oid, ent->name, cached))
@@ -518,6 +528,7 @@ int run_diff_index(struct rev_info *revs, int cached)
        diffcore_fix_diff_index(&revs->diffopt);
        diffcore_std(&revs->diffopt);
        diff_flush(&revs->diffopt);
+       trace_performance_since(start, "diff-index");
        return 0;
 }
 
@@ -534,7 +545,7 @@ int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt)
        return 0;
 }
 
-int index_differs_from(const char *def, int diff_flags,
+int index_differs_from(const char *def, const struct diff_flags *flags,
                       int ita_invisible_in_index)
 {
        struct rev_info rev;
@@ -544,11 +555,12 @@ int index_differs_from(const char *def, int diff_flags,
        memset(&opt, 0, sizeof(opt));
        opt.def = def;
        setup_revisions(0, NULL, &rev, &opt);
-       DIFF_OPT_SET(&rev.diffopt, QUICK);
-       DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS);
-       rev.diffopt.flags |= diff_flags;
+       rev.diffopt.flags.quick = 1;
+       rev.diffopt.flags.exit_with_status = 1;
+       if (flags)
+               diff_flags_or(&rev.diffopt.flags, flags);
        rev.diffopt.ita_invisible_in_index = ita_invisible_in_index;
        run_diff_index(&rev, 1);
        object_array_clear(&rev.pending);
-       return (DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0);
+       return (rev.diffopt.flags.has_changes != 0);
 }