@@ -118,6 +118,56 @@ static int module_name(int argc, const char **argv, const char *prefix)
118118
119119 return 0 ;
120120}
121+
122+ /*
123+ * Rules to sanitize configuration variables that are Ok to be passed into
124+ * submodule operations from the parent project using "-c". Should only
125+ * include keys which are both (a) safe and (b) necessary for proper
126+ * operation.
127+ */
128+ static int submodule_config_ok (const char * var )
129+ {
130+ if (starts_with (var , "credential." ) ||
131+ (starts_with (var , "http." ) && ends_with (var , ".extraheader" )))
132+ return 1 ;
133+ return 0 ;
134+ }
135+
136+ static int sanitize_submodule_config (const char * var , const char * value , void * data )
137+ {
138+ struct strbuf * out = data ;
139+
140+ if (submodule_config_ok (var )) {
141+ if (out -> len )
142+ strbuf_addch (out , ' ' );
143+
144+ if (value )
145+ sq_quotef (out , "%s=%s" , var , value );
146+ else
147+ sq_quote_buf (out , var );
148+ }
149+
150+ return 0 ;
151+ }
152+
153+ static void prepare_submodule_repo_env (struct argv_array * out )
154+ {
155+ const char * const * var ;
156+
157+ for (var = local_repo_env ; * var ; var ++ ) {
158+ if (!strcmp (* var , CONFIG_DATA_ENVIRONMENT )) {
159+ struct strbuf sanitized_config = STRBUF_INIT ;
160+ git_config_from_parameters (sanitize_submodule_config ,
161+ & sanitized_config );
162+ argv_array_pushf (out , "%s=%s" , * var , sanitized_config .buf );
163+ strbuf_release (& sanitized_config );
164+ } else {
165+ argv_array_push (out , * var );
166+ }
167+ }
168+
169+ }
170+
121171static int clone_submodule (const char * path , const char * gitdir , const char * url ,
122172 const char * depth , const char * reference , int quiet )
123173{
@@ -139,7 +189,7 @@ static int clone_submodule(const char *path, const char *gitdir, const char *url
139189 argv_array_push (& cp .args , path );
140190
141191 cp .git_cmd = 1 ;
142- cp .env = local_repo_env ;
192+ prepare_submodule_repo_env ( & cp .env_array ) ;
143193 cp .no_stdin = 1 ;
144194
145195 return run_command (& cp );
@@ -180,14 +230,18 @@ static int module_clone(int argc, const char **argv, const char *prefix)
180230
181231 const char * const git_submodule_helper_usage [] = {
182232 N_ ("git submodule--helper clone [--prefix=<path>] [--quiet] "
183- "[--reference <repository>] [--name <name>] [--url <url>] "
184- "[--depth <depth>] [--] [ <path>...] " ),
233+ "[--reference <repository>] [--name <name>] [--depth <depth>] "
234+ "--url <url> --path <path>" ),
185235 NULL
186236 };
187237
188238 argc = parse_options (argc , argv , prefix , module_clone_options ,
189239 git_submodule_helper_usage , 0 );
190240
241+ if (argc || !url || !path )
242+ usage_with_options (git_submodule_helper_usage ,
243+ module_clone_options );
244+
191245 strbuf_addf (& sb , "%s/modules/%s" , get_git_dir (), name );
192246 sm_gitdir = strbuf_detach (& sb , NULL );
193247
@@ -249,6 +303,22 @@ static int module_clone(int argc, const char **argv, const char *prefix)
249303 return 0 ;
250304}
251305
306+ static int module_sanitize_config (int argc , const char * * argv , const char * prefix )
307+ {
308+ struct strbuf sanitized_config = STRBUF_INIT ;
309+
310+ if (argc > 1 )
311+ usage (_ ("git submodule--helper sanitize-config" ));
312+
313+ git_config_from_parameters (sanitize_submodule_config , & sanitized_config );
314+ if (sanitized_config .len )
315+ printf ("%s\n" , sanitized_config .buf );
316+
317+ strbuf_release (& sanitized_config );
318+
319+ return 0 ;
320+ }
321+
252322struct cmd_struct {
253323 const char * cmd ;
254324 int (* fn )(int , const char * * , const char * );
@@ -258,6 +328,7 @@ static struct cmd_struct commands[] = {
258328 {"list" , module_list },
259329 {"name" , module_name },
260330 {"clone" , module_clone },
331+ {"sanitize-config" , module_sanitize_config },
261332};
262333
263334int cmd_submodule__helper (int argc , const char * * argv , const char * prefix )
0 commit comments