submodule: use submodule repos for object lookup

This converts the 'show_submodule_header' function to use the repository API properly, such that the submodule objects are not added to the main object store. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stefan Beller committed Dec 14, 2018 at 16:09 UTC 605f0ec1350477e53fd1a7774bad977257bf10d5
1 file changed +60 -15
submodule.c
+60 -15
@@ -443,7 +443,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
443 return prepare_revision_walk(rev);
444 }
445
446 -static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)
446 +static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)
447 {
448 static const char format[] = " %m %s";
449 struct strbuf sb = STRBUF_INIT;
@@ -454,7 +454,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o
454 ctx.date_mode = rev->date_mode;
455 ctx.output_encoding = get_log_output_encoding();
456 strbuf_setlen(&sb, 0);
457 - format_commit_message(commit, format, &sb, &ctx);
457 + repo_format_commit_message(r, commit, format, &sb,
458 + &ctx);
459 strbuf_addch(&sb, '\n');
460 if (commit->object.flags & SYMMETRIC_LEFT)
461 diff_emit_submodule_del(o, sb.buf);
@@ -481,14 +482,46 @@ void prepare_submodule_repo_env(struct argv_array *out)
482 DEFAULT_GIT_DIR_ENVIRONMENT);
483 }
484
484 -/* Helper function to display the submodule header line prior to the full
485 - * summary output. If it can locate the submodule objects directory it will
486 - * attempt to lookup both the left and right commits and put them into the
487 - * left and right pointers.
485 +/*
486 + * Initialize a repository struct for a submodule based on the provided 'path'.
487 + *
488 + * Unlike repo_submodule_init, this tolerates submodules not present
489 + * in .gitmodules. This function exists only to preserve historical behavior,
490 + *
491 + * Returns the repository struct on success,
492 + * NULL when the submodule is not present.
493 */
489 -static void show_submodule_header(struct diff_options *o, const char *path,
494 +static struct repository *open_submodule(const char *path)
495 +{
496 + struct strbuf sb = STRBUF_INIT;
497 + struct repository *out = xmalloc(sizeof(*out));
498 +
499 + if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
500 + strbuf_release(&sb);
501 + free(out);
502 + return NULL;
503 + }
504 +
505 + /* Mark it as a submodule */
506 + out->submodule_prefix = xstrdup(path);
507 +
508 + strbuf_release(&sb);
509 + return out;
510 +}
511 +
512 +/*
513 + * Helper function to display the submodule header line prior to the full
514 + * summary output.
515 + *
516 + * If it can locate the submodule git directory it will create a repository
517 + * handle for the submodule and lookup both the left and right commits and
518 + * put them into the left and right pointers.
519 + */
520 +static void show_submodule_header(struct diff_options *o,
521 + const char *path,
522 struct object_id *one, struct object_id *two,
523 unsigned dirty_submodule,
524 + struct repository *sub,
525 struct commit **left, struct commit **right,
526 struct commit_list **merge_bases)
527 {
@@ -507,7 +540,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
540 else if (is_null_oid(two))
541 message = "(submodule deleted)";
542
510 - if (add_submodule_odb(path)) {
543 + if (!sub) {
544 if (!message)
545 message = "(commits not present)";
546 goto output_header;
@@ -517,8 +550,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,
550 * Attempt to lookup the commit references, and determine if this is
551 * a fast forward or fast backwards update.
552 */
520 - *left = lookup_commit_reference(the_repository, one);
521 - *right = lookup_commit_reference(the_repository, two);
553 + *left = lookup_commit_reference(sub, one);
554 + *right = lookup_commit_reference(sub, two);
555
556 /*
557 * Warn about missing commits in the submodule project, but only if
@@ -528,7 +561,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
561 (!is_null_oid(two) && !*right))
562 message = "(commits not present)";
563
531 - *merge_bases = get_merge_bases(*left, *right);
564 + *merge_bases = repo_get_merge_bases(sub, *left, *right);
565 if (*merge_bases) {
566 if ((*merge_bases)->item == *left)
567 fast_forward = 1;
@@ -562,16 +595,18 @@ void show_submodule_summary(struct diff_options *o, const char *path,
595 struct rev_info rev;
596 struct commit *left = NULL, *right = NULL;
597 struct commit_list *merge_bases = NULL;
598 + struct repository *sub;
599
600 + sub = open_submodule(path);
601 show_submodule_header(o, path, one, two, dirty_submodule,
567 - &left, &right, &merge_bases);
602 + sub, &left, &right, &merge_bases);
603
604 /*
605 * If we don't have both a left and a right pointer, there is no
606 * reason to try and display a summary. The header line should contain
607 * all the information the user needs.
608 */
574 - if (!left || !right)
609 + if (!left || !right || !sub)
610 goto out;
611
612 /* Treat revision walker failure the same as missing commits */
@@ -580,13 +615,17 @@ void show_submodule_summary(struct diff_options *o, const char *path,
615 goto out;
616 }
617
583 - print_submodule_summary(&rev, o);
618 + print_submodule_summary(sub, &rev, o);
619
620 out:
621 if (merge_bases)
622 free_commit_list(merge_bases);
623 clear_commit_marks(left, ~0);
624 clear_commit_marks(right, ~0);
625 + if (sub) {
626 + repo_clear(sub);
627 + free(sub);
628 + }
629 }
630
631 void show_submodule_inline_diff(struct diff_options *o, const char *path,
@@ -598,9 +637,11 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
637 struct commit_list *merge_bases = NULL;
638 struct child_process cp = CHILD_PROCESS_INIT;
639 struct strbuf sb = STRBUF_INIT;
640 + struct repository *sub;
641
642 + sub = open_submodule(path);
643 show_submodule_header(o, path, one, two, dirty_submodule,
603 - &left, &right, &merge_bases);
644 + sub, &left, &right, &merge_bases);
645
646 /* We need a valid left and right commit to display a difference */
647 if (!(left || is_null_oid(one)) ||
@@ -661,6 +702,10 @@ done:
702 clear_commit_marks(left, ~0);
703 if (right)
704 clear_commit_marks(right, ~0);
705 + if (sub) {
706 + repo_clear(sub);
707 + free(sub);
708 + }
709 }
710
711 int should_update_submodules(void)