@@ -55,6 +55,27 @@ static int check_removed(const struct cache_entry *ce, struct stat *st)
5555 return 0 ;
5656}
5757
58+ /*
59+ * Has a file changed or has a submodule new commits or a dirty work tree?
60+ *
61+ * Return 1 when changes are detected, 0 otherwise. If the DIRTY_SUBMODULES
62+ * option is set, the caller does not only want to know if a submodule is
63+ * modified at all but wants to know all the conditions that are met (new
64+ * commits, untracked content and/or modified content).
65+ */
66+ static int match_stat_with_submodule (struct diff_options * diffopt ,
67+ struct cache_entry * ce , struct stat * st ,
68+ unsigned ce_option , unsigned * dirty_submodule )
69+ {
70+ int changed = ce_match_stat (ce , st , ce_option );
71+ if (S_ISGITLINK (ce -> ce_mode )
72+ && !DIFF_OPT_TST (diffopt , IGNORE_SUBMODULES )
73+ && (!changed || DIFF_OPT_TST (diffopt , DIRTY_SUBMODULES ))) {
74+ * dirty_submodule = is_submodule_modified (ce -> name , DIFF_OPT_TST (diffopt , IGNORE_UNTRACKED_IN_SUBMODULES ));
75+ }
76+ return changed ;
77+ }
78+
5879int run_diff_files (struct rev_info * revs , unsigned int option )
5980{
6081 int entries , i ;
@@ -177,15 +198,9 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
177198 ce -> sha1 , ce -> name , 0 );
178199 continue ;
179200 }
180- changed = ce_match_stat (ce , & st , ce_option );
181- if (S_ISGITLINK (ce -> ce_mode )
182- && !DIFF_OPT_TST (& revs -> diffopt , IGNORE_SUBMODULES )
183- && (!changed || (revs -> diffopt .output_format & DIFF_FORMAT_PATCH ))
184- && is_submodule_modified (ce -> name )) {
185- changed = 1 ;
186- dirty_submodule = 1 ;
187- }
188- if (!changed ) {
201+ changed = match_stat_with_submodule (& revs -> diffopt , ce , & st ,
202+ ce_option , & dirty_submodule );
203+ if (!changed && !dirty_submodule ) {
189204 ce_mark_uptodate (ce );
190205 if (!DIFF_OPT_TST (& revs -> diffopt , FIND_COPIES_HARDER ))
191206 continue ;
@@ -240,14 +255,8 @@ static int get_stat_data(struct cache_entry *ce,
240255 }
241256 return -1 ;
242257 }
243- changed = ce_match_stat (ce , & st , 0 );
244- if (S_ISGITLINK (ce -> ce_mode )
245- && !DIFF_OPT_TST (diffopt , IGNORE_SUBMODULES )
246- && (!changed || (diffopt -> output_format & DIFF_FORMAT_PATCH ))
247- && is_submodule_modified (ce -> name )) {
248- changed = 1 ;
249- * dirty_submodule = 1 ;
250- }
258+ changed = match_stat_with_submodule (diffopt , ce , & st ,
259+ 0 , dirty_submodule );
251260 if (changed ) {
252261 mode = ce_mode_from_stat (ce , st .st_mode );
253262 sha1 = null_sha1 ;
@@ -322,7 +331,7 @@ static int show_modified(struct rev_info *revs,
322331 }
323332
324333 oldmode = old -> ce_mode ;
325- if (mode == oldmode && !hashcmp (sha1 , old -> sha1 ) &&
334+ if (mode == oldmode && !hashcmp (sha1 , old -> sha1 ) && ! dirty_submodule &&
326335 !DIFF_OPT_TST (& revs -> diffopt , FIND_COPIES_HARDER ))
327336 return 0 ;
328337
0 commit comments