X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=diff-lib.c;h=d7e13cb177a3c345eb076a9ffede87c6e6afa367;hb=a004fb923d74c1d5500d493506b1462eb04cf017;hp=1c7e652a8048524e73f2f34833647d7ec1610bc9;hpb=6751e0471df1bdc4a1d5e5a3929a531c74e95aeb;p=git.git diff --git a/diff-lib.c b/diff-lib.c index 1c7e652a8..d7e13cb17 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -10,6 +10,7 @@ #include "cache-tree.h" #include "unpack-trees.h" #include "refs.h" +#include "submodule.h" /* * diff-files @@ -72,6 +73,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) unsigned int oldmode, newmode; struct cache_entry *ce = active_cache[i]; int changed; + unsigned dirty_submodule = 0; if (DIFF_OPT_TST(&revs->diffopt, QUICK) && DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES)) @@ -172,10 +174,17 @@ int run_diff_files(struct rev_info *revs, unsigned int option) if (silent_on_removed) continue; diff_addremove(&revs->diffopt, '-', ce->ce_mode, - ce->sha1, ce->name); + ce->sha1, ce->name, 0); continue; } changed = ce_match_stat(ce, &st, ce_option); + if (S_ISGITLINK(ce->ce_mode) + && !DIFF_OPT_TST(&revs->diffopt, IGNORE_SUBMODULES) + && (!changed || (revs->diffopt.output_format & DIFF_FORMAT_PATCH)) + && is_submodule_modified(ce->name)) { + changed = 1; + dirty_submodule = 1; + } if (!changed) { ce_mark_uptodate(ce); if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) @@ -185,7 +194,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) newmode = ce_mode_from_stat(ce, st.st_mode); diff_change(&revs->diffopt, oldmode, newmode, ce->sha1, (changed ? null_sha1 : ce->sha1), - ce->name); + ce->name, 0, dirty_submodule); } diffcore_std(&revs->diffopt); @@ -201,16 +210,18 @@ int run_diff_files(struct rev_info *revs, unsigned int option) static void diff_index_show_file(struct rev_info *revs, const char *prefix, struct cache_entry *ce, - const unsigned char *sha1, unsigned int mode) + const unsigned char *sha1, unsigned int mode, + unsigned dirty_submodule) { diff_addremove(&revs->diffopt, prefix[0], mode, - sha1, ce->name); + sha1, ce->name, dirty_submodule); } static int get_stat_data(struct cache_entry *ce, const unsigned char **sha1p, unsigned int *modep, - int cached, int match_missing) + int cached, int match_missing, + unsigned *dirty_submodule, struct diff_options *diffopt) { const unsigned char *sha1 = ce->sha1; unsigned int mode = ce->ce_mode; @@ -230,6 +241,13 @@ static int get_stat_data(struct cache_entry *ce, return -1; } changed = ce_match_stat(ce, &st, 0); + if (S_ISGITLINK(ce->ce_mode) + && !DIFF_OPT_TST(diffopt, IGNORE_SUBMODULES) + && (!changed || (diffopt->output_format & DIFF_FORMAT_PATCH)) + && is_submodule_modified(ce->name)) { + changed = 1; + *dirty_submodule = 1; + } if (changed) { mode = ce_mode_from_stat(ce, st.st_mode); sha1 = null_sha1; @@ -247,15 +265,17 @@ static void show_new_file(struct rev_info *revs, { const unsigned char *sha1; unsigned int mode; + unsigned dirty_submodule = 0; /* * New file in the index: it might actually be different in * the working copy. */ - if (get_stat_data(new, &sha1, &mode, cached, match_missing) < 0) + if (get_stat_data(new, &sha1, &mode, cached, match_missing, + &dirty_submodule, &revs->diffopt) < 0) return; - diff_index_show_file(revs, "+", new, sha1, mode); + diff_index_show_file(revs, "+", new, sha1, mode, dirty_submodule); } static int show_modified(struct rev_info *revs, @@ -266,11 +286,13 @@ static int show_modified(struct rev_info *revs, { unsigned int mode, oldmode; const unsigned char *sha1; + unsigned dirty_submodule = 0; - if (get_stat_data(new, &sha1, &mode, cached, match_missing) < 0) { + if (get_stat_data(new, &sha1, &mode, cached, match_missing, + &dirty_submodule, &revs->diffopt) < 0) { if (report_missing) diff_index_show_file(revs, "-", old, - old->sha1, old->ce_mode); + old->sha1, old->ce_mode, 0); return -1; } @@ -305,7 +327,7 @@ static int show_modified(struct rev_info *revs, return 0; diff_change(&revs->diffopt, oldmode, mode, - old->sha1, sha1, old->name); + old->sha1, sha1, old->name, 0, dirty_submodule); return 0; } @@ -352,7 +374,7 @@ static void do_oneway_diff(struct unpack_trees_options *o, * Something removed from the tree? */ if (!idx) { - diff_index_show_file(revs, "-", tree, tree->sha1, tree->ce_mode); + diff_index_show_file(revs, "-", tree, tree->sha1, tree->ce_mode, 0); return; } @@ -360,21 +382,6 @@ static void do_oneway_diff(struct unpack_trees_options *o, show_modified(revs, tree, idx, 1, cached, match_missing); } -static inline void skip_same_name(struct cache_entry *ce, struct unpack_trees_options *o) -{ - int len = ce_namelen(ce); - const struct index_state *index = o->src_index; - - while (o->pos < index->cache_nr) { - struct cache_entry *next = index->cache[o->pos]; - if (len != ce_namelen(next)) - break; - if (memcmp(ce->name, next->name, len)) - break; - o->pos++; - } -} - /* * The unpack_trees() interface is designed for merging, so * the different source entries are designed primarily for @@ -396,9 +403,6 @@ static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o) struct cache_entry *tree = src[1]; struct rev_info *revs = o->unpack_data; - if (idx && ce_stage(idx)) - skip_same_name(idx, o); - /* * Unpack-trees generates a DF/conflict entry if * there was a directory in the index and a tree @@ -444,6 +448,7 @@ int run_diff_index(struct rev_info *revs, int cached) exit(128); diff_set_mnemonic_prefix(&revs->diffopt, "c/", cached ? "i/" : "w/"); + diffcore_fix_diff_index(&revs->diffopt); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); return 0;