99#include "cache-tree.h"
1010#include "tree-walk.h"
1111#include "parse-options.h"
12+ #include "string-list.h"
1213#include "submodule.h"
1314
1415static const char * const builtin_rm_usage [] = {
@@ -36,10 +37,31 @@ static int get_ours_cache_pos(const char *path, int pos)
3637 return -1 ;
3738}
3839
40+ static void print_error_files (struct string_list * files_list ,
41+ const char * main_msg ,
42+ const char * hints_msg ,
43+ int * errs )
44+ {
45+ if (files_list -> nr ) {
46+ int i ;
47+ struct strbuf err_msg = STRBUF_INIT ;
48+
49+ strbuf_addstr (& err_msg , main_msg );
50+ for (i = 0 ; i < files_list -> nr ; i ++ )
51+ strbuf_addf (& err_msg ,
52+ "\n %s" ,
53+ files_list -> items [i ].string );
54+ strbuf_addstr (& err_msg , hints_msg );
55+ * errs = error ("%s" , err_msg .buf );
56+ strbuf_release (& err_msg );
57+ }
58+ }
59+
3960static int check_submodules_use_gitfiles (void )
4061{
4162 int i ;
4263 int errs = 0 ;
64+ struct string_list files = STRING_LIST_INIT_NODUP ;
4365
4466 for (i = 0 ; i < list .nr ; i ++ ) {
4567 const char * name = list .entry [i ].name ;
@@ -61,11 +83,18 @@ static int check_submodules_use_gitfiles(void)
6183 continue ;
6284
6385 if (!submodule_uses_gitfile (name ))
64- errs = error (_ ("submodule '%s' (or one of its nested "
65- "submodules) uses a .git directory\n"
66- "(use 'rm -rf' if you really want to remove "
67- "it including all of its history)" ), name );
86+ string_list_append (& files , name );
6887 }
88+ print_error_files (& files ,
89+ Q_ ("the following submodule (or one of its nested "
90+ "submodules)\n uses a .git directory:" ,
91+ "the following submodules (or one of its nested "
92+ "submodules)\n use a .git directory:" ,
93+ files .nr ),
94+ _ ("\n(use 'rm -rf' if you really want to remove "
95+ "it including all of its history)" ),
96+ & errs );
97+ string_list_clear (& files , 0 );
6998
7099 return errs ;
71100}
@@ -81,6 +110,10 @@ static int check_local_mod(unsigned char *head, int index_only)
81110 */
82111 int i , no_head ;
83112 int errs = 0 ;
113+ struct string_list files_staged = STRING_LIST_INIT_NODUP ;
114+ struct string_list files_cached = STRING_LIST_INIT_NODUP ;
115+ struct string_list files_submodule = STRING_LIST_INIT_NODUP ;
116+ struct string_list files_local = STRING_LIST_INIT_NODUP ;
84117
85118 no_head = is_null_sha1 (head );
86119 for (i = 0 ; i < list .nr ; i ++ ) {
@@ -171,29 +204,58 @@ static int check_local_mod(unsigned char *head, int index_only)
171204 */
172205 if (local_changes && staged_changes ) {
173206 if (!index_only || !(ce -> ce_flags & CE_INTENT_TO_ADD ))
174- errs = error (_ ("'%s' has staged content different "
175- "from both the file and the HEAD\n"
176- "(use -f to force removal)" ), name );
207+ string_list_append (& files_staged , name );
177208 }
178209 else if (!index_only ) {
179210 if (staged_changes )
180- errs = error (_ ("'%s' has changes staged in the index\n"
181- "(use --cached to keep the file, "
182- "or -f to force removal)" ), name );
211+ string_list_append (& files_cached , name );
183212 if (local_changes ) {
184213 if (S_ISGITLINK (ce -> ce_mode ) &&
185- !submodule_uses_gitfile (name )) {
186- errs = error (_ ("submodule '%s' (or one of its nested "
187- "submodules) uses a .git directory\n"
188- "(use 'rm -rf' if you really want to remove "
189- "it including all of its history)" ), name );
190- } else
191- errs = error (_ ("'%s' has local modifications\n"
192- "(use --cached to keep the file, "
193- "or -f to force removal)" ), name );
214+ !submodule_uses_gitfile (name ))
215+ string_list_append (& files_submodule , name );
216+ else
217+ string_list_append (& files_local , name );
194218 }
195219 }
196220 }
221+ print_error_files (& files_staged ,
222+ Q_ ("the following file has staged content different "
223+ "from both the\nfile and the HEAD:" ,
224+ "the following files have staged content different"
225+ " from both the\nfile and the HEAD:" ,
226+ files_staged .nr ),
227+ _ ("\n(use -f to force removal)" ),
228+ & errs );
229+ string_list_clear (& files_staged , 0 );
230+ print_error_files (& files_cached ,
231+ Q_ ("the following file has changes "
232+ "staged in the index:" ,
233+ "the following files have changes "
234+ "staged in the index:" , files_cached .nr ),
235+ _ ("\n(use --cached to keep the file,"
236+ " or -f to force removal)" ),
237+ & errs );
238+ string_list_clear (& files_cached , 0 );
239+ print_error_files (& files_submodule ,
240+ Q_ ("the following submodule (or one of its nested "
241+ "submodule)\nuses a .git directory:" ,
242+ "the following submodules (or one of its nested "
243+ "submodule)\nuse a .git directory:" ,
244+ files_submodule .nr ),
245+ _ ("\n(use 'rm -rf' if you really "
246+ "want to remove it including all "
247+ "of its history)" ),
248+ & errs );
249+ string_list_clear (& files_submodule , 0 );
250+ print_error_files (& files_local ,
251+ Q_ ("the following file has local modifications:" ,
252+ "the following files have local modifications:" ,
253+ files_local .nr ),
254+ _ ("\n(use --cached to keep the file,"
255+ " or -f to force removal)" ),
256+ & errs );
257+ string_list_clear (& files_local , 0 );
258+
197259 return errs ;
198260}
199261
0 commit comments