12
struct string_list config_name_for_path;
13
struct string_list config_fetch_recurse_submodules_for_name;
14
struct string_list config_ignore_for_name;
15
-static int config_fetch_recurse_submodules;
15
+static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND;
16
+struct string_list changed_submodule_paths;
17
18
static int add_submodule_odb(const char *path)
19
{
153
die("bad --ignore-submodules argument: %s", arg);
154
}
155
156
+int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg)
157
+{
158
+ switch (git_config_maybe_bool(opt, arg)) {
159
+ case 1:
160
+ return RECURSE_SUBMODULES_ON;
161
+ case 0:
162
+ return RECURSE_SUBMODULES_OFF;
163
+ default:
164
+ if (!strcmp(arg, "on-demand"))
165
+ return RECURSE_SUBMODULES_ON_DEMAND;
166
+ die("bad %s argument: %s", opt, arg);
167
+ }
168
+}
169
+
170
void show_submodule_summary(FILE *f, const char *path,
171
unsigned char one[20], unsigned char two[20],
172
unsigned dirty_submodule,
263
config_fetch_recurse_submodules = value;
264
}
265
266
+static void submodule_collect_changed_cb(struct diff_queue_struct *q,
267
+ struct diff_options *options,
268
+ void *data)
269
+{
270
+ int i;
271
+ for (i = 0; i < q->nr; i++) {
272
+ struct diff_filepair *p = q->queue[i];
273
+ if (!S_ISGITLINK(p->two->mode))
274
+ continue;
275
+
276
+ if (S_ISGITLINK(p->one->mode)) {
277
+ /* NEEDSWORK: We should honor the name configured in
278
+ * the .gitmodules file of the commit we are examining
279
+ * here to be able to correctly follow submodules
280
+ * being moved around. */
281
+ struct string_list_item *path;
282
+ path = unsorted_string_list_lookup(&changed_submodule_paths, p->two->path);
283
+ if (!path)
284
+ string_list_append(&changed_submodule_paths, xstrdup(p->two->path));
285
+ } else {
286
+ /* Submodule is new or was moved here */
287
+ /* NEEDSWORK: When the .git directories of submodules
288
+ * live inside the superprojects .git directory some
289
+ * day we should fetch new submodules directly into
290
+ * that location too when config or options request
291
+ * that so they can be checked out from there. */
292
+ continue;
293
+ }
294
+ }
295
+}
296
+
297
+void check_for_new_submodule_commits(unsigned char new_sha1[20])
298
+{
299
+ struct rev_info rev;
300
+ struct commit *commit;
301
+ const char *argv[] = {NULL, NULL, "--not", "--all", NULL};
302
+ int argc = ARRAY_SIZE(argv) - 1;
303
+
304
+ init_revisions(&rev, NULL);
305
+ argv[1] = xstrdup(sha1_to_hex(new_sha1));
306
+ setup_revisions(argc, argv, &rev, NULL);
307
+ if (prepare_revision_walk(&rev))
308
+ die("revision walk setup failed");
309
+
310
+ /*
311
+ * Collect all submodules (whether checked out or not) for which new
312
+ * commits have been recorded upstream in "changed_submodule_paths".
313
+ */
314
+ while ((commit = get_revision(&rev))) {
315
+ struct commit_list *parent = commit->parents;
316
+ while (parent) {
317
+ struct diff_options diff_opts;
318
+ diff_setup(&diff_opts);
319
+ diff_opts.output_format |= DIFF_FORMAT_CALLBACK;
320
+ diff_opts.format_callback = submodule_collect_changed_cb;
321
+ if (diff_setup_done(&diff_opts) < 0)
322
+ die("diff_setup_done failed");
323
+ diff_tree_sha1(parent->item->object.sha1, commit->object.sha1, "", &diff_opts);
324
+ diffcore_std(&diff_opts);
325
+ diff_flush(&diff_opts);
326
+ parent = parent->next;
327
+ }
328
+ }
329
+ free((char *)argv[1]);
330
+}
331
+
332
int fetch_populated_submodules(int num_options, const char **options,
333
const char *prefix, int ignore_config,
334
int quiet)
335
{
255
- int i, result = 0, argc = 0;
336
+ int i, result = 0, argc = 0, default_argc;
337
struct child_process cp;
338
const char **argv;
339
struct string_list_item *name_for_path;
340
const char *work_tree = get_git_work_tree();
341
if (!work_tree)
261
- return 0;
342
+ goto out;
343
344
if (!the_index.initialized)
345
if (read_cache() < 0)
346
die("index file corrupt");
347
267
- /* 4: "fetch" (options) "--submodule-prefix" prefix NULL */
268
- argv = xcalloc(num_options + 4, sizeof(const char *));
348
+ /* 6: "fetch" (options) --recurse-submodules-default default "--submodule-prefix" prefix NULL */
349
+ argv = xcalloc(num_options + 6, sizeof(const char *));
350
argv[argc++] = "fetch";
351
for (i = 0; i < num_options; i++)
352
argv[argc++] = options[i];
353
+ argv[argc++] = "--recurse-submodules-default";
354
+ default_argc = argc++;
355
argv[argc++] = "--submodule-prefix";
356
357
memset(&cp, 0, sizeof(cp));
365
struct strbuf submodule_git_dir = STRBUF_INIT;
366
struct strbuf submodule_prefix = STRBUF_INIT;
367
struct cache_entry *ce = active_cache[i];
285
- const char *git_dir, *name;
368
+ const char *git_dir, *name, *default_argv;
369
370
if (!S_ISGITLINK(ce->ce_mode))
371
continue;
375
if (name_for_path)
376
name = name_for_path->util;
377
378
+ default_argv = "yes";
379
if (!ignore_config) {
380
struct string_list_item *fetch_recurse_submodules_option;
381
fetch_recurse_submodules_option = unsorted_string_list_lookup(&config_fetch_recurse_submodules_for_name, name);
383
if (!fetch_recurse_submodules_option->util)
384
continue;
385
} else {
302
- if (!config_fetch_recurse_submodules)
386
+ if (config_fetch_recurse_submodules == RECURSE_SUBMODULES_OFF)
387
continue;
388
+ if (config_fetch_recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) {
389
+ if (!unsorted_string_list_lookup(&changed_submodule_paths, ce->name))
390
+ continue;
391
+ default_argv = "on-demand";
392
+ }
393
}
394
}
395
403
if (!quiet)
404
printf("Fetching submodule %s%s\n", prefix, ce->name);
405
cp.dir = submodule_path.buf;
406
+ argv[default_argc] = default_argv;
407
argv[argc] = submodule_prefix.buf;
408
if (run_command(&cp))
409
result = 1;
413
strbuf_release(&submodule_prefix);
414
}
415
free(argv);
416
+out:
417
+ string_list_clear(&changed_submodule_paths, 1);
418
return result;
419
}
420