Raw
1 #define USE_THE_REPOSITORY_VARIABLE
2 #define DISABLE_SIGN_COMPARE_WARNINGS
3
4 #include "git-compat-util.h"
5 #include "dir.h"
6 #include "environment.h"
7 #include "gettext.h"
8 #include "hex.h"
9 #include "path.h"
10 #include "repository.h"
11 #include "config.h"
12 #include "submodule-config.h"
13 #include "submodule.h"
14 #include "strbuf.h"
15 #include "object-name.h"
16 #include "odb.h"
17 #include "odb/source.h"
18 #include "parse-options.h"
19 #include "thread-utils.h"
20 #include "tree-walk.h"
21 #include "url.h"
22 #include "urlmatch.h"
23
24 /*
25 * submodule cache lookup structure
26 * There is one shared set of 'struct submodule' entries which can be
27 * looked up by their sha1 blob id of the .gitmodules file and either
28 * using path or name as key.
29 * for_path stores submodule entries with path as key
30 * for_name stores submodule entries with name as key
31 */
32 struct submodule_cache {
33 struct hashmap for_path;
34 struct hashmap for_name;
35 unsigned initialized:1;
36 unsigned gitmodules_read:1;
37 };
38
39 /*
40 * thin wrapper struct needed to insert 'struct submodule' entries to
41 * the hashmap
42 */
43 struct submodule_entry {
44 struct hashmap_entry ent;
45 struct submodule *config;
46 };
47
48 enum lookup_type {
49 lookup_name,
50 lookup_path
51 };
52
53 static int config_path_cmp(const void *cmp_data UNUSED,
54 const struct hashmap_entry *eptr,
55 const struct hashmap_entry *entry_or_key,
56 const void *keydata UNUSED)
57 {
58 const struct submodule_entry *a, *b;
59
60 a = container_of(eptr, const struct submodule_entry, ent);
61 b = container_of(entry_or_key, const struct submodule_entry, ent);
62
63 return strcmp(a->config->path, b->config->path) ||
64 !oideq(&a->config->gitmodules_oid, &b->config->gitmodules_oid);
65 }
66
67 static int config_name_cmp(const void *cmp_data UNUSED,
68 const struct hashmap_entry *eptr,
69 const struct hashmap_entry *entry_or_key,
70 const void *keydata UNUSED)
71 {
72 const struct submodule_entry *a, *b;
73
74 a = container_of(eptr, const struct submodule_entry, ent);
75 b = container_of(entry_or_key, const struct submodule_entry, ent);
76
77 return strcmp(a->config->name, b->config->name) ||
78 !oideq(&a->config->gitmodules_oid, &b->config->gitmodules_oid);
79 }
80
81 static struct submodule_cache *submodule_cache_alloc(void)
82 {
83 return xcalloc(1, sizeof(struct submodule_cache));
84 }
85
86 static void submodule_cache_init(struct submodule_cache *cache)
87 {
88 hashmap_init(&cache->for_path, config_path_cmp, NULL, 0);
89 hashmap_init(&cache->for_name, config_name_cmp, NULL, 0);
90 cache->initialized = 1;
91 }
92
93 static void free_one_config(struct submodule_entry *entry)
94 {
95 free((void *) entry->config->path);
96 free((void *) entry->config->name);
97 free((void *) entry->config->branch);
98 free((void *) entry->config->url);
99 free((void *) entry->config->ignore);
100 submodule_update_strategy_release(&entry->config->update_strategy);
101 free(entry->config);
102 }
103
104 static void submodule_cache_clear(struct submodule_cache *cache)
105 {
106 struct hashmap_iter iter;
107 struct submodule_entry *entry;
108
109 if (!cache->initialized)
110 return;
111
112 /*
113 * We iterate over the name hash here to be symmetric with the
114 * allocation of struct submodule entries. Each is allocated by
115 * their .gitmodules blob sha1 and submodule name.
116 */
117 hashmap_for_each_entry(&cache->for_name, &iter, entry,
118 ent /* member name */)
119 free_one_config(entry);
120
121 hashmap_clear_and_free(&cache->for_path, struct submodule_entry, ent);
122 hashmap_clear_and_free(&cache->for_name, struct submodule_entry, ent);
123 cache->initialized = 0;
124 cache->gitmodules_read = 0;
125 }
126
127 void submodule_cache_free(struct submodule_cache *cache)
128 {
129 submodule_cache_clear(cache);
130 free(cache);
131 }
132
133 static unsigned int hash_oid_string(const struct object_id *oid,
134 const char *string)
135 {
136 return memhash(oid->hash, the_hash_algo->rawsz) + strhash(string);
137 }
138
139 static void cache_put_path(struct submodule_cache *cache,
140 struct submodule *submodule)
141 {
142 unsigned int hash = hash_oid_string(&submodule->gitmodules_oid,
143 submodule->path);
144 struct submodule_entry *e = xmalloc(sizeof(*e));
145 hashmap_entry_init(&e->ent, hash);
146 e->config = submodule;
147 hashmap_put(&cache->for_path, &e->ent);
148 }
149
150 static void cache_remove_path(struct submodule_cache *cache,
151 struct submodule *submodule)
152 {
153 unsigned int hash = hash_oid_string(&submodule->gitmodules_oid,
154 submodule->path);
155 struct submodule_entry e;
156 struct submodule_entry *removed;
157 hashmap_entry_init(&e.ent, hash);
158 e.config = submodule;
159 removed = hashmap_remove_entry(&cache->for_path, &e, ent, NULL);
160 free(removed);
161 }
162
163 static void cache_add(struct submodule_cache *cache,
164 struct submodule *submodule)
165 {
166 unsigned int hash = hash_oid_string(&submodule->gitmodules_oid,
167 submodule->name);
168 struct submodule_entry *e = xmalloc(sizeof(*e));
169 hashmap_entry_init(&e->ent, hash);
170 e->config = submodule;
171 hashmap_add(&cache->for_name, &e->ent);
172 }
173
174 static const struct submodule *cache_lookup_path(struct submodule_cache *cache,
175 const struct object_id *gitmodules_oid, const char *path)
176 {
177 struct submodule_entry *entry;
178 unsigned int hash = hash_oid_string(gitmodules_oid, path);
179 struct submodule_entry key;
180 struct submodule key_config;
181
182 oidcpy(&key_config.gitmodules_oid, gitmodules_oid);
183 key_config.path = path;
184
185 hashmap_entry_init(&key.ent, hash);
186 key.config = &key_config;
187
188 entry = hashmap_get_entry(&cache->for_path, &key, ent, NULL);
189 if (entry)
190 return entry->config;
191 return NULL;
192 }
193
194 static struct submodule *cache_lookup_name(struct submodule_cache *cache,
195 const struct object_id *gitmodules_oid, const char *name)
196 {
197 struct submodule_entry *entry;
198 unsigned int hash = hash_oid_string(gitmodules_oid, name);
199 struct submodule_entry key;
200 struct submodule key_config;
201
202 oidcpy(&key_config.gitmodules_oid, gitmodules_oid);
203 key_config.name = name;
204
205 hashmap_entry_init(&key.ent, hash);
206 key.config = &key_config;
207
208 entry = hashmap_get_entry(&cache->for_name, &key, ent, NULL);
209 if (entry)
210 return entry->config;
211 return NULL;
212 }
213
214 int check_submodule_name(const char *name)
215 {
216 /* Disallow empty names */
217 if (!*name)
218 return -1;
219
220 /*
221 * Look for '..' as a path component. Check is_xplatform_dir_sep() as
222 * separators rather than is_dir_sep(), because we want the name rules
223 * to be consistent across platforms.
224 */
225 goto in_component; /* always start inside component */
226 while (*name) {
227 char c = *name++;
228 if (is_xplatform_dir_sep(c)) {
229 in_component:
230 if (name[0] == '.' && name[1] == '.' &&
231 (!name[2] || is_xplatform_dir_sep(name[2])))
232 return -1;
233 }
234 }
235
236 return 0;
237 }
238
239 static int submodule_url_is_relative(const char *url)
240 {
241 return starts_with_dot_slash(url) || starts_with_dot_dot_slash(url);
242 }
243
244 /*
245 * Count directory components that a relative submodule URL should chop
246 * from the remote_url it is to be resolved against.
247 *
248 * In other words, this counts "../" components at the start of a
249 * submodule URL.
250 *
251 * Returns the number of directory components to chop and writes a
252 * pointer to the next character of url after all leading "./" and
253 * "../" components to out.
254 */
255 static int count_leading_dotdots(const char *url, const char **out)
256 {
257 int result = 0;
258 while (1) {
259 if (starts_with_dot_dot_slash(url)) {
260 result++;
261 url += strlen("../");
262 continue;
263 }
264 if (starts_with_dot_slash(url)) {
265 url += strlen("./");
266 continue;
267 }
268 *out = url;
269 return result;
270 }
271 }
272 /*
273 * Check whether a transport is implemented by git-remote-curl.
274 *
275 * If it is, returns 1 and writes the URL that would be passed to
276 * git-remote-curl to the "out" parameter.
277 *
278 * Otherwise, returns 0 and leaves "out" untouched.
279 *
280 * Examples:
281 * http::https://example.com/repo.git -> 1, https://example.com/repo.git
282 * https://example.com/repo.git -> 1, https://example.com/repo.git
283 * git://example.com/repo.git -> 0
284 *
285 * This is for use in checking for previously exploitable bugs that
286 * required a submodule URL to be passed to git-remote-curl.
287 */
288 static int url_to_curl_url(const char *url, const char **out)
289 {
290 /*
291 * We don't need to check for case-aliases, "http.exe", and so
292 * on because in the default configuration, is_transport_allowed
293 * prevents URLs with those schemes from being cloned
294 * automatically.
295 */
296 if (skip_prefix(url, "http::", out) ||
297 skip_prefix(url, "https::", out) ||
298 skip_prefix(url, "ftp::", out) ||
299 skip_prefix(url, "ftps::", out))
300 return 1;
301 if (starts_with(url, "http://") ||
302 starts_with(url, "https://") ||
303 starts_with(url, "ftp://") ||
304 starts_with(url, "ftps://")) {
305 *out = url;
306 return 1;
307 }
308 return 0;
309 }
310
311 int check_submodule_url(const char *url)
312 {
313 const char *curl_url;
314
315 if (looks_like_command_line_option(url))
316 return -1;
317
318 if (submodule_url_is_relative(url) || starts_with(url, "git://")) {
319 char *decoded;
320 const char *next;
321 int has_nl;
322
323 /*
324 * This could be appended to an http URL and url-decoded;
325 * check for malicious characters.
326 */
327 decoded = url_decode(url);
328 has_nl = !!strchr(decoded, '\n');
329
330 free(decoded);
331 if (has_nl)
332 return -1;
333
334 /*
335 * URLs which escape their root via "../" can overwrite
336 * the host field and previous components, resolving to
337 * URLs like https::example.com/submodule.git and
338 * https:///example.com/submodule.git that were
339 * susceptible to CVE-2020-11008.
340 */
341 if (count_leading_dotdots(url, &next) > 0 &&
342 (*next == ':' || *next == '/'))
343 return -1;
344 }
345
346 else if (url_to_curl_url(url, &curl_url)) {
347 int ret = 0;
348 char *normalized = url_normalize(curl_url, NULL);
349 if (normalized) {
350 char *decoded = url_decode(normalized);
351 if (strchr(decoded, '\n'))
352 ret = -1;
353 free(normalized);
354 free(decoded);
355 } else {
356 ret = -1;
357 }
358
359 return ret;
360 }
361
362 return 0;
363 }
364
365 static int name_and_item_from_var(const char *var, struct strbuf *name,
366 struct strbuf *item)
367 {
368 const char *subsection, *key;
369 size_t subsection_len;
370 int parse;
371 parse = parse_config_key(var, "submodule", &subsection,
372 &subsection_len, &key);
373 if (parse < 0 || !subsection)
374 return 0;
375
376 strbuf_add(name, subsection, subsection_len);
377 if (check_submodule_name(name->buf) < 0) {
378 warning(_("ignoring suspicious submodule name: %s"), name->buf);
379 strbuf_release(name);
380 return 0;
381 }
382
383 strbuf_addstr(item, key);
384
385 return 1;
386 }
387
388 static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache,
389 const struct object_id *gitmodules_oid, const char *name)
390 {
391 struct submodule *submodule;
392 struct strbuf name_buf = STRBUF_INIT;
393
394 submodule = cache_lookup_name(cache, gitmodules_oid, name);
395 if (submodule)
396 return submodule;
397
398 submodule = xmalloc(sizeof(*submodule));
399
400 strbuf_addstr(&name_buf, name);
401 submodule->name = strbuf_detach(&name_buf, NULL);
402
403 submodule->path = NULL;
404 submodule->url = NULL;
405 submodule->update_strategy.type = SM_UPDATE_UNSPECIFIED;
406 submodule->update_strategy.command = NULL;
407 submodule->fetch_recurse = RECURSE_SUBMODULES_NONE;
408 submodule->ignore = NULL;
409 submodule->branch = NULL;
410 submodule->recommend_shallow = -1;
411
412 oidcpy(&submodule->gitmodules_oid, gitmodules_oid);
413
414 cache_add(cache, submodule);
415
416 return submodule;
417 }
418
419 static int parse_fetch_recurse(const char *opt, const char *arg,
420 int die_on_error)
421 {
422 switch (git_parse_maybe_bool(arg)) {
423 case 1:
424 return RECURSE_SUBMODULES_ON;
425 case 0:
426 return RECURSE_SUBMODULES_OFF;
427 default:
428 if (!strcmp(arg, "on-demand"))
429 return RECURSE_SUBMODULES_ON_DEMAND;
430 /*
431 * Please update $__git_fetch_recurse_submodules in
432 * git-completion.bash when you add new options.
433 */
434 if (die_on_error)
435 die("bad %s argument: %s", opt, arg);
436 else
437 return RECURSE_SUBMODULES_ERROR;
438 }
439 }
440
441 int parse_submodule_fetchjobs(const char *var, const char *value,
442 const struct key_value_info *kvi)
443 {
444 int fetchjobs = git_config_int(var, value, kvi);
445 if (fetchjobs < 0)
446 die(_("negative values not allowed for submodule.fetchJobs"));
447 if (!fetchjobs)
448 fetchjobs = online_cpus();
449 return fetchjobs;
450 }
451
452 int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg)
453 {
454 return parse_fetch_recurse(opt, arg, 1);
455 }
456
457 int option_fetch_parse_recurse_submodules(const struct option *opt,
458 const char *arg, int unset)
459 {
460 int *v;
461
462 if (!opt->value)
463 return -1;
464
465 v = opt->value;
466
467 if (unset) {
468 *v = RECURSE_SUBMODULES_OFF;
469 } else {
470 if (arg)
471 *v = parse_fetch_recurse_submodules_arg(opt->long_name, arg);
472 else
473 *v = RECURSE_SUBMODULES_ON;
474 }
475 return 0;
476 }
477
478 static int parse_update_recurse(const char *opt, const char *arg,
479 int die_on_error)
480 {
481 switch (git_parse_maybe_bool(arg)) {
482 case 1:
483 return RECURSE_SUBMODULES_ON;
484 case 0:
485 return RECURSE_SUBMODULES_OFF;
486 default:
487 if (die_on_error)
488 die("bad %s argument: %s", opt, arg);
489 return RECURSE_SUBMODULES_ERROR;
490 }
491 }
492
493 int parse_update_recurse_submodules_arg(const char *opt, const char *arg)
494 {
495 return parse_update_recurse(opt, arg, 1);
496 }
497
498 static int parse_push_recurse(const char *opt, const char *arg,
499 int die_on_error)
500 {
501 switch (git_parse_maybe_bool(arg)) {
502 case 1:
503 /* There's no simple "on" value when pushing */
504 if (die_on_error)
505 die("bad %s argument: %s", opt, arg);
506 else
507 return RECURSE_SUBMODULES_ERROR;
508 case 0:
509 return RECURSE_SUBMODULES_OFF;
510 default:
511 if (!strcmp(arg, "on-demand"))
512 return RECURSE_SUBMODULES_ON_DEMAND;
513 else if (!strcmp(arg, "check"))
514 return RECURSE_SUBMODULES_CHECK;
515 else if (!strcmp(arg, "only"))
516 return RECURSE_SUBMODULES_ONLY;
517 /*
518 * Please update $__git_push_recurse_submodules in
519 * git-completion.bash when you add new modes.
520 */
521 else if (die_on_error)
522 die("bad %s argument: %s", opt, arg);
523 else
524 return RECURSE_SUBMODULES_ERROR;
525 }
526 }
527
528 int parse_push_recurse_submodules_arg(const char *opt, const char *arg)
529 {
530 return parse_push_recurse(opt, arg, 1);
531 }
532
533 static void warn_multiple_config(const struct object_id *treeish_name,
534 const char *name, const char *option)
535 {
536 const char *commit_string = "WORKTREE";
537 if (treeish_name)
538 commit_string = oid_to_hex(treeish_name);
539 warning("%s:.gitmodules, multiple configurations found for "
540 "'submodule.%s.%s'. Skipping second one!",
541 commit_string, name, option);
542 }
543
544 static void warn_command_line_option(const char *var, const char *value)
545 {
546 warning(_("ignoring '%s' which may be interpreted as"
547 " a command-line option: %s"), var, value);
548 }
549
550 struct parse_config_parameter {
551 struct submodule_cache *cache;
552 const struct object_id *treeish_name;
553 const struct object_id *gitmodules_oid;
554 int overwrite;
555 };
556
557 /*
558 * Parse a config item from .gitmodules.
559 *
560 * This does not handle submodule-related configuration from the main
561 * config store (.git/config, etc). Callers are responsible for
562 * checking for overrides in the main config store when appropriate.
563 */
564 static int parse_config(const char *var, const char *value,
565 const struct config_context *ctx UNUSED, void *data)
566 {
567 struct parse_config_parameter *me = data;
568 struct submodule *submodule;
569 struct strbuf name = STRBUF_INIT, item = STRBUF_INIT;
570 int ret = 0;
571
572 /* this also ensures that we only parse submodule entries */
573 if (!name_and_item_from_var(var, &name, &item))
574 return 0;
575
576 submodule = lookup_or_create_by_name(me->cache,
577 me->gitmodules_oid,
578 name.buf);
579
580 if (!strcmp(item.buf, "path")) {
581 if (!value)
582 ret = config_error_nonbool(var);
583 else if (looks_like_command_line_option(value))
584 warn_command_line_option(var, value);
585 else if (!me->overwrite && submodule->path)
586 warn_multiple_config(me->treeish_name, submodule->name,
587 "path");
588 else {
589 if (submodule->path)
590 cache_remove_path(me->cache, submodule);
591 free((void *) submodule->path);
592 submodule->path = xstrdup(value);
593 cache_put_path(me->cache, submodule);
594 }
595 } else if (!strcmp(item.buf, "fetchrecursesubmodules")) {
596 /* when parsing worktree configurations we can die early */
597 int die_on_error = is_null_oid(me->gitmodules_oid);
598 if (!me->overwrite &&
599 submodule->fetch_recurse != RECURSE_SUBMODULES_NONE)
600 warn_multiple_config(me->treeish_name, submodule->name,
601 "fetchrecursesubmodules");
602 else
603 submodule->fetch_recurse = parse_fetch_recurse(
604 var, value,
605 die_on_error);
606 } else if (!strcmp(item.buf, "ignore")) {
607 if (!value)
608 ret = config_error_nonbool(var);
609 else if (!me->overwrite && submodule->ignore)
610 warn_multiple_config(me->treeish_name, submodule->name,
611 "ignore");
612 else if (strcmp(value, "untracked") &&
613 strcmp(value, "dirty") &&
614 strcmp(value, "all") &&
615 strcmp(value, "none"))
616 warning("Invalid parameter '%s' for config option "
617 "'submodule.%s.ignore'", value, name.buf);
618 else {
619 free((void *) submodule->ignore);
620 submodule->ignore = xstrdup(value);
621 }
622 } else if (!strcmp(item.buf, "url")) {
623 if (!value) {
624 ret = config_error_nonbool(var);
625 } else if (looks_like_command_line_option(value)) {
626 warn_command_line_option(var, value);
627 } else if (!me->overwrite && submodule->url) {
628 warn_multiple_config(me->treeish_name, submodule->name,
629 "url");
630 } else {
631 free((void *) submodule->url);
632 submodule->url = xstrdup(value);
633 }
634 } else if (!strcmp(item.buf, "update")) {
635 if (!value)
636 ret = config_error_nonbool(var);
637 else if (!me->overwrite &&
638 submodule->update_strategy.type != SM_UPDATE_UNSPECIFIED)
639 warn_multiple_config(me->treeish_name, submodule->name,
640 "update");
641 else if (parse_submodule_update_strategy(value,
642 &submodule->update_strategy) < 0 ||
643 submodule->update_strategy.type == SM_UPDATE_COMMAND)
644 die(_("invalid value for '%s'"), var);
645 } else if (!strcmp(item.buf, "shallow")) {
646 if (!me->overwrite && submodule->recommend_shallow != -1)
647 warn_multiple_config(me->treeish_name, submodule->name,
648 "shallow");
649 else
650 submodule->recommend_shallow =
651 git_config_bool(var, value);
652 } else if (!strcmp(item.buf, "branch")) {
653 if (!value)
654 ret = config_error_nonbool(var);
655 else if (!me->overwrite && submodule->branch)
656 warn_multiple_config(me->treeish_name, submodule->name,
657 "branch");
658 else {
659 free((void *)submodule->branch);
660 submodule->branch = xstrdup(value);
661 }
662 }
663
664 strbuf_release(&name);
665 strbuf_release(&item);
666
667 return ret;
668 }
669
670 static int gitmodule_oid_from_commit(const struct object_id *treeish_name,
671 struct object_id *gitmodules_oid,
672 struct strbuf *rev)
673 {
674 int ret = 0;
675
676 if (is_null_oid(treeish_name)) {
677 oidclr(gitmodules_oid, the_repository->hash_algo);
678 return 1;
679 }
680
681 strbuf_addf(rev, "%s:.gitmodules", oid_to_hex(treeish_name));
682 if (repo_get_oid(the_repository, rev->buf, gitmodules_oid) >= 0)
683 ret = 1;
684
685 return ret;
686 }
687
688 /* This does a lookup of a submodule configuration by name or by path
689 * (key) with on-demand reading of the appropriate .gitmodules from
690 * revisions.
691 */
692 static const struct submodule *config_from(struct submodule_cache *cache,
693 const struct object_id *treeish_name, const char *key,
694 enum lookup_type lookup_type)
695 {
696 struct strbuf rev = STRBUF_INIT;
697 size_t config_size;
698 char *config = NULL;
699 struct object_id oid;
700 enum object_type type;
701 const struct submodule *submodule = NULL;
702 struct parse_config_parameter parameter;
703
704 /*
705 * If any parameter except the cache is a NULL pointer just
706 * return the first submodule. Can be used to check whether
707 * there are any submodules parsed.
708 */
709 if (!treeish_name || !key) {
710 struct hashmap_iter iter;
711 struct submodule_entry *entry;
712
713 entry = hashmap_iter_first_entry(&cache->for_name, &iter,
714 struct submodule_entry,
715 ent /* member name */);
716 if (!entry)
717 return NULL;
718 return entry->config;
719 }
720
721 if (!gitmodule_oid_from_commit(treeish_name, &oid, &rev))
722 goto out;
723
724 switch (lookup_type) {
725 case lookup_name:
726 submodule = cache_lookup_name(cache, &oid, key);
727 break;
728 case lookup_path:
729 submodule = cache_lookup_path(cache, &oid, key);
730 break;
731 }
732 if (submodule)
733 goto out;
734
735 config = odb_read_object(the_repository->objects, &oid,
736 &type, &config_size);
737 if (!config || type != OBJ_BLOB)
738 goto out;
739
740 /* fill the submodule config into the cache */
741 parameter.cache = cache;
742 parameter.treeish_name = treeish_name;
743 parameter.gitmodules_oid = &oid;
744 parameter.overwrite = 0;
745 git_config_from_mem(parse_config, CONFIG_ORIGIN_SUBMODULE_BLOB, rev.buf,
746 config, config_size, &parameter, CONFIG_SCOPE_UNKNOWN, NULL);
747 strbuf_release(&rev);
748 free(config);
749
750 switch (lookup_type) {
751 case lookup_name:
752 return cache_lookup_name(cache, &oid, key);
753 case lookup_path:
754 return cache_lookup_path(cache, &oid, key);
755 default:
756 return NULL;
757 }
758
759 out:
760 strbuf_release(&rev);
761 free(config);
762 return submodule;
763 }
764
765 static void submodule_cache_check_init(struct repository *repo)
766 {
767 if (repo->submodule_cache && repo->submodule_cache->initialized)
768 return;
769
770 if (!repo->submodule_cache)
771 repo->submodule_cache = submodule_cache_alloc();
772
773 submodule_cache_init(repo->submodule_cache);
774 }
775
776 /*
777 * Note: This function is private for a reason, the '.gitmodules' file should
778 * not be used as a mechanism to retrieve arbitrary configuration stored in
779 * the repository.
780 *
781 * Runs the provided config function on the '.gitmodules' file found in the
782 * working directory.
783 */
784 static void config_from_gitmodules(config_fn_t fn, struct repository *repo, void *data)
785 {
786 if (repo->worktree) {
787 struct git_config_source config_source = {
788 0, .scope = CONFIG_SCOPE_SUBMODULE
789 };
790 const struct config_options opts = { 0 };
791 struct object_id oid;
792 char *file;
793 char *oidstr = NULL;
794
795 file = repo_worktree_path(repo, GITMODULES_FILE);
796 if (file_exists(file)) {
797 config_source.file = file;
798 } else if (repo_get_oid(repo, GITMODULES_INDEX, &oid) >= 0 ||
799 repo_get_oid(repo, GITMODULES_HEAD, &oid) >= 0) {
800 config_source.blob = oidstr = xstrdup(oid_to_hex(&oid));
801 if (repo != the_repository)
802 odb_add_submodule_source_by_path(the_repository->objects,
803 repo->objects->sources->path);
804 } else {
805 goto out;
806 }
807
808 config_with_options(fn, data, &config_source, repo, &opts);
809
810 out:
811 free(oidstr);
812 free(file);
813 }
814 }
815
816 static int gitmodules_cb(const char *var, const char *value,
817 const struct config_context *ctx, void *data)
818 {
819 struct repository *repo = data;
820 struct parse_config_parameter parameter;
821
822 parameter.cache = repo->submodule_cache;
823 parameter.treeish_name = NULL;
824 parameter.gitmodules_oid = null_oid(the_hash_algo);
825 parameter.overwrite = 1;
826
827 return parse_config(var, value, ctx, &parameter);
828 }
829
830 void repo_read_gitmodules(struct repository *repo, int skip_if_read)
831 {
832 submodule_cache_check_init(repo);
833
834 if (repo->submodule_cache->gitmodules_read && skip_if_read)
835 return;
836
837 if (repo_read_index(repo) < 0)
838 return;
839
840 if (!is_gitmodules_unmerged(repo->index))
841 config_from_gitmodules(gitmodules_cb, repo, repo);
842
843 repo->submodule_cache->gitmodules_read = 1;
844 }
845
846 void gitmodules_config_oid(const struct object_id *commit_oid)
847 {
848 struct strbuf rev = STRBUF_INIT;
849 struct object_id oid;
850
851 submodule_cache_check_init(the_repository);
852
853 if (gitmodule_oid_from_commit(commit_oid, &oid, &rev)) {
854 git_config_from_blob_oid(gitmodules_cb, rev.buf,
855 the_repository, &oid, the_repository,
856 CONFIG_SCOPE_UNKNOWN);
857 }
858 strbuf_release(&rev);
859
860 the_repository->submodule_cache->gitmodules_read = 1;
861 }
862
863 const struct submodule *submodule_from_name(struct repository *r,
864 const struct object_id *treeish_name,
865 const char *name)
866 {
867 repo_read_gitmodules(r, 1);
868 return config_from(r->submodule_cache, treeish_name, name, lookup_name);
869 }
870
871 const struct submodule *submodule_from_path(struct repository *r,
872 const struct object_id *treeish_name,
873 const char *path)
874 {
875 repo_read_gitmodules(r, 1);
876 return config_from(r->submodule_cache, treeish_name, path, lookup_path);
877 }
878
879 /**
880 * Used internally by submodules_of_tree(). Recurses into 'treeish_name'
881 * and appends submodule entries to 'out'. The submodule_cache expects
882 * a root-level treeish_name and paths, so keep track of these values
883 * with 'root_tree' and 'prefix'.
884 */
885 static void traverse_tree_submodules(struct repository *r,
886 const struct object_id *root_tree,
887 char *prefix,
888 const struct object_id *treeish_name,
889 struct submodule_entry_list *out)
890 {
891 struct tree_desc tree;
892 struct submodule_tree_entry *st_entry;
893 struct name_entry name_entry;
894 char *tree_path = NULL;
895 char *tree_buf;
896
897 tree_buf = fill_tree_descriptor(r, &tree, treeish_name);
898 while (tree_entry(&tree, &name_entry)) {
899 if (prefix)
900 tree_path =
901 mkpathdup("%s/%s", prefix, name_entry.path);
902 else
903 tree_path = xstrdup(name_entry.path);
904
905 if (S_ISGITLINK(name_entry.mode) &&
906 is_tree_submodule_active(r, root_tree, tree_path)) {
907 ALLOC_GROW(out->entries, out->entry_nr + 1,
908 out->entry_alloc);
909 st_entry = &out->entries[out->entry_nr++];
910
911 st_entry->name_entry = xmalloc(sizeof(*st_entry->name_entry));
912 *st_entry->name_entry = name_entry;
913 st_entry->submodule =
914 submodule_from_path(r, root_tree, tree_path);
915 st_entry->repo = xmalloc(sizeof(*st_entry->repo));
916 if (repo_submodule_init(st_entry->repo, r, tree_path,
917 root_tree))
918 FREE_AND_NULL(st_entry->repo);
919
920 } else if (S_ISDIR(name_entry.mode))
921 traverse_tree_submodules(r, root_tree, tree_path,
922 &name_entry.oid, out);
923 free(tree_path);
924 }
925
926 free(tree_buf);
927 }
928
929 void submodules_of_tree(struct repository *r,
930 const struct object_id *treeish_name,
931 struct submodule_entry_list *out)
932 {
933 CALLOC_ARRAY(out->entries, 0);
934 out->entry_nr = 0;
935 out->entry_alloc = 0;
936
937 traverse_tree_submodules(r, treeish_name, NULL, treeish_name, out);
938 }
939
940 void submodule_entry_list_release(struct submodule_entry_list *list)
941 {
942 for (size_t i = 0; i < list->entry_nr; i++) {
943 free(list->entries[i].name_entry);
944 repo_clear(list->entries[i].repo);
945 free(list->entries[i].repo);
946 }
947 free(list->entries);
948 }
949
950 void submodule_free(struct repository *r)
951 {
952 if (r->submodule_cache)
953 submodule_cache_clear(r->submodule_cache);
954 }
955
956 static int config_print_callback(const char *var, const char *value,
957 const struct config_context *ctx UNUSED,
958 void *cb_data)
959 {
960 char *wanted_key = cb_data;
961
962 if (!strcmp(wanted_key, var))
963 printf("%s\n", value);
964
965 return 0;
966 }
967
968 int print_config_from_gitmodules(struct repository *repo, const char *key)
969 {
970 int ret;
971 char *store_key;
972
973 ret = git_config_parse_key(key, &store_key, NULL);
974 if (ret < 0)
975 return CONFIG_INVALID_KEY;
976
977 config_from_gitmodules(config_print_callback, repo, store_key);
978
979 free(store_key);
980 return 0;
981 }
982
983 int config_set_in_gitmodules_file_gently(const char *key, const char *value)
984 {
985 int ret;
986
987 ret = repo_config_set_in_file_gently(the_repository, GITMODULES_FILE, key, NULL, value);
988 if (ret < 0)
989 /* Maybe the user already did that, don't error out here */
990 warning(_("Could not update .gitmodules entry %s"), key);
991
992 return ret;
993 }
994
995 struct fetch_config {
996 int *max_children;
997 int *recurse_submodules;
998 };
999
1000 static int gitmodules_fetch_config(const char *var, const char *value,
1001 const struct config_context *ctx,
1002 void *cb)
1003 {
1004 struct fetch_config *config = cb;
1005 if (!strcmp(var, "submodule.fetchjobs")) {
1006 if (config->max_children)
1007 *(config->max_children) =
1008 parse_submodule_fetchjobs(var, value, ctx->kvi);
1009 return 0;
1010 } else if (!strcmp(var, "fetch.recursesubmodules")) {
1011 if (config->recurse_submodules)
1012 *(config->recurse_submodules) =
1013 parse_fetch_recurse_submodules_arg(var, value);
1014 return 0;
1015 }
1016
1017 return 0;
1018 }
1019
1020 void fetch_config_from_gitmodules(int *max_children, int *recurse_submodules)
1021 {
1022 struct fetch_config config = {
1023 .max_children = max_children,
1024 .recurse_submodules = recurse_submodules
1025 };
1026 config_from_gitmodules(gitmodules_fetch_config, the_repository, &config);
1027 }
1028
1029 static int gitmodules_update_clone_config(const char *var, const char *value,
1030 const struct config_context *ctx,
1031 void *cb)
1032 {
1033 int *max_jobs = cb;
1034 if (!strcmp(var, "submodule.fetchjobs"))
1035 *max_jobs = parse_submodule_fetchjobs(var, value, ctx->kvi);
1036 return 0;
1037 }
1038
1039 void update_clone_config_from_gitmodules(int *max_jobs)
1040 {
1041 config_from_gitmodules(gitmodules_update_clone_config, the_repository, max_jobs);
1042 }