]> git.ipfire.org Git - thirdparty/git.git/blame - builtin/submodule--helper.c
submodule--helper: libify more "die" paths for module_update()
[thirdparty/git.git] / builtin / submodule--helper.c
CommitLineData
f8adbec9 1#define USE_THE_INDEX_COMPATIBILITY_MACROS
74703a1e 2#include "builtin.h"
627d9342 3#include "repository.h"
74703a1e 4#include "cache.h"
b2141fc1 5#include "config.h"
74703a1e
SB
6#include "parse-options.h"
7#include "quote.h"
8#include "pathspec.h"
9#include "dir.h"
0ea306ef
SB
10#include "submodule.h"
11#include "submodule-config.h"
12#include "string-list.h"
ee8838d1 13#include "run-command.h"
63e95beb
SB
14#include "remote.h"
15#include "refs.h"
ec0cb496 16#include "refspec.h"
63e95beb 17#include "connect.h"
a9f8a375
PC
18#include "revision.h"
19#include "diffcore.h"
20#include "diff.h"
0d4a1321 21#include "object-store.h"
4f3e57ef 22#include "advice.h"
961b130d 23#include "branch.h"
f05da2b4 24#include "list-objects-filter-options.h"
63e95beb 25
9f580a62 26#define OPT_QUIET (1 << 0)
a9f8a375
PC
27#define OPT_CACHED (1 << 1)
28#define OPT_RECURSIVE (1 << 2)
2e612731 29#define OPT_FORCE (1 << 3)
9f580a62
PC
30
31typedef void (*each_submodule_fn)(const struct cache_entry *list_item,
32 void *cb_data);
63e95beb 33
f5373dea 34static int repo_get_default_remote(struct repository *repo, char **default_remote)
63e95beb 35{
f5373dea 36 char *dest = NULL;
63e95beb 37 struct strbuf sb = STRBUF_INIT;
a77c3fcb
AR
38 struct ref_store *store = get_main_ref_store(repo);
39 const char *refname = refs_resolve_ref_unsafe(store, "HEAD", 0, NULL,
40 NULL);
63e95beb
SB
41
42 if (!refname)
f5373dea 43 return die_message(_("No such ref: %s"), "HEAD");
63e95beb
SB
44
45 /* detached HEAD */
f5373dea
ÆAB
46 if (!strcmp(refname, "HEAD")) {
47 *default_remote = xstrdup("origin");
48 return 0;
49 }
63e95beb
SB
50
51 if (!skip_prefix(refname, "refs/heads/", &refname))
f5373dea
ÆAB
52 return die_message(_("Expecting a full ref name, got %s"),
53 refname);
63e95beb
SB
54
55 strbuf_addf(&sb, "branch.%s.remote", refname);
a77c3fcb 56 if (repo_config_get_string(repo, sb.buf, &dest))
f5373dea 57 *default_remote = xstrdup("origin");
63e95beb 58 else
f5373dea 59 *default_remote = dest;
63e95beb
SB
60
61 strbuf_release(&sb);
f5373dea 62 return 0;
63e95beb
SB
63}
64
f5373dea 65static int get_default_remote_submodule(const char *module_path, char **default_remote)
13424764 66{
a77c3fcb 67 struct repository subrepo;
13424764 68
1e8697b5
ÆAB
69 if (repo_submodule_init(&subrepo, the_repository, module_path,
70 null_oid()) < 0)
f5373dea
ÆAB
71 return die_message(_("could not get a repository handle for submodule '%s'"),
72 module_path);
73 return repo_get_default_remote(&subrepo, default_remote);
a77c3fcb 74}
13424764 75
a77c3fcb
AR
76static char *get_default_remote(void)
77{
f5373dea
ÆAB
78 char *default_remote;
79 int code = repo_get_default_remote(the_repository, &default_remote);
80
81 if (code)
82 exit(code);
83
84 return default_remote;
13424764
PC
85}
86
de0fcbe0 87static char *resolve_relative_url(const char *rel_url, const char *up_path, int quiet)
63e95beb 88{
ab6f23b7 89 char *remoteurl, *resolved_url;
63e95beb 90 char *remote = get_default_remote();
ab6f23b7 91 struct strbuf remotesb = STRBUF_INIT;
63e95beb 92
ab6f23b7
AR
93 strbuf_addf(&remotesb, "remote.%s.url", remote);
94 if (git_config_get_string(remotesb.buf, &remoteurl)) {
95 if (!quiet)
96 warning(_("could not look up configuration '%s'. "
97 "Assuming this repository is its own "
98 "authoritative upstream."),
99 remotesb.buf);
63e95beb 100 remoteurl = xgetcwd();
ab6f23b7
AR
101 }
102 resolved_url = relative_url(remoteurl, rel_url, up_path);
63e95beb 103
ab6f23b7 104 free(remote);
63e95beb 105 free(remoteurl);
ab6f23b7
AR
106 strbuf_release(&remotesb);
107
108 return resolved_url;
63e95beb
SB
109}
110
5ad87271
GC
111/* the result should be freed by the caller. */
112static char *get_submodule_displaypath(const char *path, const char *prefix)
74a10642 113{
5ad87271
GC
114 const char *super_prefix = get_super_prefix();
115
74a10642
PC
116 if (prefix && super_prefix) {
117 BUG("cannot have prefix '%s' and superprefix '%s'",
118 prefix, super_prefix);
119 } else if (prefix) {
120 struct strbuf sb = STRBUF_INIT;
121 char *displaypath = xstrdup(relative_path(path, prefix, &sb));
122 strbuf_release(&sb);
123 return displaypath;
124 } else if (super_prefix) {
125 return xstrfmt("%s%s", super_prefix, path);
126 } else {
127 return xstrdup(path);
128 }
129}
130
a9f8a375
PC
131static char *compute_rev_name(const char *sub_path, const char* object_id)
132{
133 struct strbuf sb = STRBUF_INIT;
134 const char ***d;
135
136 static const char *describe_bare[] = { NULL };
137
138 static const char *describe_tags[] = { "--tags", NULL };
139
140 static const char *describe_contains[] = { "--contains", NULL };
141
142 static const char *describe_all_always[] = { "--all", "--always", NULL };
143
144 static const char **describe_argv[] = { describe_bare, describe_tags,
145 describe_contains,
146 describe_all_always, NULL };
147
148 for (d = describe_argv; *d; d++) {
149 struct child_process cp = CHILD_PROCESS_INIT;
29fda24d 150 prepare_submodule_repo_env(&cp.env);
a9f8a375
PC
151 cp.dir = sub_path;
152 cp.git_cmd = 1;
153 cp.no_stderr = 1;
154
22f9b7f3
JK
155 strvec_push(&cp.args, "describe");
156 strvec_pushv(&cp.args, *d);
157 strvec_push(&cp.args, object_id);
a9f8a375
PC
158
159 if (!capture_command(&cp, &sb, 0)) {
160 strbuf_strip_suffix(&sb, "\n");
161 return strbuf_detach(&sb, NULL);
162 }
163 }
164
165 strbuf_release(&sb);
166 return NULL;
167}
168
74703a1e
SB
169struct module_list {
170 const struct cache_entry **entries;
171 int alloc, nr;
172};
9865b6e6 173#define MODULE_LIST_INIT { 0 }
74703a1e
SB
174
175static int module_list_compute(int argc, const char **argv,
176 const char *prefix,
177 struct pathspec *pathspec,
178 struct module_list *list)
179{
180 int i, result = 0;
2b56bb7a 181 char *ps_matched = NULL;
0b83b2b0 182
74703a1e 183 parse_pathspec(pathspec, 0,
2249d4db 184 PATHSPEC_PREFER_FULL,
74703a1e
SB
185 prefix, argv);
186
74703a1e
SB
187 if (pathspec->nr)
188 ps_matched = xcalloc(pathspec->nr, 1);
189
190 if (read_cache() < 0)
191 die(_("index file corrupt"));
192
193 for (i = 0; i < active_nr; i++) {
194 const struct cache_entry *ce = active_cache[i];
195
6d2df284 196 if (!match_pathspec(&the_index, pathspec, ce->name, ce_namelen(ce),
84ba959b
SB
197 0, ps_matched, 1) ||
198 !S_ISGITLINK(ce->ce_mode))
74703a1e
SB
199 continue;
200
201 ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
202 list->entries[list->nr++] = ce;
203 while (i + 1 < active_nr &&
204 !strcmp(ce->name, active_cache[i + 1]->name))
205 /*
206 * Skip entries with the same name in different stages
207 * to make sure an entry is returned only once.
208 */
209 i++;
210 }
74703a1e 211
c5c33504 212 if (ps_matched && report_path_error(ps_matched, pathspec))
74703a1e
SB
213 result = -1;
214
215 free(ps_matched);
216
217 return result;
218}
219
3e7eaed0
BW
220static void module_list_active(struct module_list *list)
221{
222 int i;
223 struct module_list active_modules = MODULE_LIST_INIT;
224
3e7eaed0
BW
225 for (i = 0; i < list->nr; i++) {
226 const struct cache_entry *ce = list->entries[i];
227
627d9342 228 if (!is_submodule_active(the_repository, ce->name))
3e7eaed0
BW
229 continue;
230
231 ALLOC_GROW(active_modules.entries,
232 active_modules.nr + 1,
233 active_modules.alloc);
234 active_modules.entries[active_modules.nr++] = ce;
235 }
236
237 free(list->entries);
238 *list = active_modules;
239}
240
13424764
PC
241static char *get_up_path(const char *path)
242{
243 int i;
244 struct strbuf sb = STRBUF_INIT;
245
246 for (i = count_slashes(path); i; i--)
247 strbuf_addstr(&sb, "../");
248
249 /*
250 * Check if 'path' ends with slash or not
251 * for having the same output for dir/sub_dir
252 * and dir/sub_dir/
253 */
254 if (!is_dir_sep(path[strlen(path) - 1]))
255 strbuf_addstr(&sb, "../");
256
257 return strbuf_detach(&sb, NULL);
258}
259
9f580a62
PC
260static void for_each_listed_submodule(const struct module_list *list,
261 each_submodule_fn fn, void *cb_data)
262{
263 int i;
0b83b2b0 264
9f580a62
PC
265 for (i = 0; i < list->nr; i++)
266 fn(list->entries[i], cb_data);
267}
268
d00a5bdd 269struct foreach_cb {
fc1b9243
PC
270 int argc;
271 const char **argv;
272 const char *prefix;
273 int quiet;
274 int recursive;
275};
d00a5bdd 276#define FOREACH_CB_INIT { 0 }
fc1b9243
PC
277
278static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
279 void *cb_data)
280{
d00a5bdd 281 struct foreach_cb *info = cb_data;
fc1b9243
PC
282 const char *path = list_item->name;
283 const struct object_id *ce_oid = &list_item->oid;
fc1b9243
PC
284 const struct submodule *sub;
285 struct child_process cp = CHILD_PROCESS_INIT;
286 char *displaypath;
287
288 displaypath = get_submodule_displaypath(path, info->prefix);
289
14228447 290 sub = submodule_from_path(the_repository, null_oid(), path);
fc1b9243
PC
291
292 if (!sub)
293 die(_("No url found for submodule path '%s' in .gitmodules"),
294 displaypath);
295
296 if (!is_submodule_populated_gently(path, NULL))
297 goto cleanup;
298
29fda24d 299 prepare_submodule_repo_env(&cp.env);
fc1b9243
PC
300
301 /*
302 * For the purpose of executing <command> in the submodule,
303 * separate shell is used for the purpose of running the
304 * child process.
305 */
306 cp.use_shell = 1;
307 cp.dir = path;
308
309 /*
310 * NEEDSWORK: the command currently has access to the variables $name,
311 * $sm_path, $displaypath, $sha1 and $toplevel only when the command
312 * contains a single argument. This is done for maintaining a faithful
313 * translation from shell script.
314 */
315 if (info->argc == 1) {
316 char *toplevel = xgetcwd();
317 struct strbuf sb = STRBUF_INIT;
318
29fda24d
ÆAB
319 strvec_pushf(&cp.env, "name=%s", sub->name);
320 strvec_pushf(&cp.env, "sm_path=%s", path);
321 strvec_pushf(&cp.env, "displaypath=%s", displaypath);
322 strvec_pushf(&cp.env, "sha1=%s",
f6d8942b 323 oid_to_hex(ce_oid));
29fda24d 324 strvec_pushf(&cp.env, "toplevel=%s", toplevel);
fc1b9243
PC
325
326 /*
327 * Since the path variable was accessible from the script
328 * before porting, it is also made available after porting.
329 * The environment variable "PATH" has a very special purpose
330 * on windows. And since environment variables are
331 * case-insensitive in windows, it interferes with the
332 * existing PATH variable. Hence, to avoid that, we expose
b3193252 333 * path via the args strvec and not via env.
fc1b9243
PC
334 */
335 sq_quote_buf(&sb, path);
22f9b7f3 336 strvec_pushf(&cp.args, "path=%s; %s",
f6d8942b 337 sb.buf, info->argv[0]);
fc1b9243
PC
338 strbuf_release(&sb);
339 free(toplevel);
340 } else {
22f9b7f3 341 strvec_pushv(&cp.args, info->argv);
fc1b9243
PC
342 }
343
344 if (!info->quiet)
345 printf(_("Entering '%s'\n"), displaypath);
346
347 if (info->argv[0] && run_command(&cp))
348 die(_("run_command returned non-zero status for %s\n."),
349 displaypath);
350
351 if (info->recursive) {
352 struct child_process cpr = CHILD_PROCESS_INIT;
353
354 cpr.git_cmd = 1;
355 cpr.dir = path;
29fda24d 356 prepare_submodule_repo_env(&cpr.env);
fc1b9243 357
22f9b7f3
JK
358 strvec_pushl(&cpr.args, "--super-prefix", NULL);
359 strvec_pushf(&cpr.args, "%s/", displaypath);
360 strvec_pushl(&cpr.args, "submodule--helper", "foreach", "--recursive",
f6d8942b 361 NULL);
fc1b9243
PC
362
363 if (info->quiet)
22f9b7f3 364 strvec_push(&cpr.args, "--quiet");
fc1b9243 365
22f9b7f3
JK
366 strvec_push(&cpr.args, "--");
367 strvec_pushv(&cpr.args, info->argv);
fc1b9243
PC
368
369 if (run_command(&cpr))
27c929ed 370 die(_("run_command returned non-zero status while "
fc1b9243
PC
371 "recursing in the nested submodules of %s\n."),
372 displaypath);
373 }
374
375cleanup:
376 free(displaypath);
377}
378
379static int module_foreach(int argc, const char **argv, const char *prefix)
380{
d00a5bdd 381 struct foreach_cb info = FOREACH_CB_INIT;
fc1b9243
PC
382 struct pathspec pathspec;
383 struct module_list list = MODULE_LIST_INIT;
fc1b9243 384 struct option module_foreach_options[] = {
e73fe3dd 385 OPT__QUIET(&info.quiet, N_("suppress output of entering each submodule command")),
fc1b9243 386 OPT_BOOL(0, "recursive", &info.recursive,
e73fe3dd 387 N_("recurse into nested submodules")),
fc1b9243
PC
388 OPT_END()
389 };
fc1b9243 390 const char *const git_submodule_helper_usage[] = {
36d45163 391 N_("git submodule foreach [--quiet] [--recursive] [--] <command>"),
fc1b9243
PC
392 NULL
393 };
394
395 argc = parse_options(argc, argv, prefix, module_foreach_options,
a282f5a9 396 git_submodule_helper_usage, 0);
fc1b9243
PC
397
398 if (module_list_compute(0, NULL, prefix, &pathspec, &list) < 0)
399 return 1;
400
401 info.argc = argc;
402 info.argv = argv;
403 info.prefix = prefix;
404
405 for_each_listed_submodule(&list, runcommand_in_submodule_cb, &info);
406
407 return 0;
408}
409
1d04e719
DS
410static int starts_with_dot_slash(const char *const path)
411{
412 return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_SLASH |
413 PATH_MATCH_XPLATFORM);
414}
415
416static int starts_with_dot_dot_slash(const char *const path)
417{
418 return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH |
419 PATH_MATCH_XPLATFORM);
420}
421
9f580a62
PC
422struct init_cb {
423 const char *prefix;
424 unsigned int flags;
425};
9865b6e6 426#define INIT_CB_INIT { 0 }
9f580a62
PC
427
428static void init_submodule(const char *path, const char *prefix,
d7a714fd 429 unsigned int flags)
3604242f
SB
430{
431 const struct submodule *sub;
432 struct strbuf sb = STRBUF_INIT;
b9dd63ff
ÆAB
433 const char *upd;
434 char *url = NULL, *displaypath;
3604242f 435
5ad87271 436 displaypath = get_submodule_displaypath(path, prefix);
d92028a5 437
14228447 438 sub = submodule_from_path(the_repository, null_oid(), path);
d92028a5
SB
439
440 if (!sub)
441 die(_("No url found for submodule path '%s' in .gitmodules"),
442 displaypath);
3604242f 443
1f8d7115
BW
444 /*
445 * NEEDSWORK: In a multi-working-tree world, this needs to be
446 * set in the per-worktree config.
447 *
448 * Set active flag for the submodule being initialized
449 */
627d9342 450 if (!is_submodule_active(the_repository, path)) {
1f8d7115
BW
451 strbuf_addf(&sb, "submodule.%s.active", sub->name);
452 git_config_set_gently(sb.buf, "true");
74a10642 453 strbuf_reset(&sb);
1f8d7115
BW
454 }
455
3604242f
SB
456 /*
457 * Copy url setting when it is not set yet.
458 * To look up the url in .git/config, we must not fall back to
459 * .gitmodules, so look it up directly.
460 */
3604242f
SB
461 strbuf_addf(&sb, "submodule.%s.url", sub->name);
462 if (git_config_get_string(sb.buf, &url)) {
627fde10 463 if (!sub->url)
3604242f
SB
464 die(_("No url found for submodule path '%s' in .gitmodules"),
465 displaypath);
466
627fde10
JK
467 url = xstrdup(sub->url);
468
3604242f
SB
469 /* Possibly a url relative to parent */
470 if (starts_with_dot_dot_slash(url) ||
471 starts_with_dot_slash(url)) {
e0a862fd 472 char *oldurl = url;
0b83b2b0 473
de0fcbe0 474 url = resolve_relative_url(oldurl, NULL, 0);
e0a862fd 475 free(oldurl);
3604242f
SB
476 }
477
478 if (git_config_set_gently(sb.buf, url))
479 die(_("Failed to register url for submodule path '%s'"),
480 displaypath);
9f580a62 481 if (!(flags & OPT_QUIET))
c66410ed
SB
482 fprintf(stderr,
483 _("Submodule '%s' (%s) registered for path '%s'\n"),
3604242f
SB
484 sub->name, url, displaypath);
485 }
74a10642 486 strbuf_reset(&sb);
3604242f
SB
487
488 /* Copy "update" setting when it is not set yet */
3604242f 489 strbuf_addf(&sb, "submodule.%s.update", sub->name);
b9dd63ff 490 if (git_config_get_string_tmp(sb.buf, &upd) &&
3604242f
SB
491 sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
492 if (sub->update_strategy.type == SM_UPDATE_COMMAND) {
493 fprintf(stderr, _("warning: command update mode suggested for submodule '%s'\n"),
494 sub->name);
b9dd63ff 495 upd = "none";
96a90737 496 } else {
b9dd63ff 497 upd = submodule_update_type_to_string(sub->update_strategy.type);
96a90737 498 }
3604242f
SB
499
500 if (git_config_set_gently(sb.buf, upd))
501 die(_("Failed to register update mode for submodule path '%s'"), displaypath);
502 }
503 strbuf_release(&sb);
504 free(displaypath);
505 free(url);
3604242f
SB
506}
507
9f580a62
PC
508static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data)
509{
510 struct init_cb *info = cb_data;
0b83b2b0 511
d7a714fd 512 init_submodule(list_item->name, info->prefix, info->flags);
9f580a62
PC
513}
514
3604242f
SB
515static int module_init(int argc, const char **argv, const char *prefix)
516{
9f580a62 517 struct init_cb info = INIT_CB_INIT;
3604242f
SB
518 struct pathspec pathspec;
519 struct module_list list = MODULE_LIST_INIT;
520 int quiet = 0;
3604242f 521 struct option module_init_options[] = {
e73fe3dd 522 OPT__QUIET(&quiet, N_("suppress output for initializing a submodule")),
3604242f
SB
523 OPT_END()
524 };
3604242f 525 const char *const git_submodule_helper_usage[] = {
36d45163 526 N_("git submodule init [<options>] [<path>]"),
3604242f
SB
527 NULL
528 };
529
530 argc = parse_options(argc, argv, prefix, module_init_options,
531 git_submodule_helper_usage, 0);
532
533 if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
534 return 1;
535
3e7eaed0
BW
536 /*
537 * If there are no path args and submodule.active is set then,
538 * by default, only initialize 'active' modules.
539 */
540 if (!argc && git_config_get_value_multi("submodule.active"))
541 module_list_active(&list);
542
9f580a62
PC
543 info.prefix = prefix;
544 if (quiet)
545 info.flags |= OPT_QUIET;
546
547 for_each_listed_submodule(&list, init_submodule_cb, &info);
3604242f
SB
548
549 return 0;
550}
551
a9f8a375
PC
552struct status_cb {
553 const char *prefix;
554 unsigned int flags;
555};
9865b6e6 556#define STATUS_CB_INIT { 0 }
a9f8a375
PC
557
558static void print_status(unsigned int flags, char state, const char *path,
559 const struct object_id *oid, const char *displaypath)
560{
561 if (flags & OPT_QUIET)
562 return;
563
564 printf("%c%s %s", state, oid_to_hex(oid), displaypath);
565
0b5e2ea7
NTND
566 if (state == ' ' || state == '+') {
567 const char *name = compute_rev_name(path, oid_to_hex(oid));
568
569 if (name)
570 printf(" (%s)", name);
571 }
a9f8a375
PC
572
573 printf("\n");
574}
575
576static int handle_submodule_head_ref(const char *refname,
577 const struct object_id *oid, int flags,
578 void *cb_data)
579{
580 struct object_id *output = cb_data;
0b83b2b0 581
a9f8a375
PC
582 if (oid)
583 oidcpy(output, oid);
584
585 return 0;
586}
587
588static void status_submodule(const char *path, const struct object_id *ce_oid,
589 unsigned int ce_flags, const char *prefix,
590 unsigned int flags)
591{
592 char *displaypath;
22f9b7f3 593 struct strvec diff_files_args = STRVEC_INIT;
f196c1e9 594 struct rev_info rev = REV_INFO_INIT;
a9f8a375 595 int diff_files_result;
3b2885ec
PK
596 struct strbuf buf = STRBUF_INIT;
597 const char *git_dir;
a9f8a375 598
14228447 599 if (!submodule_from_path(the_repository, null_oid(), path))
a9f8a375
PC
600 die(_("no submodule mapping found in .gitmodules for path '%s'"),
601 path);
602
603 displaypath = get_submodule_displaypath(path, prefix);
604
605 if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
14228447 606 print_status(flags, 'U', path, null_oid(), displaypath);
a9f8a375
PC
607 goto cleanup;
608 }
609
3b2885ec
PK
610 strbuf_addf(&buf, "%s/.git", path);
611 git_dir = read_gitfile(buf.buf);
612 if (!git_dir)
613 git_dir = buf.buf;
614
615 if (!is_submodule_active(the_repository, path) ||
616 !is_git_directory(git_dir)) {
a9f8a375 617 print_status(flags, '-', path, ce_oid, displaypath);
3b2885ec 618 strbuf_release(&buf);
a9f8a375
PC
619 goto cleanup;
620 }
3b2885ec 621 strbuf_release(&buf);
a9f8a375 622
22f9b7f3 623 strvec_pushl(&diff_files_args, "diff-files",
f6d8942b
JK
624 "--ignore-submodules=dirty", "--quiet", "--",
625 path, NULL);
a9f8a375
PC
626
627 git_config(git_diff_basic_config, NULL);
1f3aea22
MG
628
629 repo_init_revisions(the_repository, &rev, NULL);
a9f8a375 630 rev.abbrev = 0;
d70a9eb6
JK
631 diff_files_args.nr = setup_revisions(diff_files_args.nr,
632 diff_files_args.v,
633 &rev, NULL);
a9f8a375
PC
634 diff_files_result = run_diff_files(&rev, 0);
635
636 if (!diff_result_code(&rev.diffopt, diff_files_result)) {
637 print_status(flags, ' ', path, ce_oid,
638 displaypath);
639 } else if (!(flags & OPT_CACHED)) {
640 struct object_id oid;
74b6bda3 641 struct ref_store *refs = get_submodule_ref_store(path);
a9f8a375 642
74b6bda3
RS
643 if (!refs) {
644 print_status(flags, '-', path, ce_oid, displaypath);
645 goto cleanup;
646 }
647 if (refs_head_ref(refs, handle_submodule_head_ref, &oid))
ed5bdd5b 648 die(_("could not resolve HEAD ref inside the "
a9f8a375
PC
649 "submodule '%s'"), path);
650
651 print_status(flags, '+', path, &oid, displaypath);
652 } else {
653 print_status(flags, '+', path, ce_oid, displaypath);
654 }
655
656 if (flags & OPT_RECURSIVE) {
657 struct child_process cpr = CHILD_PROCESS_INIT;
658
659 cpr.git_cmd = 1;
660 cpr.dir = path;
29fda24d 661 prepare_submodule_repo_env(&cpr.env);
a9f8a375 662
22f9b7f3
JK
663 strvec_push(&cpr.args, "--super-prefix");
664 strvec_pushf(&cpr.args, "%s/", displaypath);
665 strvec_pushl(&cpr.args, "submodule--helper", "status",
f6d8942b 666 "--recursive", NULL);
a9f8a375
PC
667
668 if (flags & OPT_CACHED)
22f9b7f3 669 strvec_push(&cpr.args, "--cached");
a9f8a375
PC
670
671 if (flags & OPT_QUIET)
22f9b7f3 672 strvec_push(&cpr.args, "--quiet");
a9f8a375
PC
673
674 if (run_command(&cpr))
675 die(_("failed to recurse into submodule '%s'"), path);
676 }
677
678cleanup:
22f9b7f3 679 strvec_clear(&diff_files_args);
a9f8a375 680 free(displaypath);
f196c1e9 681 release_revisions(&rev);
a9f8a375
PC
682}
683
684static void status_submodule_cb(const struct cache_entry *list_item,
685 void *cb_data)
686{
687 struct status_cb *info = cb_data;
0b83b2b0 688
a9f8a375
PC
689 status_submodule(list_item->name, &list_item->oid, list_item->ce_flags,
690 info->prefix, info->flags);
691}
692
693static int module_status(int argc, const char **argv, const char *prefix)
694{
695 struct status_cb info = STATUS_CB_INIT;
696 struct pathspec pathspec;
697 struct module_list list = MODULE_LIST_INIT;
698 int quiet = 0;
a9f8a375 699 struct option module_status_options[] = {
e73fe3dd
ZH
700 OPT__QUIET(&quiet, N_("suppress submodule status output")),
701 OPT_BIT(0, "cached", &info.flags, N_("use commit stored in the index instead of the one stored in the submodule HEAD"), OPT_CACHED),
a9f8a375
PC
702 OPT_BIT(0, "recursive", &info.flags, N_("recurse into nested submodules"), OPT_RECURSIVE),
703 OPT_END()
704 };
a9f8a375
PC
705 const char *const git_submodule_helper_usage[] = {
706 N_("git submodule status [--quiet] [--cached] [--recursive] [<path>...]"),
707 NULL
708 };
709
710 argc = parse_options(argc, argv, prefix, module_status_options,
711 git_submodule_helper_usage, 0);
712
713 if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
714 return 1;
715
716 info.prefix = prefix;
717 if (quiet)
718 info.flags |= OPT_QUIET;
719
720 for_each_listed_submodule(&list, status_submodule_cb, &info);
3604242f
SB
721
722 return 0;
723}
724
e83e3333
PC
725struct module_cb {
726 unsigned int mod_src;
727 unsigned int mod_dst;
728 struct object_id oid_src;
729 struct object_id oid_dst;
730 char status;
731 const char *sm_path;
732};
9865b6e6 733#define MODULE_CB_INIT { 0 }
e83e3333
PC
734
735struct module_cb_list {
736 struct module_cb **entries;
737 int alloc, nr;
738};
9865b6e6 739#define MODULE_CB_LIST_INIT { 0 }
e83e3333
PC
740
741struct summary_cb {
742 int argc;
743 const char **argv;
744 const char *prefix;
745 unsigned int cached: 1;
746 unsigned int for_status: 1;
747 unsigned int files: 1;
748 int summary_limit;
749};
9865b6e6 750#define SUMMARY_CB_INIT { 0 }
e83e3333
PC
751
752enum diff_cmd {
753 DIFF_INDEX,
754 DIFF_FILES
755};
756
f0c6b646 757static char *verify_submodule_committish(const char *sm_path,
e83e3333
PC
758 const char *committish)
759{
760 struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
761 struct strbuf result = STRBUF_INIT;
762
763 cp_rev_parse.git_cmd = 1;
764 cp_rev_parse.dir = sm_path;
29fda24d 765 prepare_submodule_repo_env(&cp_rev_parse.env);
e83e3333
PC
766 strvec_pushl(&cp_rev_parse.args, "rev-parse", "-q", "--short", NULL);
767 strvec_pushf(&cp_rev_parse.args, "%s^0", committish);
768 strvec_push(&cp_rev_parse.args, "--");
769
770 if (capture_command(&cp_rev_parse, &result, 0))
771 return NULL;
772
773 strbuf_trim_trailing_newline(&result);
774 return strbuf_detach(&result, NULL);
775}
776
9d02f949 777static void print_submodule_summary(struct summary_cb *info, const char *errmsg,
e83e3333
PC
778 int total_commits, const char *displaypath,
779 const char *src_abbrev, const char *dst_abbrev,
e83e3333
PC
780 struct module_cb *p)
781{
782 if (p->status == 'T') {
783 if (S_ISGITLINK(p->mod_dst))
784 printf(_("* %s %s(blob)->%s(submodule)"),
785 displaypath, src_abbrev, dst_abbrev);
786 else
787 printf(_("* %s %s(submodule)->%s(blob)"),
788 displaypath, src_abbrev, dst_abbrev);
789 } else {
790 printf("* %s %s...%s",
791 displaypath, src_abbrev, dst_abbrev);
792 }
793
794 if (total_commits < 0)
795 printf(":\n");
796 else
797 printf(" (%d):\n", total_commits);
798
799 if (errmsg) {
800 printf(_("%s"), errmsg);
801 } else if (total_commits > 0) {
802 struct child_process cp_log = CHILD_PROCESS_INIT;
803
804 cp_log.git_cmd = 1;
805 cp_log.dir = p->sm_path;
29fda24d 806 prepare_submodule_repo_env(&cp_log.env);
e83e3333
PC
807 strvec_pushl(&cp_log.args, "log", NULL);
808
809 if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) {
810 if (info->summary_limit > 0)
811 strvec_pushf(&cp_log.args, "-%d",
812 info->summary_limit);
813
814 strvec_pushl(&cp_log.args, "--pretty= %m %s",
815 "--first-parent", NULL);
816 strvec_pushf(&cp_log.args, "%s...%s",
817 src_abbrev, dst_abbrev);
818 } else if (S_ISGITLINK(p->mod_dst)) {
819 strvec_pushl(&cp_log.args, "--pretty= > %s",
820 "-1", dst_abbrev, NULL);
821 } else {
822 strvec_pushl(&cp_log.args, "--pretty= < %s",
823 "-1", src_abbrev, NULL);
824 }
825 run_command(&cp_log);
826 }
827 printf("\n");
828}
829
830static void generate_submodule_summary(struct summary_cb *info,
831 struct module_cb *p)
832{
d79b1455 833 char *displaypath, *src_abbrev = NULL, *dst_abbrev;
e83e3333 834 int missing_src = 0, missing_dst = 0;
9d02f949 835 struct strbuf errmsg = STRBUF_INIT;
e83e3333
PC
836 int total_commits = -1;
837
14228447 838 if (!info->cached && oideq(&p->oid_dst, null_oid())) {
e83e3333
PC
839 if (S_ISGITLINK(p->mod_dst)) {
840 struct ref_store *refs = get_submodule_ref_store(p->sm_path);
0b83b2b0 841
e83e3333
PC
842 if (refs)
843 refs_head_ref(refs, handle_submodule_head_ref, &p->oid_dst);
844 } else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) {
845 struct stat st;
846 int fd = open(p->sm_path, O_RDONLY);
847
848 if (fd < 0 || fstat(fd, &st) < 0 ||
849 index_fd(&the_index, &p->oid_dst, fd, &st, OBJ_BLOB,
850 p->sm_path, 0))
851 error(_("couldn't hash object from '%s'"), p->sm_path);
852 } else {
853 /* for a submodule removal (mode:0000000), don't warn */
854 if (p->mod_dst)
f0c6b646 855 warning(_("unexpected mode %o\n"), p->mod_dst);
e83e3333
PC
856 }
857 }
858
859 if (S_ISGITLINK(p->mod_src)) {
d79b1455
SS
860 if (p->status != 'D')
861 src_abbrev = verify_submodule_committish(p->sm_path,
862 oid_to_hex(&p->oid_src));
e83e3333
PC
863 if (!src_abbrev) {
864 missing_src = 1;
865 /*
866 * As `rev-parse` failed, we fallback to getting
867 * the abbreviated hash using oid_src. We do
868 * this as we might still need the abbreviated
869 * hash in cases like a submodule type change, etc.
870 */
871 src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7);
872 }
873 } else {
874 /*
875 * The source does not point to a submodule.
876 * So, we fallback to getting the abbreviation using
877 * oid_src as we might still need the abbreviated
878 * hash in cases like submodule add, etc.
879 */
880 src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7);
881 }
882
883 if (S_ISGITLINK(p->mod_dst)) {
884 dst_abbrev = verify_submodule_committish(p->sm_path,
885 oid_to_hex(&p->oid_dst));
886 if (!dst_abbrev) {
887 missing_dst = 1;
888 /*
889 * As `rev-parse` failed, we fallback to getting
890 * the abbreviated hash using oid_dst. We do
891 * this as we might still need the abbreviated
892 * hash in cases like a submodule type change, etc.
893 */
894 dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
895 }
896 } else {
897 /*
898 * The destination does not point to a submodule.
899 * So, we fallback to getting the abbreviation using
900 * oid_dst as we might still need the abbreviated
901 * hash in cases like a submodule removal, etc.
902 */
903 dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
904 }
905
906 displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
907
908 if (!missing_src && !missing_dst) {
909 struct child_process cp_rev_list = CHILD_PROCESS_INIT;
910 struct strbuf sb_rev_list = STRBUF_INIT;
911
912 strvec_pushl(&cp_rev_list.args, "rev-list",
913 "--first-parent", "--count", NULL);
914 if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst))
915 strvec_pushf(&cp_rev_list.args, "%s...%s",
916 src_abbrev, dst_abbrev);
917 else
918 strvec_push(&cp_rev_list.args, S_ISGITLINK(p->mod_src) ?
919 src_abbrev : dst_abbrev);
920 strvec_push(&cp_rev_list.args, "--");
921
922 cp_rev_list.git_cmd = 1;
923 cp_rev_list.dir = p->sm_path;
29fda24d 924 prepare_submodule_repo_env(&cp_rev_list.env);
e83e3333
PC
925
926 if (!capture_command(&cp_rev_list, &sb_rev_list, 0))
927 total_commits = atoi(sb_rev_list.buf);
928
929 strbuf_release(&sb_rev_list);
930 } else {
931 /*
932 * Don't give error msg for modification whose dst is not
933 * submodule, i.e., deleted or changed to blob
934 */
935 if (S_ISGITLINK(p->mod_dst)) {
e83e3333 936 if (missing_src && missing_dst) {
9d02f949 937 strbuf_addf(&errmsg, " Warn: %s doesn't contain commits %s and %s\n",
e83e3333
PC
938 displaypath, oid_to_hex(&p->oid_src),
939 oid_to_hex(&p->oid_dst));
940 } else {
9d02f949 941 strbuf_addf(&errmsg, " Warn: %s doesn't contain commit %s\n",
e83e3333
PC
942 displaypath, missing_src ?
943 oid_to_hex(&p->oid_src) :
944 oid_to_hex(&p->oid_dst));
945 }
e83e3333
PC
946 }
947 }
948
9d02f949
GC
949 print_submodule_summary(info, errmsg.len ? errmsg.buf : NULL,
950 total_commits, displaypath, src_abbrev,
e0f7ae56 951 dst_abbrev, p);
e83e3333
PC
952
953 free(displaypath);
954 free(src_abbrev);
955 free(dst_abbrev);
956}
957
958static void prepare_submodule_summary(struct summary_cb *info,
959 struct module_cb_list *list)
960{
961 int i;
962 for (i = 0; i < list->nr; i++) {
963 const struct submodule *sub;
964 struct module_cb *p = list->entries[i];
965 struct strbuf sm_gitdir = STRBUF_INIT;
966
967 if (p->status == 'D' || p->status == 'T') {
968 generate_submodule_summary(info, p);
969 continue;
970 }
971
972 if (info->for_status && p->status != 'A' &&
973 (sub = submodule_from_path(the_repository,
14228447 974 null_oid(), p->sm_path))) {
e83e3333
PC
975 char *config_key = NULL;
976 const char *value;
977 int ignore_all = 0;
978
979 config_key = xstrfmt("submodule.%s.ignore",
980 sub->name);
bbdba3d8 981 if (!git_config_get_string_tmp(config_key, &value))
e83e3333
PC
982 ignore_all = !strcmp(value, "all");
983 else if (sub->ignore)
984 ignore_all = !strcmp(sub->ignore, "all");
985
986 free(config_key);
987 if (ignore_all)
988 continue;
989 }
990
991 /* Also show added or modified modules which are checked out */
992 strbuf_addstr(&sm_gitdir, p->sm_path);
993 if (is_nonbare_repository_dir(&sm_gitdir))
994 generate_submodule_summary(info, p);
995 strbuf_release(&sm_gitdir);
996 }
997}
998
999static void submodule_summary_callback(struct diff_queue_struct *q,
1000 struct diff_options *options,
1001 void *data)
1002{
1003 int i;
1004 struct module_cb_list *list = data;
1005 for (i = 0; i < q->nr; i++) {
1006 struct diff_filepair *p = q->queue[i];
1007 struct module_cb *temp;
1008
1009 if (!S_ISGITLINK(p->one->mode) && !S_ISGITLINK(p->two->mode))
1010 continue;
1011 temp = (struct module_cb*)malloc(sizeof(struct module_cb));
1012 temp->mod_src = p->one->mode;
1013 temp->mod_dst = p->two->mode;
1014 temp->oid_src = p->one->oid;
1015 temp->oid_dst = p->two->oid;
1016 temp->status = p->status;
1017 temp->sm_path = xstrdup(p->one->path);
1018
1019 ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
1020 list->entries[list->nr++] = temp;
1021 }
1022}
1023
1024static const char *get_diff_cmd(enum diff_cmd diff_cmd)
1025{
1026 switch (diff_cmd) {
1027 case DIFF_INDEX: return "diff-index";
1028 case DIFF_FILES: return "diff-files";
1029 default: BUG("bad diff_cmd value %d", diff_cmd);
1030 }
1031}
1032
1033static int compute_summary_module_list(struct object_id *head_oid,
1034 struct summary_cb *info,
1035 enum diff_cmd diff_cmd)
1036{
1037 struct strvec diff_args = STRVEC_INIT;
1038 struct rev_info rev;
1039 struct module_cb_list list = MODULE_CB_LIST_INIT;
0139c58a 1040 int ret = 0;
e83e3333
PC
1041
1042 strvec_push(&diff_args, get_diff_cmd(diff_cmd));
1043 if (info->cached)
1044 strvec_push(&diff_args, "--cached");
1045 strvec_pushl(&diff_args, "--ignore-submodules=dirty", "--raw", NULL);
1046 if (head_oid)
1047 strvec_push(&diff_args, oid_to_hex(head_oid));
1048 strvec_push(&diff_args, "--");
1049 if (info->argc)
1050 strvec_pushv(&diff_args, info->argv);
1051
1052 git_config(git_diff_basic_config, NULL);
1053 init_revisions(&rev, info->prefix);
1054 rev.abbrev = 0;
5c327502 1055 precompose_argv_prefix(diff_args.nr, diff_args.v, NULL);
e83e3333
PC
1056 setup_revisions(diff_args.nr, diff_args.v, &rev, NULL);
1057 rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK;
1058 rev.diffopt.format_callback = submodule_summary_callback;
1059 rev.diffopt.format_callback_data = &list;
1060
1061 if (!info->cached) {
1062 if (diff_cmd == DIFF_INDEX)
1063 setup_work_tree();
1064 if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
1065 perror("read_cache_preload");
0139c58a
ÆAB
1066 ret = -1;
1067 goto cleanup;
e83e3333
PC
1068 }
1069 } else if (read_cache() < 0) {
1070 perror("read_cache");
0139c58a
ÆAB
1071 ret = -1;
1072 goto cleanup;
e83e3333
PC
1073 }
1074
1075 if (diff_cmd == DIFF_INDEX)
1076 run_diff_index(&rev, info->cached);
1077 else
1078 run_diff_files(&rev, 0);
1079 prepare_submodule_summary(info, &list);
0139c58a 1080cleanup:
e83e3333 1081 strvec_clear(&diff_args);
2108fe4a 1082 release_revisions(&rev);
0139c58a 1083 return ret;
e83e3333
PC
1084}
1085
1086static int module_summary(int argc, const char **argv, const char *prefix)
1087{
1088 struct summary_cb info = SUMMARY_CB_INIT;
1089 int cached = 0;
1090 int for_status = 0;
1091 int files = 0;
1092 int summary_limit = -1;
1093 enum diff_cmd diff_cmd = DIFF_INDEX;
1094 struct object_id head_oid;
1095 int ret;
e83e3333
PC
1096 struct option module_summary_options[] = {
1097 OPT_BOOL(0, "cached", &cached,
1098 N_("use the commit stored in the index instead of the submodule HEAD")),
1099 OPT_BOOL(0, "files", &files,
f5f5a61d 1100 N_("compare the commit in the index with that in the submodule HEAD")),
e83e3333
PC
1101 OPT_BOOL(0, "for-status", &for_status,
1102 N_("skip submodules with 'ignore_config' value set to 'all'")),
1103 OPT_INTEGER('n', "summary-limit", &summary_limit,
1104 N_("limit the summary size")),
1105 OPT_END()
1106 };
e83e3333 1107 const char *const git_submodule_helper_usage[] = {
36d45163 1108 N_("git submodule summary [<options>] [<commit>] [--] [<path>]"),
e83e3333
PC
1109 NULL
1110 };
1111
1112 argc = parse_options(argc, argv, prefix, module_summary_options,
1113 git_submodule_helper_usage, 0);
1114
1115 if (!summary_limit)
1116 return 0;
1117
1118 if (!get_oid(argc ? argv[0] : "HEAD", &head_oid)) {
1119 if (argc) {
1120 argv++;
1121 argc--;
1122 }
1123 } else if (!argc || !strcmp(argv[0], "HEAD")) {
1124 /* before the first commit: compare with an empty tree */
1125 oidcpy(&head_oid, the_hash_algo->empty_tree);
1126 if (argc) {
1127 argv++;
1128 argc--;
1129 }
1130 } else {
1131 if (get_oid("HEAD", &head_oid))
1132 die(_("could not fetch a revision for HEAD"));
1133 }
1134
1135 if (files) {
1136 if (cached)
43ea635c 1137 die(_("options '%s' and '%s' cannot be used together"), "--cached", "--files");
e83e3333
PC
1138 diff_cmd = DIFF_FILES;
1139 }
1140
1141 info.argc = argc;
1142 info.argv = argv;
1143 info.prefix = prefix;
1144 info.cached = !!cached;
1145 info.files = !!files;
1146 info.for_status = !!for_status;
1147 info.summary_limit = summary_limit;
1148
1149 ret = compute_summary_module_list((diff_cmd == DIFF_INDEX) ? &head_oid : NULL,
1150 &info, diff_cmd);
1151 return ret;
1152}
1153
13424764
PC
1154struct sync_cb {
1155 const char *prefix;
1156 unsigned int flags;
1157};
9865b6e6 1158#define SYNC_CB_INIT { 0 }
13424764
PC
1159
1160static void sync_submodule(const char *path, const char *prefix,
1161 unsigned int flags)
1162{
1163 const struct submodule *sub;
1164 char *remote_key = NULL;
a77c3fcb 1165 char *sub_origin_url, *super_config_url, *displaypath, *default_remote;
13424764 1166 struct strbuf sb = STRBUF_INIT;
13424764 1167 char *sub_config_path = NULL;
f5373dea 1168 int code;
13424764
PC
1169
1170 if (!is_submodule_active(the_repository, path))
1171 return;
1172
14228447 1173 sub = submodule_from_path(the_repository, null_oid(), path);
13424764
PC
1174
1175 if (sub && sub->url) {
1176 if (starts_with_dot_dot_slash(sub->url) ||
1177 starts_with_dot_slash(sub->url)) {
0c61041e 1178 char *up_path = get_up_path(path);
0b83b2b0 1179
de0fcbe0
AR
1180 sub_origin_url = resolve_relative_url(sub->url, up_path, 1);
1181 super_config_url = resolve_relative_url(sub->url, NULL, 1);
13424764 1182 free(up_path);
13424764
PC
1183 } else {
1184 sub_origin_url = xstrdup(sub->url);
1185 super_config_url = xstrdup(sub->url);
1186 }
1187 } else {
1188 sub_origin_url = xstrdup("");
1189 super_config_url = xstrdup("");
1190 }
1191
1192 displaypath = get_submodule_displaypath(path, prefix);
1193
1194 if (!(flags & OPT_QUIET))
1195 printf(_("Synchronizing submodule url for '%s'\n"),
1196 displaypath);
1197
1198 strbuf_reset(&sb);
1199 strbuf_addf(&sb, "submodule.%s.url", sub->name);
1200 if (git_config_set_gently(sb.buf, super_config_url))
1201 die(_("failed to register url for submodule path '%s'"),
1202 displaypath);
1203
1204 if (!is_submodule_populated_gently(path, NULL))
1205 goto cleanup;
1206
13424764 1207 strbuf_reset(&sb);
f5373dea
ÆAB
1208 code = get_default_remote_submodule(path, &default_remote);
1209 if (code)
1210 exit(code);
13424764 1211
a77c3fcb
AR
1212 remote_key = xstrfmt("remote.%s.url", default_remote);
1213 free(default_remote);
13424764 1214
13424764
PC
1215 submodule_to_gitdir(&sb, path);
1216 strbuf_addstr(&sb, "/config");
1217
1218 if (git_config_set_in_file_gently(sb.buf, remote_key, sub_origin_url))
1219 die(_("failed to update remote for submodule '%s'"),
1220 path);
1221
1222 if (flags & OPT_RECURSIVE) {
1223 struct child_process cpr = CHILD_PROCESS_INIT;
1224
1225 cpr.git_cmd = 1;
1226 cpr.dir = path;
29fda24d 1227 prepare_submodule_repo_env(&cpr.env);
13424764 1228
22f9b7f3
JK
1229 strvec_push(&cpr.args, "--super-prefix");
1230 strvec_pushf(&cpr.args, "%s/", displaypath);
1231 strvec_pushl(&cpr.args, "submodule--helper", "sync",
f6d8942b 1232 "--recursive", NULL);
13424764
PC
1233
1234 if (flags & OPT_QUIET)
22f9b7f3 1235 strvec_push(&cpr.args, "--quiet");
13424764
PC
1236
1237 if (run_command(&cpr))
1238 die(_("failed to recurse into submodule '%s'"),
1239 path);
1240 }
1241
1242cleanup:
1243 free(super_config_url);
1244 free(sub_origin_url);
1245 strbuf_release(&sb);
1246 free(remote_key);
1247 free(displaypath);
1248 free(sub_config_path);
1249}
1250
1251static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data)
1252{
1253 struct sync_cb *info = cb_data;
0b83b2b0 1254
13424764 1255 sync_submodule(list_item->name, info->prefix, info->flags);
13424764
PC
1256}
1257
1258static int module_sync(int argc, const char **argv, const char *prefix)
1259{
1260 struct sync_cb info = SYNC_CB_INIT;
1261 struct pathspec pathspec;
1262 struct module_list list = MODULE_LIST_INIT;
1263 int quiet = 0;
1264 int recursive = 0;
13424764 1265 struct option module_sync_options[] = {
e73fe3dd 1266 OPT__QUIET(&quiet, N_("suppress output of synchronizing submodule url")),
13424764 1267 OPT_BOOL(0, "recursive", &recursive,
e73fe3dd 1268 N_("recurse into nested submodules")),
13424764
PC
1269 OPT_END()
1270 };
13424764 1271 const char *const git_submodule_helper_usage[] = {
36d45163 1272 N_("git submodule sync [--quiet] [--recursive] [<path>]"),
13424764
PC
1273 NULL
1274 };
1275
1276 argc = parse_options(argc, argv, prefix, module_sync_options,
1277 git_submodule_helper_usage, 0);
1278
1279 if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
1280 return 1;
1281
1282 info.prefix = prefix;
1283 if (quiet)
1284 info.flags |= OPT_QUIET;
1285 if (recursive)
1286 info.flags |= OPT_RECURSIVE;
1287
1288 for_each_listed_submodule(&list, sync_submodule_cb, &info);
1289
1290 return 0;
1291}
1292
2e612731
PC
1293struct deinit_cb {
1294 const char *prefix;
1295 unsigned int flags;
1296};
9865b6e6 1297#define DEINIT_CB_INIT { 0 }
2e612731
PC
1298
1299static void deinit_submodule(const char *path, const char *prefix,
1300 unsigned int flags)
1301{
1302 const struct submodule *sub;
1303 char *displaypath = NULL;
1304 struct child_process cp_config = CHILD_PROCESS_INIT;
1305 struct strbuf sb_config = STRBUF_INIT;
1306 char *sub_git_dir = xstrfmt("%s/.git", path);
1307
14228447 1308 sub = submodule_from_path(the_repository, null_oid(), path);
2e612731
PC
1309
1310 if (!sub || !sub->name)
1311 goto cleanup;
1312
1313 displaypath = get_submodule_displaypath(path, prefix);
1314
1315 /* remove the submodule work tree (unless the user already did it) */
1316 if (is_directory(path)) {
1317 struct strbuf sb_rm = STRBUF_INIT;
1318 const char *format;
1319
0adc8ba6
MP
1320 if (is_directory(sub_git_dir)) {
1321 if (!(flags & OPT_QUIET))
1322 warning(_("Submodule work tree '%s' contains a .git "
1323 "directory. This will be replaced with a "
1324 ".git file by using absorbgitdirs."),
1325 displaypath);
1326
1327 absorb_git_dir_into_superproject(path,
1328 ABSORB_GITDIR_RECURSE_SUBMODULES);
1329
1330 }
2e612731
PC
1331
1332 if (!(flags & OPT_FORCE)) {
1333 struct child_process cp_rm = CHILD_PROCESS_INIT;
0b83b2b0 1334
2e612731 1335 cp_rm.git_cmd = 1;
22f9b7f3 1336 strvec_pushl(&cp_rm.args, "rm", "-qn",
f6d8942b 1337 path, NULL);
2e612731
PC
1338
1339 if (run_command(&cp_rm))
1340 die(_("Submodule work tree '%s' contains local "
1341 "modifications; use '-f' to discard them"),
1342 displaypath);
1343 }
1344
1345 strbuf_addstr(&sb_rm, path);
1346
1347 if (!remove_dir_recursively(&sb_rm, 0))
1348 format = _("Cleared directory '%s'\n");
1349 else
1350 format = _("Could not remove submodule work tree '%s'\n");
1351
1352 if (!(flags & OPT_QUIET))
1353 printf(format, displaypath);
1354
8eda5efa
SB
1355 submodule_unset_core_worktree(sub);
1356
2e612731
PC
1357 strbuf_release(&sb_rm);
1358 }
1359
1360 if (mkdir(path, 0777))
1361 printf(_("could not create empty submodule directory %s"),
1362 displaypath);
1363
1364 cp_config.git_cmd = 1;
22f9b7f3
JK
1365 strvec_pushl(&cp_config.args, "config", "--get-regexp", NULL);
1366 strvec_pushf(&cp_config.args, "submodule.%s\\.", sub->name);
2e612731
PC
1367
1368 /* remove the .git/config entries (unless the user already did it) */
1369 if (!capture_command(&cp_config, &sb_config, 0) && sb_config.len) {
1370 char *sub_key = xstrfmt("submodule.%s", sub->name);
0b83b2b0 1371
2e612731
PC
1372 /*
1373 * remove the whole section so we have a clean state when
1374 * the user later decides to init this submodule again
1375 */
1376 git_config_rename_section_in_file(NULL, sub_key, NULL);
1377 if (!(flags & OPT_QUIET))
1378 printf(_("Submodule '%s' (%s) unregistered for path '%s'\n"),
1379 sub->name, sub->url, displaypath);
1380 free(sub_key);
1381 }
1382
1383cleanup:
1384 free(displaypath);
1385 free(sub_git_dir);
1386 strbuf_release(&sb_config);
1387}
1388
1389static void deinit_submodule_cb(const struct cache_entry *list_item,
1390 void *cb_data)
1391{
1392 struct deinit_cb *info = cb_data;
1393 deinit_submodule(list_item->name, info->prefix, info->flags);
1394}
1395
1396static int module_deinit(int argc, const char **argv, const char *prefix)
1397{
1398 struct deinit_cb info = DEINIT_CB_INIT;
1399 struct pathspec pathspec;
1400 struct module_list list = MODULE_LIST_INIT;
1401 int quiet = 0;
1402 int force = 0;
1403 int all = 0;
2e612731 1404 struct option module_deinit_options[] = {
e73fe3dd
ZH
1405 OPT__QUIET(&quiet, N_("suppress submodule status output")),
1406 OPT__FORCE(&force, N_("remove submodule working trees even if they contain local changes"), 0),
1407 OPT_BOOL(0, "all", &all, N_("unregister all submodules")),
2e612731
PC
1408 OPT_END()
1409 };
2e612731
PC
1410 const char *const git_submodule_helper_usage[] = {
1411 N_("git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"),
1412 NULL
1413 };
1414
1415 argc = parse_options(argc, argv, prefix, module_deinit_options,
1416 git_submodule_helper_usage, 0);
1417
1418 if (all && argc) {
1419 error("pathspec and --all are incompatible");
1420 usage_with_options(git_submodule_helper_usage,
1421 module_deinit_options);
1422 }
1423
1424 if (!argc && !all)
1425 die(_("Use '--all' if you really want to deinitialize all submodules"));
1426
1427 if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
9748e39d 1428 return 1;
2e612731
PC
1429
1430 info.prefix = prefix;
1431 if (quiet)
1432 info.flags |= OPT_QUIET;
1433 if (force)
1434 info.flags |= OPT_FORCE;
1435
1436 for_each_listed_submodule(&list, deinit_submodule_cb, &info);
1437
1438 return 0;
1439}
1440
a98b02c1
AR
1441struct module_clone_data {
1442 const char *prefix;
1443 const char *path;
1444 const char *name;
1445 const char *url;
1446 const char *depth;
f05da2b4 1447 struct list_objects_filter_options *filter_options;
a98b02c1
AR
1448 unsigned int quiet: 1;
1449 unsigned int progress: 1;
1450 unsigned int dissociate: 1;
1451 unsigned int require_init: 1;
1452 int single_branch;
1453};
c9911c93 1454#define MODULE_CLONE_DATA_INIT { \
c9911c93
GC
1455 .single_branch = -1, \
1456}
ee8838d1 1457
31224cbd
SB
1458struct submodule_alternate_setup {
1459 const char *submodule_name;
1460 enum SUBMODULE_ALTERNATE_ERROR_MODE {
1461 SUBMODULE_ALTERNATE_ERROR_DIE,
1462 SUBMODULE_ALTERNATE_ERROR_INFO,
1463 SUBMODULE_ALTERNATE_ERROR_IGNORE
1464 } error_mode;
1465 struct string_list *reference;
1466};
f69a6e4f
ÆAB
1467#define SUBMODULE_ALTERNATE_SETUP_INIT { \
1468 .error_mode = SUBMODULE_ALTERNATE_ERROR_IGNORE, \
1469}
31224cbd 1470
4f3e57ef
JT
1471static const char alternate_error_advice[] = N_(
1472"An alternate computed from a superproject's alternate is invalid.\n"
1473"To allow Git to clone without an alternate in such a case, set\n"
1474"submodule.alternateErrorStrategy to 'info' or, equivalently, clone with\n"
1475"'--reference-if-able' instead of '--reference'."
1476);
1477
31224cbd 1478static int add_possible_reference_from_superproject(
263db403 1479 struct object_directory *odb, void *sas_cb)
31224cbd
SB
1480{
1481 struct submodule_alternate_setup *sas = sas_cb;
b2ac148f 1482 size_t len;
31224cbd 1483
31224cbd
SB
1484 /*
1485 * If the alternate object store is another repository, try the
bf03b790 1486 * standard layout with .git/(modules/<name>)+/objects
31224cbd 1487 */
263db403 1488 if (strip_suffix(odb->path, "/objects", &len)) {
ce125d43 1489 struct repository alternate;
31224cbd
SB
1490 char *sm_alternate;
1491 struct strbuf sb = STRBUF_INIT;
1492 struct strbuf err = STRBUF_INIT;
263db403 1493 strbuf_add(&sb, odb->path, len);
597f9134 1494
1e8697b5
ÆAB
1495 if (repo_init(&alternate, sb.buf, NULL) < 0)
1496 die(_("could not get a repository handle for gitdir '%s'"),
1497 sb.buf);
ce125d43 1498
31224cbd
SB
1499 /*
1500 * We need to end the new path with '/' to mark it as a dir,
1501 * otherwise a submodule name containing '/' will be broken
1502 * as the last part of a missing submodule reference would
1503 * be taken as a file name.
1504 */
ce125d43
JT
1505 strbuf_reset(&sb);
1506 submodule_name_to_gitdir(&sb, &alternate, sas->submodule_name);
1507 strbuf_addch(&sb, '/');
1508 repo_clear(&alternate);
31224cbd
SB
1509
1510 sm_alternate = compute_alternate_path(sb.buf, &err);
1511 if (sm_alternate) {
1512 string_list_append(sas->reference, xstrdup(sb.buf));
1513 free(sm_alternate);
1514 } else {
1515 switch (sas->error_mode) {
1516 case SUBMODULE_ALTERNATE_ERROR_DIE:
ed9bff08 1517 if (advice_enabled(ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE))
4f3e57ef 1518 advise(_(alternate_error_advice));
31224cbd
SB
1519 die(_("submodule '%s' cannot add alternate: %s"),
1520 sas->submodule_name, err.buf);
1521 case SUBMODULE_ALTERNATE_ERROR_INFO:
1a878714 1522 fprintf_ln(stderr, _("submodule '%s' cannot add alternate: %s"),
31224cbd
SB
1523 sas->submodule_name, err.buf);
1524 case SUBMODULE_ALTERNATE_ERROR_IGNORE:
1525 ; /* nothing */
1526 }
1527 }
1528 strbuf_release(&sb);
1529 }
1530
31224cbd
SB
1531 return 0;
1532}
1533
1534static void prepare_possible_alternates(const char *sm_name,
1535 struct string_list *reference)
1536{
1537 char *sm_alternate = NULL, *error_strategy = NULL;
1538 struct submodule_alternate_setup sas = SUBMODULE_ALTERNATE_SETUP_INIT;
1539
1540 git_config_get_string("submodule.alternateLocation", &sm_alternate);
1541 if (!sm_alternate)
1542 return;
1543
1544 git_config_get_string("submodule.alternateErrorStrategy", &error_strategy);
1545
1546 if (!error_strategy)
1547 error_strategy = xstrdup("die");
1548
1549 sas.submodule_name = sm_name;
1550 sas.reference = reference;
1551 if (!strcmp(error_strategy, "die"))
1552 sas.error_mode = SUBMODULE_ALTERNATE_ERROR_DIE;
1553 else if (!strcmp(error_strategy, "info"))
1554 sas.error_mode = SUBMODULE_ALTERNATE_ERROR_INFO;
1555 else if (!strcmp(error_strategy, "ignore"))
1556 sas.error_mode = SUBMODULE_ALTERNATE_ERROR_IGNORE;
1557 else
1558 die(_("Value '%s' for submodule.alternateErrorStrategy is not recognized"), error_strategy);
1559
1560 if (!strcmp(sm_alternate, "superproject"))
1561 foreach_alt_odb(add_possible_reference_from_superproject, &sas);
1562 else if (!strcmp(sm_alternate, "no"))
1563 ; /* do nothing */
1564 else
1565 die(_("Value '%s' for submodule.alternateLocation is not recognized"), sm_alternate);
1566
1567 free(sm_alternate);
1568 free(error_strategy);
1569}
1570
9bdf5277 1571static char *clone_submodule_sm_gitdir(const char *name)
ee8838d1 1572{
a98b02c1 1573 struct strbuf sb = STRBUF_INIT;
9bdf5277 1574 char *sm_gitdir;
a98b02c1 1575
9bdf5277 1576 submodule_name_to_gitdir(&sb, the_repository, name);
a98b02c1 1577 sm_gitdir = absolute_pathdup(sb.buf);
9bdf5277
ÆAB
1578 strbuf_release(&sb);
1579
1580 return sm_gitdir;
1581}
1582
6fac5b2f
ÆAB
1583static int clone_submodule(const struct module_clone_data *clone_data,
1584 struct string_list *reference)
9bdf5277
ÆAB
1585{
1586 char *p;
1587 char *sm_gitdir = clone_submodule_sm_gitdir(clone_data->name);
1588 char *sm_alternate = NULL, *error_strategy = NULL;
1589 struct child_process cp = CHILD_PROCESS_INIT;
6fac5b2f 1590 const char *clone_data_path;
a98b02c1 1591
21496b4c 1592 if (!is_absolute_path(clone_data->path))
6fac5b2f
ÆAB
1593 clone_data_path = xstrfmt("%s/%s", get_git_work_tree(),
1594 clone_data->path);
21496b4c 1595 else
6fac5b2f 1596 clone_data_path = xstrdup(clone_data->path);
a98b02c1
AR
1597
1598 if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0)
1599 die(_("refusing to create/use '%s' in another submodule's "
1600 "git dir"), sm_gitdir);
1601
1602 if (!file_exists(sm_gitdir)) {
1603 if (safe_create_leading_directories_const(sm_gitdir) < 0)
1604 die(_("could not create directory '%s'"), sm_gitdir);
1605
6fac5b2f 1606 prepare_possible_alternates(clone_data->name, reference);
a98b02c1
AR
1607
1608 strvec_push(&cp.args, "clone");
1609 strvec_push(&cp.args, "--no-checkout");
1610 if (clone_data->quiet)
1611 strvec_push(&cp.args, "--quiet");
1612 if (clone_data->progress)
1613 strvec_push(&cp.args, "--progress");
1614 if (clone_data->depth && *(clone_data->depth))
1615 strvec_pushl(&cp.args, "--depth", clone_data->depth, NULL);
6fac5b2f 1616 if (reference->nr) {
a98b02c1 1617 struct string_list_item *item;
0b83b2b0 1618
6fac5b2f 1619 for_each_string_list_item(item, reference)
a98b02c1
AR
1620 strvec_pushl(&cp.args, "--reference",
1621 item->string, NULL);
1622 }
1623 if (clone_data->dissociate)
1624 strvec_push(&cp.args, "--dissociate");
1625 if (sm_gitdir && *sm_gitdir)
1626 strvec_pushl(&cp.args, "--separate-git-dir", sm_gitdir, NULL);
f05da2b4
JS
1627 if (clone_data->filter_options && clone_data->filter_options->choice)
1628 strvec_pushf(&cp.args, "--filter=%s",
1629 expand_list_objects_filter_spec(
1630 clone_data->filter_options));
a98b02c1
AR
1631 if (clone_data->single_branch >= 0)
1632 strvec_push(&cp.args, clone_data->single_branch ?
1633 "--single-branch" :
1634 "--no-single-branch");
1635
1636 strvec_push(&cp.args, "--");
1637 strvec_push(&cp.args, clone_data->url);
6fac5b2f 1638 strvec_push(&cp.args, clone_data_path);
a98b02c1
AR
1639
1640 cp.git_cmd = 1;
29fda24d 1641 prepare_submodule_repo_env(&cp.env);
a98b02c1
AR
1642 cp.no_stdin = 1;
1643
1644 if(run_command(&cp))
1645 die(_("clone of '%s' into submodule path '%s' failed"),
6fac5b2f 1646 clone_data->url, clone_data_path);
a98b02c1 1647 } else {
21496b4c
ÆAB
1648 char *path;
1649
6fac5b2f
ÆAB
1650 if (clone_data->require_init && !access(clone_data_path, X_OK) &&
1651 !is_empty_dir(clone_data_path))
1652 die(_("directory not empty: '%s'"), clone_data_path);
1653 if (safe_create_leading_directories_const(clone_data_path) < 0)
1654 die(_("could not create directory '%s'"), clone_data_path);
21496b4c
ÆAB
1655 path = xstrfmt("%s/index", sm_gitdir);
1656 unlink_or_warn(path);
1657 free(path);
a98b02c1
AR
1658 }
1659
6fac5b2f 1660 connect_work_tree_and_git_dir(clone_data_path, sm_gitdir, 0);
a98b02c1 1661
6fac5b2f 1662 p = git_pathdup_submodule(clone_data_path, "config");
a98b02c1 1663 if (!p)
6fac5b2f 1664 die(_("could not get submodule directory for '%s'"), clone_data_path);
a98b02c1
AR
1665
1666 /* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */
1667 git_config_get_string("submodule.alternateLocation", &sm_alternate);
1668 if (sm_alternate)
1669 git_config_set_in_file(p, "submodule.alternateLocation",
1670 sm_alternate);
1671 git_config_get_string("submodule.alternateErrorStrategy", &error_strategy);
1672 if (error_strategy)
1673 git_config_set_in_file(p, "submodule.alternateErrorStrategy",
1674 error_strategy);
1675
1676 free(sm_alternate);
1677 free(error_strategy);
1678
a98b02c1
AR
1679 free(sm_gitdir);
1680 free(p);
1681 return 0;
1682}
1683
1684static int module_clone(int argc, const char **argv, const char *prefix)
1685{
1686 int dissociate = 0, quiet = 0, progress = 0, require_init = 0;
1687 struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;
4b82d75b 1688 struct list_objects_filter_options filter_options = { 0 };
6fac5b2f 1689 struct string_list reference = STRING_LIST_INIT_NODUP;
ee8838d1 1690 struct option module_clone_options[] = {
a98b02c1 1691 OPT_STRING(0, "prefix", &clone_data.prefix,
ee8838d1
SB
1692 N_("path"),
1693 N_("alternative anchor for relative paths")),
a98b02c1 1694 OPT_STRING(0, "path", &clone_data.path,
ee8838d1
SB
1695 N_("path"),
1696 N_("where the new submodule will be cloned to")),
a98b02c1 1697 OPT_STRING(0, "name", &clone_data.name,
ee8838d1
SB
1698 N_("string"),
1699 N_("name of the new submodule")),
a98b02c1 1700 OPT_STRING(0, "url", &clone_data.url,
ee8838d1
SB
1701 N_("string"),
1702 N_("url where to clone the submodule from")),
6fac5b2f 1703 OPT_STRING_LIST(0, "reference", &reference,
965dbea0 1704 N_("repo"),
ee8838d1 1705 N_("reference repository")),
a0ef2934
CF
1706 OPT_BOOL(0, "dissociate", &dissociate,
1707 N_("use --reference only while cloning")),
a98b02c1 1708 OPT_STRING(0, "depth", &clone_data.depth,
ee8838d1
SB
1709 N_("string"),
1710 N_("depth for shallow clones")),
9e1f22c8 1711 OPT__QUIET(&quiet, "suppress output for cloning a submodule"),
72c5f883
JK
1712 OPT_BOOL(0, "progress", &progress,
1713 N_("force cloning progress")),
0060fd15
JS
1714 OPT_BOOL(0, "require-init", &require_init,
1715 N_("disallow cloning into non-empty directory")),
a98b02c1 1716 OPT_BOOL(0, "single-branch", &clone_data.single_branch,
132f600b 1717 N_("clone only one branch, HEAD or --branch")),
f05da2b4 1718 OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
ee8838d1
SB
1719 OPT_END()
1720 };
ee8838d1
SB
1721 const char *const git_submodule_helper_usage[] = {
1722 N_("git submodule--helper clone [--prefix=<path>] [--quiet] "
7dad2633 1723 "[--reference <repository>] [--name <name>] [--depth <depth>] "
5da9560e 1724 "[--single-branch] [--filter <filter-spec>] "
7dad2633 1725 "--url <url> --path <path>"),
ee8838d1
SB
1726 NULL
1727 };
1728
1729 argc = parse_options(argc, argv, prefix, module_clone_options,
1730 git_submodule_helper_usage, 0);
1731
a98b02c1
AR
1732 clone_data.dissociate = !!dissociate;
1733 clone_data.quiet = !!quiet;
1734 clone_data.progress = !!progress;
1735 clone_data.require_init = !!require_init;
f05da2b4 1736 clone_data.filter_options = &filter_options;
a98b02c1
AR
1737
1738 if (argc || !clone_data.url || !clone_data.path || !*(clone_data.path))
08e0970a
JK
1739 usage_with_options(git_submodule_helper_usage,
1740 module_clone_options);
1741
6fac5b2f 1742 clone_submodule(&clone_data, &reference);
f05da2b4 1743 list_objects_filter_release(&filter_options);
ee8838d1
SB
1744 return 0;
1745}
74703a1e 1746
484f9150
ÆAB
1747static int determine_submodule_update_strategy(struct repository *r,
1748 int just_cloned,
1749 const char *path,
1750 enum submodule_update_type update,
1751 struct submodule_update_strategy *out)
ee69b2a9 1752{
14228447 1753 const struct submodule *sub = submodule_from_path(r, null_oid(), path);
ee69b2a9
SB
1754 char *key;
1755 const char *val;
484f9150 1756 int ret;
ee69b2a9
SB
1757
1758 key = xstrfmt("submodule.%s.update", sub->name);
1759
1760 if (update) {
b788fc67 1761 out->type = update;
f1de981e 1762 } else if (!repo_config_get_string_tmp(r, key, &val)) {
484f9150
ÆAB
1763 if (parse_submodule_update_strategy(val, out) < 0) {
1764 ret = die_message(_("Invalid update mode '%s' configured for submodule path '%s'"),
1765 val, path);
1766 goto cleanup;
1767 }
ee69b2a9 1768 } else if (sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
c1547450
JN
1769 if (sub->update_strategy.type == SM_UPDATE_COMMAND)
1770 BUG("how did we read update = !command from .gitmodules?");
ee69b2a9
SB
1771 out->type = sub->update_strategy.type;
1772 out->command = sub->update_strategy.command;
1773 } else
1774 out->type = SM_UPDATE_CHECKOUT;
1775
1776 if (just_cloned &&
1777 (out->type == SM_UPDATE_MERGE ||
1778 out->type == SM_UPDATE_REBASE ||
1779 out->type == SM_UPDATE_NONE))
1780 out->type = SM_UPDATE_CHECKOUT;
1781
484f9150
ÆAB
1782 ret = 0;
1783cleanup:
ee69b2a9 1784 free(key);
484f9150 1785 return ret;
ee69b2a9
SB
1786}
1787
f1d15713
SB
1788struct update_clone_data {
1789 const struct submodule *sub;
1790 struct object_id oid;
1791 unsigned just_cloned;
1792};
1793
48308681 1794struct submodule_update_clone {
c9911c93 1795 /* index into 'update_data.list', the list of submodules to look into for cloning */
48308681 1796 int current;
48308681
SB
1797
1798 /* configuration parameters which are passed on to the children */
1da635b8 1799 const struct update_data *update_data;
48308681 1800
b3c5f5cb 1801 /* to be consumed by update_submodule() */
f1d15713
SB
1802 struct update_clone_data *update_clone;
1803 int update_clone_nr; int update_clone_alloc;
48308681
SB
1804
1805 /* If we want to stop as fast as possible and return an error */
1806 unsigned quickstop : 1;
665b35ec
SB
1807
1808 /* failed clones to be retried again */
1809 const struct cache_entry **failed_clones;
1810 int failed_clones_nr, failed_clones_alloc;
48308681 1811};
c9911c93 1812#define SUBMODULE_UPDATE_CLONE_INIT { 0 }
48308681 1813
c51f8f94 1814struct update_data {
c9911c93 1815 const char *prefix;
c51f8f94 1816 const char *displaypath;
b788fc67 1817 enum submodule_update_type update_default;
c51f8f94 1818 struct object_id suboid;
c9911c93 1819 struct string_list references;
c51f8f94 1820 struct submodule_update_strategy update_strategy;
c9911c93
GC
1821 struct list_objects_filter_options *filter_options;
1822 struct module_list list;
c51f8f94 1823 int depth;
c9911c93
GC
1824 int max_jobs;
1825 int single_branch;
1826 int recommend_shallow;
1827 unsigned int require_init;
ed9c8485
ÆAB
1828 unsigned int force;
1829 unsigned int quiet;
1830 unsigned int nofetch;
1012a5cb 1831 unsigned int remote;
c9911c93
GC
1832 unsigned int progress;
1833 unsigned int dissociate;
1834 unsigned int init;
1835 unsigned int warn_if_uninitialized;
b3c5f5cb
AR
1836 unsigned int recursive;
1837
1838 /* copied over from update_clone_data */
1839 struct object_id oid;
1840 unsigned int just_cloned;
1841 const char *sm_path;
c51f8f94 1842};
c9911c93
GC
1843#define UPDATE_DATA_INIT { \
1844 .update_strategy = SUBMODULE_UPDATE_STRATEGY_INIT, \
1845 .list = MODULE_LIST_INIT, \
1846 .recommend_shallow = -1, \
1847 .references = STRING_LIST_INIT_DUP, \
1848 .single_branch = -1, \
1849 .max_jobs = 1, \
c9911c93 1850}
08fdbdb1
SB
1851
1852static void next_submodule_warn_missing(struct submodule_update_clone *suc,
1853 struct strbuf *out, const char *displaypath)
1854{
1855 /*
1856 * Only mention uninitialized submodules when their
1857 * paths have been specified.
1858 */
c9911c93 1859 if (suc->update_data->warn_if_uninitialized) {
08fdbdb1
SB
1860 strbuf_addf(out,
1861 _("Submodule path '%s' not initialized"),
1862 displaypath);
1863 strbuf_addch(out, '\n');
1864 strbuf_addstr(out,
1865 _("Maybe you want to use 'update --init'?"));
1866 strbuf_addch(out, '\n');
1867 }
1868}
1869
48308681
SB
1870/**
1871 * Determine whether 'ce' needs to be cloned. If so, prepare the 'child' to
1872 * run the clone. Returns 1 if 'ce' needs to be cloned, 0 otherwise.
1873 */
1874static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
1875 struct child_process *child,
1876 struct submodule_update_clone *suc,
1877 struct strbuf *out)
1878{
1879 const struct submodule *sub = NULL;
ec6141a0
BW
1880 const char *url = NULL;
1881 const char *update_string;
1882 enum submodule_update_type update_type;
1883 char *key;
1da635b8 1884 const struct update_data *ud = suc->update_data;
5ad87271 1885 char *displaypath = get_submodule_displaypath(ce->name, ud->prefix);
48308681 1886 struct strbuf sb = STRBUF_INIT;
48308681 1887 int needs_cloning = 0;
e0a862fd 1888 int need_free_url = 0;
48308681
SB
1889
1890 if (ce_stage(ce)) {
618b8445 1891 strbuf_addf(out, _("Skipping unmerged submodule %s"), displaypath);
48308681
SB
1892 strbuf_addch(out, '\n');
1893 goto cleanup;
1894 }
1895
14228447 1896 sub = submodule_from_path(the_repository, null_oid(), ce->name);
48308681 1897
08fdbdb1
SB
1898 if (!sub) {
1899 next_submodule_warn_missing(suc, out, displaypath);
1900 goto cleanup;
1901 }
1902
ec6141a0 1903 key = xstrfmt("submodule.%s.update", sub->name);
f1de981e 1904 if (!repo_config_get_string_tmp(the_repository, key, &update_string)) {
ec6141a0
BW
1905 update_type = parse_submodule_update_type(update_string);
1906 } else {
1907 update_type = sub->update_strategy.type;
1908 }
1909 free(key);
1910
c9911c93
GC
1911 if (suc->update_data->update_strategy.type == SM_UPDATE_NONE
1912 || (suc->update_data->update_strategy.type == SM_UPDATE_UNSPECIFIED
ec6141a0 1913 && update_type == SM_UPDATE_NONE)) {
48308681
SB
1914 strbuf_addf(out, _("Skipping submodule '%s'"), displaypath);
1915 strbuf_addch(out, '\n');
1916 goto cleanup;
1917 }
1918
ee92ab99 1919 /* Check if the submodule has been initialized. */
627d9342 1920 if (!is_submodule_active(the_repository, ce->name)) {
08fdbdb1 1921 next_submodule_warn_missing(suc, out, displaypath);
48308681
SB
1922 goto cleanup;
1923 }
1924
ec6141a0
BW
1925 strbuf_reset(&sb);
1926 strbuf_addf(&sb, "submodule.%s.url", sub->name);
f1de981e 1927 if (repo_config_get_string_tmp(the_repository, sb.buf, &url)) {
e0a862fd
SB
1928 if (starts_with_dot_slash(sub->url) ||
1929 starts_with_dot_dot_slash(sub->url)) {
de0fcbe0 1930 url = resolve_relative_url(sub->url, NULL, 0);
e0a862fd
SB
1931 need_free_url = 1;
1932 } else
1933 url = sub->url;
1934 }
ec6141a0 1935
48308681
SB
1936 strbuf_reset(&sb);
1937 strbuf_addf(&sb, "%s/.git", ce->name);
1938 needs_cloning = !file_exists(sb.buf);
1939
f1d15713
SB
1940 ALLOC_GROW(suc->update_clone, suc->update_clone_nr + 1,
1941 suc->update_clone_alloc);
1942 oidcpy(&suc->update_clone[suc->update_clone_nr].oid, &ce->oid);
1943 suc->update_clone[suc->update_clone_nr].just_cloned = needs_cloning;
1944 suc->update_clone[suc->update_clone_nr].sub = sub;
1945 suc->update_clone_nr++;
48308681
SB
1946
1947 if (!needs_cloning)
1948 goto cleanup;
1949
1950 child->git_cmd = 1;
1951 child->no_stdin = 1;
1952 child->stdout_to_stderr = 1;
1953 child->err = -1;
22f9b7f3
JK
1954 strvec_push(&child->args, "submodule--helper");
1955 strvec_push(&child->args, "clone");
c9911c93 1956 if (suc->update_data->progress)
22f9b7f3 1957 strvec_push(&child->args, "--progress");
c9911c93 1958 if (suc->update_data->quiet)
22f9b7f3 1959 strvec_push(&child->args, "--quiet");
c9911c93
GC
1960 if (suc->update_data->prefix)
1961 strvec_pushl(&child->args, "--prefix", suc->update_data->prefix, NULL);
1962 if (suc->update_data->recommend_shallow && sub->recommend_shallow == 1)
22f9b7f3 1963 strvec_push(&child->args, "--depth=1");
c9911c93
GC
1964 else if (suc->update_data->depth)
1965 strvec_pushf(&child->args, "--depth=%d", suc->update_data->depth);
1966 if (suc->update_data->filter_options && suc->update_data->filter_options->choice)
f05da2b4 1967 strvec_pushf(&child->args, "--filter=%s",
c9911c93
GC
1968 expand_list_objects_filter_spec(suc->update_data->filter_options));
1969 if (suc->update_data->require_init)
22f9b7f3
JK
1970 strvec_push(&child->args, "--require-init");
1971 strvec_pushl(&child->args, "--path", sub->path, NULL);
1972 strvec_pushl(&child->args, "--name", sub->name, NULL);
1973 strvec_pushl(&child->args, "--url", url, NULL);
c9911c93 1974 if (suc->update_data->references.nr) {
5f50f33e 1975 struct string_list_item *item;
0b83b2b0 1976
c9911c93 1977 for_each_string_list_item(item, &suc->update_data->references)
22f9b7f3 1978 strvec_pushl(&child->args, "--reference", item->string, NULL);
5f50f33e 1979 }
c9911c93 1980 if (suc->update_data->dissociate)
22f9b7f3 1981 strvec_push(&child->args, "--dissociate");
c9911c93
GC
1982 if (suc->update_data->single_branch >= 0)
1983 strvec_push(&child->args, suc->update_data->single_branch ?
132f600b
ES
1984 "--single-branch" :
1985 "--no-single-branch");
48308681
SB
1986
1987cleanup:
618b8445 1988 free(displaypath);
9101c8ea 1989 strbuf_release(&sb);
e0a862fd
SB
1990 if (need_free_url)
1991 free((void*)url);
48308681
SB
1992
1993 return needs_cloning;
1994}
1995
1996static int update_clone_get_next_task(struct child_process *child,
1997 struct strbuf *err,
1998 void *suc_cb,
665b35ec 1999 void **idx_task_cb)
48308681
SB
2000{
2001 struct submodule_update_clone *suc = suc_cb;
665b35ec
SB
2002 const struct cache_entry *ce;
2003 int index;
48308681 2004
c9911c93
GC
2005 for (; suc->current < suc->update_data->list.nr; suc->current++) {
2006 ce = suc->update_data->list.entries[suc->current];
48308681 2007 if (prepare_to_clone_next_submodule(ce, child, suc, err)) {
665b35ec 2008 int *p = xmalloc(sizeof(*p));
0b83b2b0 2009
665b35ec
SB
2010 *p = suc->current;
2011 *idx_task_cb = p;
48308681
SB
2012 suc->current++;
2013 return 1;
2014 }
2015 }
665b35ec
SB
2016
2017 /*
2018 * The loop above tried cloning each submodule once, now try the
2019 * stragglers again, which we can imagine as an extension of the
2020 * entry list.
2021 */
c9911c93 2022 index = suc->current - suc->update_data->list.nr;
665b35ec
SB
2023 if (index < suc->failed_clones_nr) {
2024 int *p;
0b83b2b0 2025
665b35ec 2026 ce = suc->failed_clones[index];
2201ee09
SB
2027 if (!prepare_to_clone_next_submodule(ce, child, suc, err)) {
2028 suc->current ++;
a22ae753
RS
2029 strbuf_addstr(err, "BUG: submodule considered for "
2030 "cloning, doesn't need cloning "
2031 "any more?\n");
2201ee09
SB
2032 return 0;
2033 }
665b35ec
SB
2034 p = xmalloc(sizeof(*p));
2035 *p = suc->current;
2036 *idx_task_cb = p;
2037 suc->current ++;
2038 return 1;
2039 }
2040
48308681
SB
2041 return 0;
2042}
2043
2044static int update_clone_start_failure(struct strbuf *err,
2045 void *suc_cb,
665b35ec 2046 void *idx_task_cb)
48308681
SB
2047{
2048 struct submodule_update_clone *suc = suc_cb;
0b83b2b0 2049
48308681
SB
2050 suc->quickstop = 1;
2051 return 1;
2052}
2053
2054static int update_clone_task_finished(int result,
2055 struct strbuf *err,
2056 void *suc_cb,
665b35ec 2057 void *idx_task_cb)
48308681 2058{
665b35ec 2059 const struct cache_entry *ce;
48308681 2060 struct submodule_update_clone *suc = suc_cb;
c1e860f1 2061 int *idxP = idx_task_cb;
665b35ec 2062 int idx = *idxP;
0b83b2b0 2063
665b35ec
SB
2064 free(idxP);
2065
48308681
SB
2066 if (!result)
2067 return 0;
2068
c9911c93
GC
2069 if (idx < suc->update_data->list.nr) {
2070 ce = suc->update_data->list.entries[idx];
665b35ec
SB
2071 strbuf_addf(err, _("Failed to clone '%s'. Retry scheduled"),
2072 ce->name);
2073 strbuf_addch(err, '\n');
2074 ALLOC_GROW(suc->failed_clones,
2075 suc->failed_clones_nr + 1,
2076 suc->failed_clones_alloc);
2077 suc->failed_clones[suc->failed_clones_nr++] = ce;
2078 return 0;
2079 } else {
c9911c93 2080 idx -= suc->update_data->list.nr;
665b35ec
SB
2081 ce = suc->failed_clones[idx];
2082 strbuf_addf(err, _("Failed to clone '%s' a second time, aborting"),
2083 ce->name);
2084 strbuf_addch(err, '\n');
2085 suc->quickstop = 1;
2086 return 1;
2087 }
2088
2089 return 0;
48308681
SB
2090}
2091
05744997
AO
2092static int git_update_clone_config(const char *var, const char *value,
2093 void *cb)
f20e7c1e
BW
2094{
2095 int *max_jobs = cb;
0b83b2b0 2096
f20e7c1e
BW
2097 if (!strcmp(var, "submodule.fetchjobs"))
2098 *max_jobs = parse_submodule_fetchjobs(var, value);
2099 return 0;
2100}
2101
a253be68 2102static int is_tip_reachable(const char *path, const struct object_id *oid)
c51f8f94
AR
2103{
2104 struct child_process cp = CHILD_PROCESS_INIT;
2105 struct strbuf rev = STRBUF_INIT;
2106 char *hex = oid_to_hex(oid);
2107
2108 cp.git_cmd = 1;
2109 cp.dir = xstrdup(path);
2110 cp.no_stderr = 1;
2111 strvec_pushl(&cp.args, "rev-list", "-n", "1", hex, "--not", "--all", NULL);
2112
29fda24d 2113 prepare_submodule_repo_env(&cp.env);
c51f8f94
AR
2114
2115 if (capture_command(&cp, &rev, GIT_MAX_HEXSZ + 1) || rev.len)
2116 return 0;
2117
2118 return 1;
2119}
2120
a253be68
ÆAB
2121static int fetch_in_submodule(const char *module_path, int depth, int quiet,
2122 const struct object_id *oid)
c51f8f94
AR
2123{
2124 struct child_process cp = CHILD_PROCESS_INIT;
2125
29fda24d 2126 prepare_submodule_repo_env(&cp.env);
c51f8f94
AR
2127 cp.git_cmd = 1;
2128 cp.dir = xstrdup(module_path);
2129
2130 strvec_push(&cp.args, "fetch");
2131 if (quiet)
2132 strvec_push(&cp.args, "--quiet");
2133 if (depth)
2134 strvec_pushf(&cp.args, "--depth=%d", depth);
2135 if (oid) {
2136 char *hex = oid_to_hex(oid);
2137 char *remote = get_default_remote();
0b83b2b0 2138
c51f8f94 2139 strvec_pushl(&cp.args, remote, hex, NULL);
41a86b64 2140 free(remote);
c51f8f94
AR
2141 }
2142
2143 return run_command(&cp);
2144}
2145
d905d443 2146static int run_update_command(const struct update_data *ud, int subforce)
c51f8f94 2147{
3c3558f0 2148 struct child_process cp = CHILD_PROCESS_INIT;
c51f8f94 2149 char *oid = oid_to_hex(&ud->oid);
a03c01de 2150 int ret;
c51f8f94
AR
2151
2152 switch (ud->update_strategy.type) {
2153 case SM_UPDATE_CHECKOUT:
3c3558f0
AR
2154 cp.git_cmd = 1;
2155 strvec_pushl(&cp.args, "checkout", "-q", NULL);
c51f8f94 2156 if (subforce)
3c3558f0 2157 strvec_push(&cp.args, "-f");
c51f8f94
AR
2158 break;
2159 case SM_UPDATE_REBASE:
3c3558f0
AR
2160 cp.git_cmd = 1;
2161 strvec_push(&cp.args, "rebase");
c51f8f94 2162 if (ud->quiet)
3c3558f0 2163 strvec_push(&cp.args, "--quiet");
c51f8f94
AR
2164 break;
2165 case SM_UPDATE_MERGE:
3c3558f0
AR
2166 cp.git_cmd = 1;
2167 strvec_push(&cp.args, "merge");
c51f8f94 2168 if (ud->quiet)
3c3558f0 2169 strvec_push(&cp.args, "--quiet");
c51f8f94
AR
2170 break;
2171 case SM_UPDATE_COMMAND:
3c3558f0
AR
2172 cp.use_shell = 1;
2173 strvec_push(&cp.args, ud->update_strategy.command);
c51f8f94
AR
2174 break;
2175 default:
08c2e778
ÆAB
2176 BUG("unexpected update strategy type: %d",
2177 ud->update_strategy.type);
c51f8f94 2178 }
3c3558f0 2179 strvec_push(&cp.args, oid);
c51f8f94 2180
3c3558f0 2181 cp.dir = xstrdup(ud->sm_path);
29fda24d 2182 prepare_submodule_repo_env(&cp.env);
a03c01de 2183 if ((ret = run_command(&cp))) {
c51f8f94
AR
2184 switch (ud->update_strategy.type) {
2185 case SM_UPDATE_CHECKOUT:
55b3f12c
GC
2186 die_message(_("Unable to checkout '%s' in submodule path '%s'"),
2187 oid, ud->displaypath);
a03c01de 2188 /* No "ret" assignment, use "git checkout"'s */
c51f8f94
AR
2189 break;
2190 case SM_UPDATE_REBASE:
6870cdc3
ÆAB
2191 ret = die_message(_("Unable to rebase '%s' in submodule path '%s'"),
2192 oid, ud->displaypath);
c51f8f94
AR
2193 break;
2194 case SM_UPDATE_MERGE:
6870cdc3
ÆAB
2195 ret = die_message(_("Unable to merge '%s' in submodule path '%s'"),
2196 oid, ud->displaypath);
c51f8f94
AR
2197 break;
2198 case SM_UPDATE_COMMAND:
6870cdc3
ÆAB
2199 ret = die_message(_("Execution of '%s %s' failed in submodule path '%s'"),
2200 ud->update_strategy.command, oid, ud->displaypath);
c51f8f94
AR
2201 break;
2202 default:
08c2e778
ÆAB
2203 BUG("unexpected update strategy type: %d",
2204 ud->update_strategy.type);
c51f8f94 2205 }
55b3f12c 2206
6870cdc3 2207 return ret;
c51f8f94
AR
2208 }
2209
55b3f12c
GC
2210 if (ud->quiet)
2211 return 0;
2212
c51f8f94
AR
2213 switch (ud->update_strategy.type) {
2214 case SM_UPDATE_CHECKOUT:
2215 printf(_("Submodule path '%s': checked out '%s'\n"),
2216 ud->displaypath, oid);
2217 break;
2218 case SM_UPDATE_REBASE:
2219 printf(_("Submodule path '%s': rebased into '%s'\n"),
2220 ud->displaypath, oid);
2221 break;
2222 case SM_UPDATE_MERGE:
2223 printf(_("Submodule path '%s': merged in '%s'\n"),
2224 ud->displaypath, oid);
2225 break;
2226 case SM_UPDATE_COMMAND:
2227 printf(_("Submodule path '%s': '%s %s'\n"),
2228 ud->displaypath, ud->update_strategy.command, oid);
2229 break;
2230 default:
08c2e778
ÆAB
2231 BUG("unexpected update strategy type: %d",
2232 ud->update_strategy.type);
c51f8f94
AR
2233 }
2234
2235 return 0;
2236}
2237
d905d443 2238static int run_update_procedure(const struct update_data *ud)
c51f8f94
AR
2239{
2240 int subforce = is_null_oid(&ud->suboid) || ud->force;
2241
2242 if (!ud->nofetch) {
2243 /*
2244 * Run fetch only if `oid` isn't present or it
2245 * is not reachable from a ref.
2246 */
2247 if (!is_tip_reachable(ud->sm_path, &ud->oid) &&
2248 fetch_in_submodule(ud->sm_path, ud->depth, ud->quiet, NULL) &&
2249 !ud->quiet)
2250 fprintf_ln(stderr,
2251 _("Unable to fetch in submodule path '%s'; "
2252 "trying to directly fetch %s:"),
2253 ud->displaypath, oid_to_hex(&ud->oid));
2254 /*
2255 * Now we tried the usual fetch, but `oid` may
2256 * not be reachable from any of the refs.
2257 */
2258 if (!is_tip_reachable(ud->sm_path, &ud->oid) &&
2259 fetch_in_submodule(ud->sm_path, ud->depth, ud->quiet, &ud->oid))
ac350155
ÆAB
2260 return die_message(_("Fetched in submodule path '%s', but it did not "
2261 "contain %s. Direct fetching of that commit failed."),
2262 ud->displaypath, oid_to_hex(&ud->oid));
c51f8f94
AR
2263 }
2264
d905d443 2265 return run_update_command(ud, subforce);
c51f8f94
AR
2266}
2267
f3875ab1
GC
2268static const char *remote_submodule_branch(const char *path)
2269{
2270 const struct submodule *sub;
2271 const char *branch = NULL;
2272 char *key;
2273
2274 sub = submodule_from_path(the_repository, null_oid(), path);
2275 if (!sub)
2276 return NULL;
2277
2278 key = xstrfmt("submodule.%s.branch", sub->name);
2279 if (repo_config_get_string_tmp(the_repository, key, &branch))
2280 branch = sub->branch;
2281 free(key);
2282
2283 if (!branch)
2284 return "HEAD";
2285
2286 if (!strcmp(branch, ".")) {
2287 const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
2288
2289 if (!refname)
2290 die(_("No such ref: %s"), "HEAD");
2291
2292 /* detached HEAD */
2293 if (!strcmp(refname, "HEAD"))
2294 die(_("Submodule (%s) branch configured to inherit "
2295 "branch from superproject, but the superproject "
2296 "is not on any branch"), sub->name);
2297
2298 if (!skip_prefix(refname, "refs/heads/", &refname))
2299 die(_("Expecting a full ref name, got %s"), refname);
2300 return refname;
2301 }
2302
2303 return branch;
2304}
2305
ac350155 2306static int ensure_core_worktree(const char *path)
f3875ab1
GC
2307{
2308 const char *cw;
2309 struct repository subrepo;
2310
2311 if (repo_submodule_init(&subrepo, the_repository, path, null_oid()))
ac350155
ÆAB
2312 return die_message(_("could not get a repository handle for submodule '%s'"),
2313 path);
f3875ab1
GC
2314
2315 if (!repo_config_get_string_tmp(&subrepo, "core.worktree", &cw)) {
2316 char *cfg_file, *abs_path;
2317 const char *rel_path;
2318 struct strbuf sb = STRBUF_INIT;
2319
2320 cfg_file = repo_git_path(&subrepo, "config");
2321
2322 abs_path = absolute_pathdup(path);
2323 rel_path = relative_path(abs_path, subrepo.gitdir, &sb);
2324
2325 git_config_set_in_file(cfg_file, "core.worktree", rel_path);
2326
2327 free(cfg_file);
2328 free(abs_path);
2329 strbuf_release(&sb);
2330 }
ac350155
ÆAB
2331
2332 return 0;
f3875ab1
GC
2333}
2334
8f12108c
ÆAB
2335static const char *submodule_update_type_to_label(enum submodule_update_type type)
2336{
2337 switch (type) {
2338 case SM_UPDATE_CHECKOUT:
2339 return "checkout";
2340 case SM_UPDATE_MERGE:
2341 return "merge";
2342 case SM_UPDATE_REBASE:
2343 return "rebase";
2344 case SM_UPDATE_UNSPECIFIED:
2345 case SM_UPDATE_NONE:
2346 case SM_UPDATE_COMMAND:
2347 break;
2348 }
2349 BUG("unreachable with type %d", type);
2350}
2351
a253be68
ÆAB
2352static void update_data_to_args(const struct update_data *update_data,
2353 struct strvec *args)
f3875ab1 2354{
b788fc67
GC
2355 enum submodule_update_type update_type = update_data->update_default;
2356
cb49e1e8 2357 if (update_data->displaypath) {
d7a714fd 2358 strvec_push(args, "--super-prefix");
cb49e1e8
GC
2359 strvec_pushf(args, "%s/", update_data->displaypath);
2360 }
d7a714fd
GC
2361 strvec_pushl(args, "submodule--helper", "update", "--recursive", NULL);
2362 strvec_pushf(args, "--jobs=%d", update_data->max_jobs);
f3875ab1
GC
2363 if (update_data->quiet)
2364 strvec_push(args, "--quiet");
2365 if (update_data->force)
2366 strvec_push(args, "--force");
2367 if (update_data->init)
2368 strvec_push(args, "--init");
2369 if (update_data->remote)
2370 strvec_push(args, "--remote");
2371 if (update_data->nofetch)
2372 strvec_push(args, "--no-fetch");
2373 if (update_data->dissociate)
2374 strvec_push(args, "--dissociate");
2375 if (update_data->progress)
2376 strvec_push(args, "--progress");
2377 if (update_data->require_init)
2378 strvec_push(args, "--require-init");
2379 if (update_data->depth)
2380 strvec_pushf(args, "--depth=%d", update_data->depth);
b788fc67
GC
2381 if (update_type != SM_UPDATE_UNSPECIFIED)
2382 strvec_pushf(args, "--%s",
2383 submodule_update_type_to_label(update_type));
2384
f3875ab1
GC
2385 if (update_data->references.nr) {
2386 struct string_list_item *item;
0b83b2b0 2387
f3875ab1
GC
2388 for_each_string_list_item(item, &update_data->references)
2389 strvec_pushl(args, "--reference", item->string, NULL);
2390 }
2391 if (update_data->filter_options && update_data->filter_options->choice)
2392 strvec_pushf(args, "--filter=%s",
2393 expand_list_objects_filter_spec(
2394 update_data->filter_options));
2395 if (update_data->recommend_shallow == 0)
2396 strvec_push(args, "--no-recommend-shallow");
2397 else if (update_data->recommend_shallow == 1)
2398 strvec_push(args, "--recommend-shallow");
2399 if (update_data->single_branch >= 0)
2400 strvec_push(args, update_data->single_branch ?
2401 "--single-branch" :
2402 "--no-single-branch");
2403}
2404
d905d443 2405static int update_submodule(struct update_data *update_data)
f3875ab1 2406{
484f9150
ÆAB
2407 int ret;
2408
ac350155
ÆAB
2409 ret = ensure_core_worktree(update_data->sm_path);
2410 if (ret)
2411 return ret;
f3875ab1 2412
5ad87271
GC
2413 update_data->displaypath = get_submodule_displaypath(
2414 update_data->sm_path, update_data->prefix);
f3875ab1 2415
484f9150
ÆAB
2416 ret = determine_submodule_update_strategy(the_repository,
2417 update_data->just_cloned,
2418 update_data->sm_path,
2419 update_data->update_default,
2420 &update_data->update_strategy);
d905d443 2421 if (ret)
484f9150 2422 return ret;
f3875ab1
GC
2423
2424 if (update_data->just_cloned)
2425 oidcpy(&update_data->suboid, null_oid());
2426 else if (resolve_gitlink_ref(update_data->sm_path, "HEAD", &update_data->suboid))
ac350155
ÆAB
2427 return die_message(_("Unable to find current revision in submodule path '%s'"),
2428 update_data->displaypath);
f3875ab1
GC
2429
2430 if (update_data->remote) {
f5373dea
ÆAB
2431 char *remote_name;
2432 const char *branch;
2433 char *remote_ref;
2434 int code;
2435
2436 code = get_default_remote_submodule(update_data->sm_path, &remote_name);
2437 if (code)
2438 return code;
2439 branch = remote_submodule_branch(update_data->sm_path);
2440 remote_ref = xstrfmt("refs/remotes/%s/%s", remote_name, branch);
f3875ab1
GC
2441
2442 if (!update_data->nofetch) {
2443 if (fetch_in_submodule(update_data->sm_path, update_data->depth,
2444 0, NULL))
ac350155
ÆAB
2445 return die_message(_("Unable to fetch in submodule path '%s'"),
2446 update_data->sm_path);
f3875ab1
GC
2447 }
2448
2449 if (resolve_gitlink_ref(update_data->sm_path, remote_ref, &update_data->oid))
ac350155
ÆAB
2450 return die_message(_("Unable to find %s revision in submodule path '%s'"),
2451 remote_ref, update_data->sm_path);
f3875ab1
GC
2452
2453 free(remote_ref);
2454 }
2455
2cb9294b 2456 if (!oideq(&update_data->oid, &update_data->suboid) || update_data->force) {
d905d443 2457 ret = run_update_procedure(update_data);
2cb9294b 2458 if (ret)
d905d443 2459 return ret;
2cb9294b 2460 }
f3875ab1
GC
2461
2462 if (update_data->recursive) {
2463 struct child_process cp = CHILD_PROCESS_INIT;
2464 struct update_data next = *update_data;
f3875ab1 2465
f3875ab1
GC
2466 next.prefix = NULL;
2467 oidcpy(&next.oid, null_oid());
2468 oidcpy(&next.suboid, null_oid());
2469
2470 cp.dir = update_data->sm_path;
2471 cp.git_cmd = 1;
29fda24d 2472 prepare_submodule_repo_env(&cp.env);
f3875ab1
GC
2473 update_data_to_args(&next, &cp.args);
2474
addda284 2475 ret = run_command(&cp);
d905d443
ÆAB
2476 if (ret)
2477 die_message(_("Failed to recurse into submodule path '%s'"),
2478 update_data->displaypath);
0b917a9f 2479 return ret;
f3875ab1
GC
2480 }
2481
2482 return 0;
2483}
2484
c9911c93 2485static int update_submodules(struct update_data *update_data)
90efe595 2486{
addda284 2487 int i, ret = 0;
c9911c93 2488 struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;
90efe595 2489
c9911c93
GC
2490 suc.update_data = update_data;
2491 run_processes_parallel_tr2(suc.update_data->max_jobs, update_clone_get_next_task,
ee4512ed 2492 update_clone_start_failure,
c9911c93 2493 update_clone_task_finished, &suc, "submodule",
ee4512ed 2494 "parallel/update");
90efe595
SB
2495
2496 /*
2497 * We saved the output and put it out all at once now.
2498 * That means:
2499 * - the listener does not have to interleave their (checkout)
2500 * work with our fetching. The writes involved in a
2501 * checkout involve more straightforward sequential I/O.
2502 * - the listener can avoid doing any work if fetching failed.
2503 */
b3c5f5cb 2504 if (suc.quickstop) {
addda284 2505 ret = 1;
b3c5f5cb
AR
2506 goto cleanup;
2507 }
90efe595 2508
b3c5f5cb
AR
2509 for (i = 0; i < suc.update_clone_nr; i++) {
2510 struct update_clone_data ucd = suc.update_clone[i];
2cb9294b 2511 int code;
90efe595 2512
b3c5f5cb
AR
2513 oidcpy(&update_data->oid, &ucd.oid);
2514 update_data->just_cloned = ucd.just_cloned;
2515 update_data->sm_path = ucd.sub->path;
2516
d905d443
ÆAB
2517 code = update_submodule(update_data);
2518 if (!code)
2519 continue;
2520 ret = code;
2521 if (ret == 128)
2cb9294b 2522 goto cleanup;
b3c5f5cb
AR
2523 }
2524
2525cleanup:
2526 string_list_clear(&update_data->references, 0);
addda284 2527 return ret;
90efe595
SB
2528}
2529
b3c5f5cb 2530static int module_update(int argc, const char **argv, const char *prefix)
48308681 2531{
48308681 2532 struct pathspec pathspec;
c9911c93 2533 struct update_data opt = UPDATE_DATA_INIT;
4b82d75b 2534 struct list_objects_filter_options filter_options = { 0 };
f05da2b4 2535 int ret;
b3c5f5cb
AR
2536 struct option module_update_options[] = {
2537 OPT__FORCE(&opt.force, N_("force checkout updates"), 0),
49fd5b99 2538 OPT_BOOL(0, "init", &opt.init,
29a5e9e1 2539 N_("initialize uninitialized submodules before update")),
b3c5f5cb
AR
2540 OPT_BOOL(0, "remote", &opt.remote,
2541 N_("use SHA-1 of submodule's remote tracking branch")),
2542 OPT_BOOL(0, "recursive", &opt.recursive,
2543 N_("traverse submodules recursively")),
2544 OPT_BOOL('N', "no-fetch", &opt.nofetch,
2545 N_("don't fetch new objects from the remote site")),
c9911c93 2546 OPT_STRING(0, "prefix", &opt.prefix,
48308681
SB
2547 N_("path"),
2548 N_("path into the working tree")),
b788fc67 2549 OPT_SET_INT(0, "checkout", &opt.update_default,
8f12108c
ÆAB
2550 N_("use the 'checkout' update strategy (default)"),
2551 SM_UPDATE_CHECKOUT),
b788fc67 2552 OPT_SET_INT('m', "merge", &opt.update_default,
8f12108c
ÆAB
2553 N_("use the 'merge' update strategy"),
2554 SM_UPDATE_MERGE),
b788fc67 2555 OPT_SET_INT('r', "rebase", &opt.update_default,
8f12108c
ÆAB
2556 N_("use the 'rebase' update strategy"),
2557 SM_UPDATE_REBASE),
49fd5b99 2558 OPT_STRING_LIST(0, "reference", &opt.references, N_("repo"),
48308681 2559 N_("reference repository")),
49fd5b99 2560 OPT_BOOL(0, "dissociate", &opt.dissociate,
a0ef2934 2561 N_("use --reference only while cloning")),
c9911c93 2562 OPT_INTEGER(0, "depth", &opt.depth,
e73fe3dd 2563 N_("create a shallow clone truncated to the "
48308681 2564 "specified number of revisions")),
49fd5b99 2565 OPT_INTEGER('j', "jobs", &opt.max_jobs,
2335b870 2566 N_("parallel jobs")),
49fd5b99 2567 OPT_BOOL(0, "recommend-shallow", &opt.recommend_shallow,
abed000a 2568 N_("whether the initial clone should follow the shallow recommendation")),
49fd5b99
ÆAB
2569 OPT__QUIET(&opt.quiet, N_("don't print cloning progress")),
2570 OPT_BOOL(0, "progress", &opt.progress,
72c5f883 2571 N_("force cloning progress")),
49fd5b99 2572 OPT_BOOL(0, "require-init", &opt.require_init,
d9c7f69a 2573 N_("disallow cloning into non-empty directory, implies --init")),
49fd5b99 2574 OPT_BOOL(0, "single-branch", &opt.single_branch,
132f600b 2575 N_("clone only one branch, HEAD or --branch")),
f05da2b4 2576 OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
48308681
SB
2577 OPT_END()
2578 };
48308681 2579 const char *const git_submodule_helper_usage[] = {
c9d25624
GC
2580 N_("git submodule [--quiet] update"
2581 " [--init [--filter=<filter-spec>]] [--remote]"
2582 " [-N|--no-fetch] [-f|--force]"
2583 " [--checkout|--merge|--rebase]"
2584 " [--[no-]recommend-shallow] [--reference <repository>]"
2585 " [--recursive] [--[no-]single-branch] [--] [<path>...]"),
48308681
SB
2586 NULL
2587 };
48308681 2588
49fd5b99
ÆAB
2589 update_clone_config_from_gitmodules(&opt.max_jobs);
2590 git_config(git_update_clone_config, &opt.max_jobs);
f20e7c1e 2591
b3c5f5cb 2592 argc = parse_options(argc, argv, prefix, module_update_options,
48308681 2593 git_submodule_helper_usage, 0);
c9d25624 2594
d9c7f69a
ÆAB
2595 if (opt.require_init)
2596 opt.init = 1;
2597
49fd5b99 2598 if (filter_options.choice && !opt.init) {
b3c5f5cb
AR
2599 usage_with_options(git_submodule_helper_usage,
2600 module_update_options);
c9d25624
GC
2601 }
2602
49fd5b99 2603 opt.filter_options = &filter_options;
48308681 2604
c9911c93 2605 if (opt.update_default)
b788fc67 2606 opt.update_strategy.type = opt.update_default;
48308681 2607
49fd5b99 2608 if (module_list_compute(argc, argv, prefix, &pathspec, &opt.list) < 0) {
f05da2b4 2609 list_objects_filter_release(&filter_options);
48308681 2610 return 1;
f05da2b4 2611 }
48308681
SB
2612
2613 if (pathspec.nr)
49fd5b99 2614 opt.warn_if_uninitialized = 1;
48308681 2615
49fd5b99 2616 if (opt.init) {
29a5e9e1
GC
2617 struct module_list list = MODULE_LIST_INIT;
2618 struct init_cb info = INIT_CB_INIT;
2619
49fd5b99 2620 if (module_list_compute(argc, argv, opt.prefix,
29a5e9e1
GC
2621 &pathspec, &list) < 0)
2622 return 1;
2623
2624 /*
2625 * If there are no path args and submodule.active is set then,
2626 * by default, only initialize 'active' modules.
2627 */
2628 if (!argc && git_config_get_value_multi("submodule.active"))
2629 module_list_active(&list);
2630
49fd5b99 2631 info.prefix = opt.prefix;
49fd5b99 2632 if (opt.quiet)
29a5e9e1
GC
2633 info.flags |= OPT_QUIET;
2634
2635 for_each_listed_submodule(&list, init_submodule_cb, &info);
2636 }
2637
49fd5b99 2638 ret = update_submodules(&opt);
f05da2b4
JS
2639 list_objects_filter_release(&filter_options);
2640 return ret;
48308681
SB
2641}
2642
93481a6b
BW
2643static int push_check(int argc, const char **argv, const char *prefix)
2644{
2645 struct remote *remote;
c7be7201
BW
2646 const char *superproject_head;
2647 char *head;
2648 int detached_head = 0;
2649 struct object_id head_oid;
93481a6b 2650
c7be7201
BW
2651 if (argc < 3)
2652 die("submodule--helper push-check requires at least 2 arguments");
2653
2654 /*
2655 * superproject's resolved head ref.
2656 * if HEAD then the superproject is in a detached head state, otherwise
2657 * it will be the resolved head ref.
2658 */
2659 superproject_head = argv[1];
2660 argv++;
2661 argc--;
2662 /* Get the submodule's head ref and determine if it is detached */
0f2dc722 2663 head = resolve_refdup("HEAD", 0, &head_oid, NULL);
c7be7201
BW
2664 if (!head)
2665 die(_("Failed to resolve HEAD as a valid ref."));
2666 if (!strcmp(head, "HEAD"))
2667 detached_head = 1;
93481a6b
BW
2668
2669 /*
2670 * The remote must be configured.
2671 * This is to avoid pushing to the exact same URL as the parent.
2672 */
2673 remote = pushremote_get(argv[1]);
2674 if (!remote || remote->origin == REMOTE_UNCONFIGURED)
2675 die("remote '%s' not configured", argv[1]);
2676
2677 /* Check the refspec */
2678 if (argc > 2) {
9c8361b2 2679 int i;
93481a6b 2680 struct ref *local_refs = get_local_heads();
9c8361b2 2681 struct refspec refspec = REFSPEC_INIT_PUSH;
93481a6b 2682
9c8361b2
BW
2683 refspec_appendn(&refspec, argv + 2, argc - 2);
2684
2685 for (i = 0; i < refspec.nr; i++) {
2686 const struct refspec_item *rs = &refspec.items[i];
93481a6b
BW
2687
2688 if (rs->pattern || rs->matching)
2689 continue;
2690
c7be7201
BW
2691 /* LHS must match a single ref */
2692 switch (count_refspec_match(rs->src, local_refs, NULL)) {
2693 case 1:
2694 break;
2695 case 0:
2696 /*
2697 * If LHS matches 'HEAD' then we need to ensure
2698 * that it matches the same named branch
2699 * checked out in the superproject.
2700 */
2701 if (!strcmp(rs->src, "HEAD")) {
2702 if (!detached_head &&
2703 !strcmp(head, superproject_head))
2704 break;
2705 die("HEAD does not match the named branch in the superproject");
2706 }
1cf01a34 2707 /* fallthrough */
c7be7201 2708 default:
93481a6b
BW
2709 die("src refspec '%s' must name a ref",
2710 rs->src);
c7be7201 2711 }
93481a6b 2712 }
9c8361b2 2713 refspec_clear(&refspec);
93481a6b 2714 }
c7be7201 2715 free(head);
93481a6b
BW
2716
2717 return 0;
2718}
2719
f6f85861
SB
2720static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
2721{
2722 int i;
2723 struct pathspec pathspec;
2724 struct module_list list = MODULE_LIST_INIT;
2725 unsigned flags = ABSORB_GITDIR_RECURSE_SUBMODULES;
f6f85861
SB
2726 struct option embed_gitdir_options[] = {
2727 OPT_STRING(0, "prefix", &prefix,
2728 N_("path"),
2729 N_("path into the working tree")),
2730 OPT_BIT(0, "--recursive", &flags, N_("recurse into submodules"),
2731 ABSORB_GITDIR_RECURSE_SUBMODULES),
2732 OPT_END()
2733 };
f6f85861 2734 const char *const git_submodule_helper_usage[] = {
36d45163 2735 N_("git submodule absorbgitdirs [<options>] [<path>...]"),
f6f85861
SB
2736 NULL
2737 };
2738
2739 argc = parse_options(argc, argv, prefix, embed_gitdir_options,
2740 git_submodule_helper_usage, 0);
2741
f6f85861
SB
2742 if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
2743 return 1;
2744
2745 for (i = 0; i < list.nr; i++)
cf7a901a 2746 absorb_git_dir_into_superproject(list.entries[i]->name, flags);
f6f85861
SB
2747
2748 return 0;
2749}
2750
2502ffc0
AO
2751static int module_config(int argc, const char **argv, const char *prefix)
2752{
b5c259f2 2753 enum {
c89c4942
DL
2754 CHECK_WRITEABLE = 1,
2755 DO_UNSET = 2
b5c259f2 2756 } command = 0;
b5c259f2
AO
2757 struct option module_config_options[] = {
2758 OPT_CMDMODE(0, "check-writeable", &command,
2759 N_("check if it is safe to write to the .gitmodules file"),
2760 CHECK_WRITEABLE),
c89c4942
DL
2761 OPT_CMDMODE(0, "unset", &command,
2762 N_("unset the config in the .gitmodules file"),
2763 DO_UNSET),
b5c259f2
AO
2764 OPT_END()
2765 };
2766 const char *const git_submodule_helper_usage[] = {
c89c4942
DL
2767 N_("git submodule--helper config <name> [<value>]"),
2768 N_("git submodule--helper config --unset <name>"),
959d670d 2769 "git submodule--helper config --check-writeable",
b5c259f2
AO
2770 NULL
2771 };
2772
2773 argc = parse_options(argc, argv, prefix, module_config_options,
2774 git_submodule_helper_usage, PARSE_OPT_KEEP_ARGV0);
2775
2776 if (argc == 1 && command == CHECK_WRITEABLE)
2777 return is_writing_gitmodules_ok() ? 0 : -1;
2778
2502ffc0 2779 /* Equivalent to ACTION_GET in builtin/config.c */
c89c4942 2780 if (argc == 2 && command != DO_UNSET)
2502ffc0
AO
2781 return print_config_from_gitmodules(the_repository, argv[1]);
2782
2783 /* Equivalent to ACTION_SET in builtin/config.c */
c89c4942
DL
2784 if (argc == 3 || (argc == 2 && command == DO_UNSET)) {
2785 const char *value = (argc == 3) ? argv[2] : NULL;
2786
76e9bdc4
AO
2787 if (!is_writing_gitmodules_ok())
2788 die(_("please make sure that the .gitmodules file is in the working tree"));
2789
c89c4942 2790 return config_set_in_gitmodules_file_gently(argv[1], value);
76e9bdc4 2791 }
2502ffc0 2792
b5c259f2 2793 usage_with_options(git_submodule_helper_usage, module_config_options);
2502ffc0
AO
2794}
2795
6417cf9c
SS
2796static int module_set_url(int argc, const char **argv, const char *prefix)
2797{
2798 int quiet = 0;
2799 const char *newurl;
2800 const char *path;
2801 char *config_name;
6417cf9c 2802 struct option options[] = {
e73fe3dd 2803 OPT__QUIET(&quiet, N_("suppress output for setting url of a submodule")),
6417cf9c
SS
2804 OPT_END()
2805 };
2806 const char *const usage[] = {
36d45163 2807 N_("git submodule set-url [--quiet] <path> <newurl>"),
6417cf9c
SS
2808 NULL
2809 };
2810
2811 argc = parse_options(argc, argv, prefix, options, usage, 0);
2812
2813 if (argc != 2 || !(path = argv[0]) || !(newurl = argv[1]))
2814 usage_with_options(usage, options);
2815
2816 config_name = xstrfmt("submodule.%s.url", path);
2817
2818 config_set_in_gitmodules_file_gently(config_name, newurl);
2819 sync_submodule(path, prefix, quiet ? OPT_QUIET : 0);
2820
2821 free(config_name);
2822
2823 return 0;
2824}
2825
2964d6e5
SS
2826static int module_set_branch(int argc, const char **argv, const char *prefix)
2827{
2828 int opt_default = 0, ret;
2829 const char *opt_branch = NULL;
2830 const char *path;
2831 char *config_name;
2964d6e5 2832 struct option options[] = {
e2d5c886
ÆAB
2833 /*
2834 * We accept the `quiet` option for uniformity across subcommands,
2835 * though there is nothing to make less verbose in this subcommand.
2836 */
2964d6e5 2837 OPT_NOOP_NOARG('q', "quiet"),
e2d5c886 2838
2964d6e5
SS
2839 OPT_BOOL('d', "default", &opt_default,
2840 N_("set the default tracking branch to master")),
2841 OPT_STRING('b', "branch", &opt_branch, N_("branch"),
2842 N_("set the default tracking branch")),
2843 OPT_END()
2844 };
2845 const char *const usage[] = {
36d45163
ÆAB
2846 N_("git submodule set-branch [-q|--quiet] (-d|--default) <path>"),
2847 N_("git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"),
2964d6e5
SS
2848 NULL
2849 };
2850
2851 argc = parse_options(argc, argv, prefix, options, usage, 0);
2852
2853 if (!opt_branch && !opt_default)
2854 die(_("--branch or --default required"));
2855
2856 if (opt_branch && opt_default)
43ea635c 2857 die(_("options '%s' and '%s' cannot be used together"), "--branch", "--default");
2964d6e5
SS
2858
2859 if (argc != 1 || !(path = argv[0]))
2860 usage_with_options(usage, options);
2861
2862 config_name = xstrfmt("submodule.%s.branch", path);
2863 ret = config_set_in_gitmodules_file_gently(config_name, opt_branch);
2864
2865 free(config_name);
2866 return !!ret;
2867}
2868
961b130d
GC
2869static int module_create_branch(int argc, const char **argv, const char *prefix)
2870{
2871 enum branch_track track;
2872 int quiet = 0, force = 0, reflog = 0, dry_run = 0;
961b130d
GC
2873 struct option options[] = {
2874 OPT__QUIET(&quiet, N_("print only error messages")),
2875 OPT__FORCE(&force, N_("force creation"), 0),
2876 OPT_BOOL(0, "create-reflog", &reflog,
2877 N_("create the branch's reflog")),
75388bf5
GC
2878 OPT_CALLBACK_F('t', "track", &track, "(direct|inherit)",
2879 N_("set branch tracking configuration"),
2880 PARSE_OPT_OPTARG,
2881 parse_opt_tracking_mode),
961b130d
GC
2882 OPT__DRY_RUN(&dry_run,
2883 N_("show whether the branch would be created")),
2884 OPT_END()
2885 };
2886 const char *const usage[] = {
af15f84d 2887 N_("git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--quiet] [-t|--track] [-n|--dry-run] <name> <start-oid> <start-name>"),
961b130d
GC
2888 NULL
2889 };
2890
2891 git_config(git_default_config, NULL);
2892 track = git_branch_track;
2893 argc = parse_options(argc, argv, prefix, options, usage, 0);
2894
2895 if (argc != 3)
2896 usage_with_options(usage, options);
2897
2898 if (!quiet && !dry_run)
2899 printf_ln(_("creating branch '%s'"), argv[0]);
2900
2901 create_branches_recursively(the_repository, argv[0], argv[1], argv[2],
2902 force, reflog, quiet, track, dry_run);
2903 return 0;
2904}
1a0b78c9 2905
8c8195e9
AR
2906struct add_data {
2907 const char *prefix;
2908 const char *branch;
2909 const char *reference_path;
a6226fd7 2910 char *sm_path;
8c8195e9
AR
2911 const char *sm_name;
2912 const char *repo;
2913 const char *realrepo;
2914 int depth;
2915 unsigned int force: 1;
2916 unsigned int quiet: 1;
2917 unsigned int progress: 1;
2918 unsigned int dissociate: 1;
2919};
2920#define ADD_DATA_INIT { .depth = -1 }
2921
6b615dbe 2922static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path)
8c8195e9
AR
2923{
2924 struct child_process cp_remote = CHILD_PROCESS_INIT;
2925 struct strbuf sb_remote_out = STRBUF_INIT;
2926
2927 cp_remote.git_cmd = 1;
29fda24d 2928 strvec_pushf(&cp_remote.env,
8c8195e9 2929 "GIT_DIR=%s", git_dir_path);
29fda24d 2930 strvec_push(&cp_remote.env, "GIT_WORK_TREE=.");
8c8195e9
AR
2931 strvec_pushl(&cp_remote.args, "remote", "-v", NULL);
2932 if (!capture_command(&cp_remote, &sb_remote_out, 0)) {
2933 char *next_line;
2934 char *line = sb_remote_out.buf;
0b83b2b0 2935
8c8195e9
AR
2936 while ((next_line = strchr(line, '\n')) != NULL) {
2937 size_t len = next_line - line;
0b83b2b0 2938
8c8195e9 2939 if (strip_suffix_mem(line, &len, " (fetch)"))
c21fb467 2940 strbuf_addf(msg, " %.*s\n", (int)len, line);
8c8195e9
AR
2941 line = next_line + 1;
2942 }
2943 }
2944
2945 strbuf_release(&sb_remote_out);
2946}
2947
2948static int add_submodule(const struct add_data *add_data)
2949{
2950 char *submod_gitdir_path;
2951 struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;
6fac5b2f 2952 struct string_list reference = STRING_LIST_INIT_NODUP;
8c8195e9
AR
2953
2954 /* perhaps the path already exists and is already a git repo, else clone it */
2955 if (is_directory(add_data->sm_path)) {
2956 struct strbuf sm_path = STRBUF_INIT;
2957 strbuf_addstr(&sm_path, add_data->sm_path);
2958 submod_gitdir_path = xstrfmt("%s/.git", add_data->sm_path);
2959 if (is_nonbare_repository_dir(&sm_path))
2960 printf(_("Adding existing repo at '%s' to the index\n"),
2961 add_data->sm_path);
2962 else
2963 die(_("'%s' already exists and is not a valid git repo"),
2964 add_data->sm_path);
2965 strbuf_release(&sm_path);
2966 free(submod_gitdir_path);
2967 } else {
2968 struct child_process cp = CHILD_PROCESS_INIT;
6fac5b2f 2969
8c8195e9
AR
2970 submod_gitdir_path = xstrfmt(".git/modules/%s", add_data->sm_name);
2971
2972 if (is_directory(submod_gitdir_path)) {
2973 if (!add_data->force) {
c21fb467
KS
2974 struct strbuf msg = STRBUF_INIT;
2975 char *die_msg;
2976
2977 strbuf_addf(&msg, _("A git directory for '%s' is found "
2978 "locally with remote(s):\n"),
2979 add_data->sm_name);
2980
6b615dbe 2981 append_fetch_remotes(&msg, submod_gitdir_path);
8c8195e9 2982 free(submod_gitdir_path);
c21fb467
KS
2983
2984 strbuf_addf(&msg, _("If you want to reuse this local git "
2985 "directory instead of cloning again from\n"
2986 " %s\n"
2987 "use the '--force' option. If the local git "
2988 "directory is not the correct repo\n"
2989 "or you are unsure what this means choose "
2990 "another name with the '--name' option."),
2991 add_data->realrepo);
2992
2993 die_msg = strbuf_detach(&msg, NULL);
2994 die("%s", die_msg);
8c8195e9
AR
2995 } else {
2996 printf(_("Reactivating local git directory for "
2997 "submodule '%s'\n"), add_data->sm_name);
2998 }
2999 }
3000 free(submod_gitdir_path);
3001
3002 clone_data.prefix = add_data->prefix;
3003 clone_data.path = add_data->sm_path;
3004 clone_data.name = add_data->sm_name;
3005 clone_data.url = add_data->realrepo;
3006 clone_data.quiet = add_data->quiet;
3007 clone_data.progress = add_data->progress;
3008 if (add_data->reference_path)
6fac5b2f 3009 string_list_append(&reference,
8c8195e9
AR
3010 xstrdup(add_data->reference_path));
3011 clone_data.dissociate = add_data->dissociate;
3012 if (add_data->depth >= 0)
3013 clone_data.depth = xstrfmt("%d", add_data->depth);
3014
6fac5b2f 3015 if (clone_submodule(&clone_data, &reference))
8c8195e9
AR
3016 return -1;
3017
29fda24d 3018 prepare_submodule_repo_env(&cp.env);
8c8195e9
AR
3019 cp.git_cmd = 1;
3020 cp.dir = add_data->sm_path;
94b7f156
EN
3021 /*
3022 * NOTE: we only get here if add_data->force is true, so
3023 * passing --force to checkout is reasonable.
3024 */
8c8195e9
AR
3025 strvec_pushl(&cp.args, "checkout", "-f", "-q", NULL);
3026
3027 if (add_data->branch) {
3028 strvec_pushl(&cp.args, "-B", add_data->branch, NULL);
3029 strvec_pushf(&cp.args, "origin/%s", add_data->branch);
3030 }
3031
3032 if (run_command(&cp))
3033 die(_("unable to checkout submodule '%s'"), add_data->sm_path);
3034 }
3035 return 0;
3036}
3037
a452128a
AR
3038static int config_submodule_in_gitmodules(const char *name, const char *var, const char *value)
3039{
3040 char *key;
3041 int ret;
3042
3043 if (!is_writing_gitmodules_ok())
3044 die(_("please make sure that the .gitmodules file is in the working tree"));
3045
3046 key = xstrfmt("submodule.%s.%s", name, var);
3047 ret = config_set_in_gitmodules_file_gently(key, value);
3048 free(key);
3049
3050 return ret;
3051}
3052
3053static void configure_added_submodule(struct add_data *add_data)
3054{
3055 char *key;
3056 char *val = NULL;
3057 struct child_process add_submod = CHILD_PROCESS_INIT;
3058 struct child_process add_gitmodules = CHILD_PROCESS_INIT;
3059
3060 key = xstrfmt("submodule.%s.url", add_data->sm_name);
3061 git_config_set_gently(key, add_data->realrepo);
3062 free(key);
3063
3064 add_submod.git_cmd = 1;
3065 strvec_pushl(&add_submod.args, "add",
3066 "--no-warn-embedded-repo", NULL);
3067 if (add_data->force)
3068 strvec_push(&add_submod.args, "--force");
3069 strvec_pushl(&add_submod.args, "--", add_data->sm_path, NULL);
3070
3071 if (run_command(&add_submod))
3072 die(_("Failed to add submodule '%s'"), add_data->sm_path);
3073
3074 if (config_submodule_in_gitmodules(add_data->sm_name, "path", add_data->sm_path) ||
3075 config_submodule_in_gitmodules(add_data->sm_name, "url", add_data->repo))
3076 die(_("Failed to register submodule '%s'"), add_data->sm_path);
3077
3078 if (add_data->branch) {
3079 if (config_submodule_in_gitmodules(add_data->sm_name,
3080 "branch", add_data->branch))
3081 die(_("Failed to register submodule '%s'"), add_data->sm_path);
3082 }
3083
3084 add_gitmodules.git_cmd = 1;
3085 strvec_pushl(&add_gitmodules.args,
3086 "add", "--force", "--", ".gitmodules", NULL);
3087
3088 if (run_command(&add_gitmodules))
3089 die(_("Failed to register submodule '%s'"), add_data->sm_path);
3090
3091 /*
3092 * NEEDSWORK: In a multi-working-tree world this needs to be
3093 * set in the per-worktree config.
3094 */
3095 /*
3096 * NEEDSWORK: In the longer run, we need to get rid of this
3097 * pattern of querying "submodule.active" before calling
3098 * is_submodule_active(), since that function needs to find
3099 * out the value of "submodule.active" again anyway.
3100 */
3101 if (!git_config_get_string("submodule.active", &val) && val) {
3102 /*
3103 * If the submodule being added isn't already covered by the
3104 * current configured pathspec, set the submodule's active flag
3105 */
3106 if (!is_submodule_active(the_repository, add_data->sm_path)) {
3107 key = xstrfmt("submodule.%s.active", add_data->sm_name);
3108 git_config_set_gently(key, "true");
3109 free(key);
3110 }
3111 } else {
3112 key = xstrfmt("submodule.%s.active", add_data->sm_name);
3113 git_config_set_gently(key, "true");
3114 free(key);
3115 }
3116}
3117
a6226fd7 3118static void die_on_index_match(const char *path, int force)
a452128a 3119{
a6226fd7
AR
3120 struct pathspec ps;
3121 const char *args[] = { path, NULL };
3122 parse_pathspec(&ps, 0, PATHSPEC_PREFER_CWD, NULL, args);
3123
3124 if (read_cache_preload(NULL) < 0)
3125 die(_("index file corrupt"));
3126
3127 if (ps.nr) {
3128 int i;
3129 char *ps_matched = xcalloc(ps.nr, 1);
3130
3131 /* TODO: audit for interaction with sparse-index. */
3132 ensure_full_index(&the_index);
3133
3134 /*
3135 * Since there is only one pathspec, we just need
3136 * need to check ps_matched[0] to know if a cache
3137 * entry matched.
3138 */
3139 for (i = 0; i < active_nr; i++) {
3140 ce_path_match(&the_index, active_cache[i], &ps,
3141 ps_matched);
3142
3143 if (ps_matched[0]) {
3144 if (!force)
3145 die(_("'%s' already exists in the index"),
3146 path);
3147 if (!S_ISGITLINK(active_cache[i]->ce_mode))
3148 die(_("'%s' already exists in the index "
3149 "and is not a submodule"), path);
3150 break;
3151 }
3152 }
3153 free(ps_matched);
3154 }
c270b055 3155 clear_pathspec(&ps);
a6226fd7
AR
3156}
3157
3158static void die_on_repo_without_commits(const char *path)
3159{
3160 struct strbuf sb = STRBUF_INIT;
3161 strbuf_addstr(&sb, path);
3162 if (is_nonbare_repository_dir(&sb)) {
3163 struct object_id oid;
3164 if (resolve_gitlink_ref(path, "HEAD", &oid) < 0)
3165 die(_("'%s' does not have a commit checked out"), path);
3166 }
c270b055 3167 strbuf_release(&sb);
a6226fd7
AR
3168}
3169
3170static int module_add(int argc, const char **argv, const char *prefix)
3171{
3172 int force = 0, quiet = 0, progress = 0, dissociate = 0;
a452128a 3173 struct add_data add_data = ADD_DATA_INIT;
8f790151 3174 char *to_free = NULL;
a452128a 3175 struct option options[] = {
a6226fd7
AR
3176 OPT_STRING('b', "branch", &add_data.branch, N_("branch"),
3177 N_("branch of repository to add as submodule")),
a452128a
AR
3178 OPT__FORCE(&force, N_("allow adding an otherwise ignored submodule path"),
3179 PARSE_OPT_NOCOMPLETE),
a6226fd7
AR
3180 OPT__QUIET(&quiet, N_("print only error messages")),
3181 OPT_BOOL(0, "progress", &progress, N_("force cloning progress")),
3182 OPT_STRING(0, "reference", &add_data.reference_path, N_("repository"),
3183 N_("reference repository")),
3184 OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")),
3185 OPT_STRING(0, "name", &add_data.sm_name, N_("name"),
6dd9a91c 3186 N_("sets the submodule's name to the given string "
a6226fd7
AR
3187 "instead of defaulting to its path")),
3188 OPT_INTEGER(0, "depth", &add_data.depth, N_("depth for shallow clones")),
a452128a
AR
3189 OPT_END()
3190 };
a452128a 3191 const char *const usage[] = {
36d45163 3192 N_("git submodule add [<options>] [--] <repository> [<path>]"),
a452128a
AR
3193 NULL
3194 };
3195
3196 argc = parse_options(argc, argv, prefix, options, usage, 0);
3197
a6226fd7
AR
3198 if (!is_writing_gitmodules_ok())
3199 die(_("please make sure that the .gitmodules file is in the working tree"));
3200
3201 if (prefix && *prefix &&
3202 add_data.reference_path && !is_absolute_path(add_data.reference_path))
3203 add_data.reference_path = xstrfmt("%s%s", prefix, add_data.reference_path);
3204
3205 if (argc == 0 || argc > 2)
a452128a
AR
3206 usage_with_options(usage, options);
3207
a6226fd7
AR
3208 add_data.repo = argv[0];
3209 if (argc == 1)
3210 add_data.sm_path = git_url_basename(add_data.repo, 0, 0);
3211 else
3212 add_data.sm_path = xstrdup(argv[1]);
3213
3214 if (prefix && *prefix && !is_absolute_path(add_data.sm_path))
3215 add_data.sm_path = xstrfmt("%s%s", prefix, add_data.sm_path);
3216
3217 if (starts_with_dot_dot_slash(add_data.repo) ||
3218 starts_with_dot_slash(add_data.repo)) {
3219 if (prefix)
3220 die(_("Relative path can only be used from the toplevel "
3221 "of the working tree"));
3222
3223 /* dereference source url relative to parent's url */
8f790151
ÆAB
3224 to_free = resolve_relative_url(add_data.repo, NULL, 1);
3225 add_data.realrepo = to_free;
a6226fd7
AR
3226 } else if (is_dir_sep(add_data.repo[0]) || strchr(add_data.repo, ':')) {
3227 add_data.realrepo = add_data.repo;
3228 } else {
3229 die(_("repo URL: '%s' must be absolute or begin with ./|../"),
3230 add_data.repo);
3231 }
3232
3233 /*
3234 * normalize path:
3235 * multiple //; leading ./; /./; /../;
3236 */
3237 normalize_path_copy(add_data.sm_path, add_data.sm_path);
3238 strip_dir_trailing_slashes(add_data.sm_path);
3239
3240 die_on_index_match(add_data.sm_path, force);
3241 die_on_repo_without_commits(add_data.sm_path);
3242
3243 if (!force) {
3244 int exit_code = -1;
3245 struct strbuf sb = STRBUF_INIT;
3246 struct child_process cp = CHILD_PROCESS_INIT;
0b83b2b0 3247
a6226fd7
AR
3248 cp.git_cmd = 1;
3249 cp.no_stdout = 1;
3250 strvec_pushl(&cp.args, "add", "--dry-run", "--ignore-missing",
3251 "--no-warn-embedded-repo", add_data.sm_path, NULL);
3252 if ((exit_code = pipe_command(&cp, NULL, 0, NULL, 0, &sb, 0))) {
3253 strbuf_complete_line(&sb);
3254 fputs(sb.buf, stderr);
3255 free(add_data.sm_path);
3256 return exit_code;
3257 }
3258 strbuf_release(&sb);
3259 }
3260
3261 if(!add_data.sm_name)
3262 add_data.sm_name = add_data.sm_path;
3263
3264 if (check_submodule_name(add_data.sm_name))
3265 die(_("'%s' is not a valid submodule name"), add_data.sm_name);
3266
3267 add_data.prefix = prefix;
a452128a 3268 add_data.force = !!force;
a6226fd7
AR
3269 add_data.quiet = !!quiet;
3270 add_data.progress = !!progress;
3271 add_data.dissociate = !!dissociate;
3272
3273 if (add_submodule(&add_data)) {
3274 free(add_data.sm_path);
3275 return 1;
3276 }
a452128a 3277 configure_added_submodule(&add_data);
a6226fd7 3278 free(add_data.sm_path);
8f790151 3279 free(to_free);
a452128a
AR
3280
3281 return 0;
3282}
3283
89c86265
SB
3284#define SUPPORT_SUPER_PREFIX (1<<0)
3285
74703a1e
SB
3286struct cmd_struct {
3287 const char *cmd;
3288 int (*fn)(int, const char **, const char *);
89c86265 3289 unsigned option;
74703a1e
SB
3290};
3291
3292static struct cmd_struct commands[] = {
d7a714fd 3293 {"clone", module_clone, SUPPORT_SUPER_PREFIX},
b0f8b213 3294 {"add", module_add, 0},
d7a714fd 3295 {"update", module_update, SUPPORT_SUPER_PREFIX},
fc1b9243 3296 {"foreach", module_foreach, SUPPORT_SUPER_PREFIX},
b0f8b213 3297 {"init", module_init, 0},
a9f8a375 3298 {"status", module_status, SUPPORT_SUPER_PREFIX},
13424764 3299 {"sync", module_sync, SUPPORT_SUPER_PREFIX},
2e612731 3300 {"deinit", module_deinit, 0},
b0f8b213 3301 {"summary", module_summary, 0},
93481a6b 3302 {"push-check", push_check, 0},
6e556c41 3303 {"absorbgitdirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
2502ffc0 3304 {"config", module_config, 0},
6417cf9c 3305 {"set-url", module_set_url, 0},
2964d6e5 3306 {"set-branch", module_set_branch, 0},
961b130d 3307 {"create-branch", module_create_branch, 0},
74703a1e
SB
3308};
3309
3310int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
3311{
3312 int i;
f0994fa8
JK
3313 if (argc < 2 || !strcmp(argv[1], "-h"))
3314 usage("git submodule--helper <command>");
74703a1e 3315
89c86265
SB
3316 for (i = 0; i < ARRAY_SIZE(commands); i++) {
3317 if (!strcmp(argv[1], commands[i].cmd)) {
3318 if (get_super_prefix() &&
3319 !(commands[i].option & SUPPORT_SUPER_PREFIX))
3320 die(_("%s doesn't support --super-prefix"),
3321 commands[i].cmd);
74703a1e 3322 return commands[i].fn(argc - 1, argv + 1, prefix);
89c86265
SB
3323 }
3324 }
74703a1e 3325
cdc04b65 3326 die(_("'%s' is not a valid submodule--helper "
74703a1e
SB
3327 "subcommand"), argv[1]);
3328}