14
14
#include "resolve-undo.h"
15
15
#include "string-list.h"
16
16
#include "pathspec.h"
17
+ #include "run-command.h"
17
18
18
19
static int abbrev ;
19
20
static int show_deleted ;
@@ -28,6 +29,8 @@ static int show_valid_bit;
28
29
static int line_terminator = '\n' ;
29
30
static int debug_mode ;
30
31
static int show_eol ;
32
+ static const char * submodule_prefix ;
33
+ static int recurse_submodules ;
31
34
32
35
static const char * prefix ;
33
36
static int max_prefix_len ;
@@ -67,6 +70,21 @@ static void write_eolinfo(const struct cache_entry *ce, const char *path)
67
70
68
71
static void write_name (const char * name )
69
72
{
73
+ /*
74
+ * NEEDSWORK: To make this thread-safe, full_name would have to be owned
75
+ * by the caller.
76
+ *
77
+ * full_name get reused across output lines to minimize the allocation
78
+ * churn.
79
+ */
80
+ static struct strbuf full_name = STRBUF_INIT ;
81
+ if (submodule_prefix && * submodule_prefix ) {
82
+ strbuf_reset (& full_name );
83
+ strbuf_addstr (& full_name , submodule_prefix );
84
+ strbuf_addstr (& full_name , name );
85
+ name = full_name .buf ;
86
+ }
87
+
70
88
/*
71
89
* With "--full-name", prefix_len=0; this caller needs to pass
72
90
* an empty string in that case (a NULL is good for "").
@@ -152,6 +170,26 @@ static void show_killed_files(struct dir_struct *dir)
152
170
}
153
171
}
154
172
173
+ /**
174
+ * Recursively call ls-files on a submodule
175
+ */
176
+ static void show_gitlink (const struct cache_entry * ce )
177
+ {
178
+ struct child_process cp = CHILD_PROCESS_INIT ;
179
+ int status ;
180
+
181
+ argv_array_push (& cp .args , "ls-files" );
182
+ argv_array_push (& cp .args , "--recurse-submodules" );
183
+ argv_array_pushf (& cp .args , "--submodule-prefix=%s%s/" ,
184
+ submodule_prefix ? submodule_prefix : "" ,
185
+ ce -> name );
186
+ cp .git_cmd = 1 ;
187
+ cp .dir = ce -> name ;
188
+ status = run_command (& cp );
189
+ if (status )
190
+ exit (status );
191
+ }
192
+
155
193
static void show_ce_entry (const char * tag , const struct cache_entry * ce )
156
194
{
157
195
int len = max_prefix_len ;
@@ -163,6 +201,10 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce)
163
201
len , ps_matched ,
164
202
S_ISDIR (ce -> ce_mode ) || S_ISGITLINK (ce -> ce_mode )))
165
203
return ;
204
+ if (recurse_submodules && S_ISGITLINK (ce -> ce_mode )) {
205
+ show_gitlink (ce );
206
+ return ;
207
+ }
166
208
167
209
if (tag && * tag && show_valid_bit &&
168
210
(ce -> ce_flags & CE_VALID )) {
@@ -468,6 +510,10 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
468
510
{ OPTION_SET_INT , 0 , "full-name" , & prefix_len , NULL ,
469
511
N_ ("make the output relative to the project top directory" ),
470
512
PARSE_OPT_NOARG | PARSE_OPT_NONEG , NULL },
513
+ OPT_STRING (0 , "submodule-prefix" , & submodule_prefix ,
514
+ N_ ("path" ), N_ ("prepend <path> to each file" )),
515
+ OPT_BOOL (0 , "recurse-submodules" , & recurse_submodules ,
516
+ N_ ("recurse through submodules" )),
471
517
OPT_BOOL (0 , "error-unmatch" , & error_unmatch ,
472
518
N_ ("if any <file> is not in the index, treat this as an error" )),
473
519
OPT_STRING (0 , "with-tree" , & with_tree , N_ ("tree-ish" ),
@@ -519,6 +565,21 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
519
565
if (require_work_tree && !is_inside_work_tree ())
520
566
setup_work_tree ();
521
567
568
+ if (recurse_submodules &&
569
+ (show_stage || show_deleted || show_others || show_unmerged ||
570
+ show_killed || show_modified || show_resolve_undo ||
571
+ show_valid_bit || show_tag || show_eol ))
572
+ die ("ls-files --recurse-submodules can only be used in "
573
+ "--cached mode" );
574
+
575
+ if (recurse_submodules && error_unmatch )
576
+ die ("ls-files --recurse-submodules does not support "
577
+ "--error-unmatch" );
578
+
579
+ if (recurse_submodules && argc )
580
+ die ("ls-files --recurse-submodules does not support path "
581
+ "arguments" );
582
+
522
583
parse_pathspec (& pathspec , 0 ,
523
584
PATHSPEC_PREFER_CWD |
524
585
PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP ,
0 commit comments