280
281
static int prepare_submodule_summary(struct rev_info *rev, const char *path,
282
struct commit *left, struct commit *right,
283
- int *fast_forward, int *fast_backward)
283
+ struct commit_list *merge_bases)
284
{
285
- struct commit_list *merge_bases, *list;
285
+ struct commit_list *list;
286
287
init_revisions(rev, NULL);
288
setup_revisions(0, NULL, rev, NULL);
291
left->object.flags |= SYMMETRIC_LEFT;
292
add_pending_object(rev, &left->object, path);
293
add_pending_object(rev, &right->object, path);
294
- merge_bases = get_merge_bases(left, right);
295
- if (merge_bases) {
296
- if (merge_bases->item == left)
297
- *fast_forward = 1;
298
- else if (merge_bases->item == right)
299
- *fast_backward = 1;
300
- }
294
for (list = merge_bases; list; list = list->next) {
295
list->item->object.flags |= UNINTERESTING;
296
add_pending_object(rev, &list->item->object,
328
strbuf_release(&sb);
329
}
330
338
-void show_submodule_summary(FILE *f, const char *path,
331
+/* Helper function to display the submodule header line prior to the full
332
+ * summary output. If it can locate the submodule objects directory it will
333
+ * attempt to lookup both the left and right commits and put them into the
334
+ * left and right pointers.
335
+ */
336
+static void show_submodule_header(FILE *f, const char *path,
337
const char *line_prefix,
338
struct object_id *one, struct object_id *two,
339
unsigned dirty_submodule, const char *meta,
342
- const char *del, const char *add, const char *reset)
340
+ const char *reset,
341
+ struct commit **left, struct commit **right,
342
+ struct commit_list **merge_bases)
343
{
344
- struct rev_info rev;
345
- struct commit *left = NULL, *right = NULL;
344
const char *message = NULL;
345
struct strbuf sb = STRBUF_INIT;
346
int fast_forward = 0, fast_backward = 0;
347
350
- if (is_null_oid(two))
351
- message = "(submodule deleted)";
352
- else if (add_submodule_odb(path))
353
- message = "(not initialized)";
354
- else if (is_null_oid(one))
355
- message = "(new submodule)";
356
- else if (!(left = lookup_commit_reference(one->hash)) ||
357
- !(right = lookup_commit_reference(two->hash)))
358
- message = "(commits not present)";
359
- else if (prepare_submodule_summary(&rev, path, left, right,
360
- &fast_forward, &fast_backward))
361
- message = "(revision walker failed)";
362
-
348
if (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)
349
fprintf(f, "%sSubmodule %s contains untracked content\n",
350
line_prefix, path);
352
fprintf(f, "%sSubmodule %s contains modified content\n",
353
line_prefix, path);
354
355
+ if (is_null_oid(one))
356
+ message = "(new submodule)";
357
+ else if (is_null_oid(two))
358
+ message = "(submodule deleted)";
359
+
360
+ if (add_submodule_odb(path)) {
361
+ if (!message)
362
+ message = "(not initialized)";
363
+ goto output_header;
364
+ }
365
+
366
+ /*
367
+ * Attempt to lookup the commit references, and determine if this is
368
+ * a fast forward or fast backwards update.
369
+ */
370
+ *left = lookup_commit_reference(one->hash);
371
+ *right = lookup_commit_reference(two->hash);
372
+
373
+ /*
374
+ * Warn about missing commits in the submodule project, but only if
375
+ * they aren't null.
376
+ */
377
+ if ((!is_null_oid(one) && !*left) ||
378
+ (!is_null_oid(two) && !*right))
379
+ message = "(commits not present)";
380
+
381
+ *merge_bases = get_merge_bases(*left, *right);
382
+ if (*merge_bases) {
383
+ if ((*merge_bases)->item == *left)
384
+ fast_forward = 1;
385
+ else if ((*merge_bases)->item == *right)
386
+ fast_backward = 1;
387
+ }
388
+
389
if (!oidcmp(one, two)) {
390
strbuf_release(&sb);
391
return;
392
}
393
394
+output_header:
395
strbuf_addf(&sb, "%s%sSubmodule %s %s..", line_prefix, meta, path,
396
find_unique_abbrev(one->hash, DEFAULT_ABBREV));
397
if (!fast_backward && !fast_forward)
403
strbuf_addf(&sb, "%s:%s\n", fast_backward ? " (rewind)" : "", reset);
404
fwrite(sb.buf, sb.len, 1, f);
405
386
- if (!message) /* only NULL if we succeeded in setting up the walk */
387
- print_submodule_summary(&rev, f, line_prefix, del, add, reset);
388
- if (left)
389
- clear_commit_marks(left, ~0);
390
- if (right)
391
- clear_commit_marks(right, ~0);
392
-
406
strbuf_release(&sb);
407
}
408
409
+void show_submodule_summary(FILE *f, const char *path,
410
+ const char *line_prefix,
411
+ struct object_id *one, struct object_id *two,
412
+ unsigned dirty_submodule, const char *meta,
413
+ const char *del, const char *add, const char *reset)
414
+{
415
+ struct rev_info rev;
416
+ struct commit *left = NULL, *right = NULL;
417
+ struct commit_list *merge_bases = NULL;
418
+
419
+ show_submodule_header(f, path, line_prefix, one, two, dirty_submodule,
420
+ meta, reset, &left, &right, &merge_bases);
421
+
422
+ /*
423
+ * If we don't have both a left and a right pointer, there is no
424
+ * reason to try and display a summary. The header line should contain
425
+ * all the information the user needs.
426
+ */
427
+ if (!left || !right)
428
+ goto out;
429
+
430
+ /* Treat revision walker failure the same as missing commits */
431
+ if (prepare_submodule_summary(&rev, path, left, right, merge_bases)) {
432
+ fprintf(f, "%s(revision walker failed)\n", line_prefix);
433
+ goto out;
434
+ }
435
+
436
+ print_submodule_summary(&rev, f, line_prefix, del, add, reset);
437
+
438
+out:
439
+ if (merge_bases)
440
+ free_commit_list(merge_bases);
441
+ clear_commit_marks(left, ~0);
442
+ clear_commit_marks(right, ~0);
443
+}
444
+
445
void set_config_fetch_recurse_submodules(int value)
446
{
447
config_fetch_recurse_submodules = value;