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,32 @@ 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+ if (advice_rm_hints )
55+ strbuf_addstr (& err_msg , hints_msg );
56+ * errs = error ("%s" , err_msg .buf );
57+ strbuf_release (& err_msg );
58+ }
59+ }
60+
3961static int check_submodules_use_gitfiles (void )
4062{
4163 int i ;
4264 int errs = 0 ;
65+ struct string_list files = STRING_LIST_INIT_NODUP ;
4366
4467 for (i = 0 ; i < list .nr ; i ++ ) {
4568 const char * name = list .entry [i ].name ;
@@ -61,11 +84,18 @@ static int check_submodules_use_gitfiles(void)
6184 continue ;
6285
6386 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 );
87+ string_list_append (& files , name );
6888 }
89+ print_error_files (& files ,
90+ Q_ ("the following submodule (or one of its nested "
91+ "submodules)\n uses a .git directory:" ,
92+ "the following submodules (or one of its nested "
93+ "submodules)\n use a .git directory:" ,
94+ files .nr ),
95+ _ ("\n(use 'rm -rf' if you really want to remove "
96+ "it including all of its history)" ),
97+ & errs );
98+ string_list_clear (& files , 0 );
6999
70100 return errs ;
71101}
@@ -81,6 +111,10 @@ static int check_local_mod(unsigned char *head, int index_only)
81111 */
82112 int i , no_head ;
83113 int errs = 0 ;
114+ struct string_list files_staged = STRING_LIST_INIT_NODUP ;
115+ struct string_list files_cached = STRING_LIST_INIT_NODUP ;
116+ struct string_list files_submodule = STRING_LIST_INIT_NODUP ;
117+ struct string_list files_local = STRING_LIST_INIT_NODUP ;
84118
85119 no_head = is_null_sha1 (head );
86120 for (i = 0 ; i < list .nr ; i ++ ) {
@@ -171,29 +205,58 @@ static int check_local_mod(unsigned char *head, int index_only)
171205 */
172206 if (local_changes && staged_changes ) {
173207 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 );
208+ string_list_append (& files_staged , name );
177209 }
178210 else if (!index_only ) {
179211 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 );
212+ string_list_append (& files_cached , name );
183213 if (local_changes ) {
184214 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 );
215+ !submodule_uses_gitfile (name ))
216+ string_list_append (& files_submodule , name );
217+ else
218+ string_list_append (& files_local , name );
194219 }
195220 }
196221 }
222+ print_error_files (& files_staged ,
223+ Q_ ("the following file has staged content different "
224+ "from both the\nfile and the HEAD:" ,
225+ "the following files have staged content different"
226+ " from both the\nfile and the HEAD:" ,
227+ files_staged .nr ),
228+ _ ("\n(use -f to force removal)" ),
229+ & errs );
230+ string_list_clear (& files_staged , 0 );
231+ print_error_files (& files_cached ,
232+ Q_ ("the following file has changes "
233+ "staged in the index:" ,
234+ "the following files have changes "
235+ "staged in the index:" , files_cached .nr ),
236+ _ ("\n(use --cached to keep the file,"
237+ " or -f to force removal)" ),
238+ & errs );
239+ string_list_clear (& files_cached , 0 );
240+ print_error_files (& files_submodule ,
241+ Q_ ("the following submodule (or one of its nested "
242+ "submodule)\nuses a .git directory:" ,
243+ "the following submodules (or one of its nested "
244+ "submodule)\nuse a .git directory:" ,
245+ files_submodule .nr ),
246+ _ ("\n(use 'rm -rf' if you really "
247+ "want to remove it including all "
248+ "of its history)" ),
249+ & errs );
250+ string_list_clear (& files_submodule , 0 );
251+ print_error_files (& files_local ,
252+ Q_ ("the following file has local modifications:" ,
253+ "the following files have local modifications:" ,
254+ files_local .nr ),
255+ _ ("\n(use --cached to keep the file,"
256+ " or -f to force removal)" ),
257+ & errs );
258+ string_list_clear (& files_local , 0 );
259+
197260 return errs ;
198261}
199262
0 commit comments