git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 18/23] submodule: use submodule repos for object lookup

From
Stefan Beller <sbeller@google.com>
Date
Dec 15, 2018, 00:09 UTC
Message-ID
<20181215000942.46033-19-sbeller@google.com>
In-Reply-To
<20181215000942.46033-1-sbeller@google.com>

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>
---
 submodule.c | 75 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 60 insertions(+), 15 deletions(-)
diff --git a/submodule.c b/submodule.c
index d9d3046689..4486ff664b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -443,7 +443,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
 	return prepare_revision_walk(rev);
 }
 
-static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)
+static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)
 {
 	static const char format[] = "  %m %s";
 	struct strbuf sb = STRBUF_INIT;
@@ -454,7 +454,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o
 		ctx.date_mode = rev->date_mode;
 		ctx.output_encoding = get_log_output_encoding();
 		strbuf_setlen(&sb, 0);
-		format_commit_message(commit, format, &sb, &ctx);
+		repo_format_commit_message(r, commit, format, &sb,
+				      &ctx);
 		strbuf_addch(&sb, '\n');
 		if (commit->object.flags & SYMMETRIC_LEFT)
 			diff_emit_submodule_del(o, sb.buf);
@@ -481,14 +482,46 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_GIT_DIR_ENVIRONMENT);
 }
 
-/* Helper function to display the submodule header line prior to the full
- * summary output. If it can locate the submodule objects directory it will
- * attempt to lookup both the left and right commits and put them into the
- * left and right pointers.
+/*
+ * Initialize a repository struct for a submodule based on the provided 'path'.
+ *
+ * Unlike repo_submodule_init, this tolerates submodules not present
+ * in .gitmodules. This function exists only to preserve historical behavior,
+ *
+ * Returns the repository struct on success,
+ * NULL when the submodule is not present.
  */
-static void show_submodule_header(struct diff_options *o, const char *path,
+static struct repository *open_submodule(const char *path)
+{
+	struct strbuf sb = STRBUF_INIT;
+	struct repository *out = xmalloc(sizeof(*out));
+
+	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
+		strbuf_release(&sb);
+		free(out);
+		return NULL;
+	}
+
+	/* Mark it as a submodule */
+	out->submodule_prefix = xstrdup(path);
+
+	strbuf_release(&sb);
+	return out;
+}
+
+/*
+ * Helper function to display the submodule header line prior to the full
+ * summary output.
+ *
+ * If it can locate the submodule git directory it will create a repository
+ * handle for the submodule and lookup both the left and right commits and
+ * put them into the left and right pointers.
+ */
+static void show_submodule_header(struct diff_options *o,
+		const char *path,
 		struct object_id *one, struct object_id *two,
 		unsigned dirty_submodule,
+		struct repository *sub,
 		struct commit **left, struct commit **right,
 		struct commit_list **merge_bases)
 {
@@ -507,7 +540,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	else if (is_null_oid(two))
 		message = "(submodule deleted)";
 
-	if (add_submodule_odb(path)) {
+	if (!sub) {
 		if (!message)
 			message = "(commits not present)";
 		goto output_header;
@@ -517,8 +550,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	 * Attempt to lookup the commit references, and determine if this is
 	 * a fast forward or fast backwards update.
 	 */
-	*left = lookup_commit_reference(the_repository, one);
-	*right = lookup_commit_reference(the_repository, two);
+	*left = lookup_commit_reference(sub, one);
+	*right = lookup_commit_reference(sub, two);
 
 	/*
 	 * 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,
 	     (!is_null_oid(two) && !*right))
 		message = "(commits not present)";
 
-	*merge_bases = get_merge_bases(*left, *right);
+	*merge_bases = repo_get_merge_bases(sub, *left, *right);
 	if (*merge_bases) {
 		if ((*merge_bases)->item == *left)
 			fast_forward = 1;
@@ -562,16 +595,18 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 	struct rev_info rev;
 	struct commit *left = NULL, *right = NULL;
 	struct commit_list *merge_bases = NULL;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/*
 	 * If we don't have both a left and a right pointer, there is no
 	 * reason to try and display a summary. The header line should contain
 	 * all the information the user needs.
 	 */
-	if (!left || !right)
+	if (!left || !right || !sub)
 		goto out;
 
 	/* Treat revision walker failure the same as missing commits */
@@ -580,13 +615,17 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 		goto out;
 	}
 
-	print_submodule_summary(&rev, o);
+	print_submodule_summary(sub, &rev, o);
 
 out:
 	if (merge_bases)
 		free_commit_list(merge_bases);
 	clear_commit_marks(left, ~0);
 	clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 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,
 	struct commit_list *merge_bases = NULL;
 	struct child_process cp = CHILD_PROCESS_INIT;
 	struct strbuf sb = STRBUF_INIT;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/* We need a valid left and right commit to display a difference */
 	if (!(left || is_null_oid(one)) ||
@@ -661,6 +702,10 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 		clear_commit_marks(left, ~0);
 	if (right)
 		clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 int should_update_submodules(void)
-- 
2.20.0.405.gbc1bbc6f85-goog
Previous: Stefan BellerNext: Stefan Beller
Message 19 of 26 in “sb/more-repo-in-api”
  1. 00/23 sb/more-repo-in-apiStefan Beller, Dec 15, 2018
  2. 01/23 sha1_file: allow read_object to read objects in arbitrary repositoriesStefan Beller, Dec 15, 2018
  3. 02/23 packfile: allow has_packed_and_bad to handle arbitrary repositoriesStefan Beller, Dec 15, 2018
  4. 03/23 object-store: allow read_object_file_extended to read from any repoStefan Beller, Dec 15, 2018
  5. 04/23 object-store: prepare read_object_file to deal with any repoStefan Beller, Dec 15, 2018
  6. 05/23 object-store: prepare has_{sha1, object}_file to handle any repoStefan Beller, Dec 15, 2018
  7. 06/23 object: parse_object to honor its repository argumentStefan Beller, Dec 15, 2018
  8. 07/23 commit: allow parse_commit* to handle any repoStefan Beller, Dec 15, 2018
  9. 08/23 commit-reach.c: allow paint_down_to_common to handle any repoStefan Beller, Dec 15, 2018
  10. 09/23 commit-reach.c: allow merge_bases_many to handle any repoStefan Beller, Dec 15, 2018
  11. 10/23 commit-reach.c: allow remove_redundant to handle any repoStefan Beller, Dec 15, 2018
  12. 11/23 commit-reach.c: allow get_merge_bases_many_0 to handle any repoStefan Beller, Dec 15, 2018
  13. 12/23 commit-reach: prepare get_merge_bases to handle any repoStefan Beller, Dec 15, 2018
  14. 13/23 commit-reach: prepare in_merge_bases[_many] to handle any repoStefan Beller, Dec 15, 2018
  15. 14/23 commit: prepare get_commit_buffer to handle any repoStefan Beller, Dec 15, 2018
  16. 15/23 commit: prepare repo_unuse_commit_buffer to handle any repoStefan Beller, Dec 15, 2018
  17. 16/23 commit: prepare logmsg_reencode to handle arbitrary repositoriesStefan Beller, Dec 15, 2018
  18. 17/23 pretty: prepare format_commit_message to handle arbitrary repositoriesStefan Beller, Dec 15, 2018
  19. 18/23 submodule: use submodule repos for object lookupStefan Beller, Dec 15, 2018
  20. 19/23 submodule: don't add submodule as odb for pushStefan Beller, Dec 15, 2018
  21. 20/23 commit-graph: convert remaining functions to handle any repoStefan Beller, Dec 15, 2018
  22. 21/23 commit: prepare free_commit_buffer and release_commit_memory for any repoStefan Beller, Dec 15, 2018
  23. 22/23 path.h: make REPO_GIT_PATH_FUNC repository agnosticStefan Beller, Dec 15, 2018
  24. 23/23 t/helper/test-repository: celebrate independence from the_repositoryStefan Beller, Dec 15, 2018
  25. Derrick StoleeDec 27, 2018
  26. Junio C HamanoDec 26, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.