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

[PATCHv4 5/8] clone: factor out checking for an alternate path

From
Stefan Beller <sbeller@google.com>
Date
Aug 11, 2016, 23:14 UTC
Message-ID
<20160811231405.17318-6-sbeller@google.com>
In-Reply-To
<20160811231405.17318-1-sbeller@google.com>

In a later patch we want to determine if a path is suitable as an alternate from other commands than builtin/clone. Move the checking functionality of `add_one_reference` to `compute_alternate_path` that is defined in cache.h.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/clone.c | 42 ++++++--------------------------
 cache.h         |  1 +
 sha1_file.c     | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 35 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index f044a8c..24b17539 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -282,44 +282,16 @@ static void strip_trailing_slashes(char *dir)
 
 static int add_one_reference(struct string_list_item *item, void *cb_data)
 {
-	char *ref_git;
-	const char *repo;
-	struct strbuf alternate = STRBUF_INIT;
-
-	/* Beware: read_gitfile(), real_path() and mkpath() return static buffer */
-	ref_git = xstrdup(real_path(item->string));
-
-	repo = read_gitfile(ref_git);
-	if (!repo)
-		repo = read_gitfile(mkpath("%s/.git", ref_git));
-	if (repo) {
-		free(ref_git);
-		ref_git = xstrdup(repo);
-	}
-
-	if (!repo && is_directory(mkpath("%s/.git/objects", ref_git))) {
-		char *ref_git_git = mkpathdup("%s/.git", ref_git);
-		free(ref_git);
-		ref_git = ref_git_git;
-	} else if (!is_directory(mkpath("%s/objects", ref_git))) {
-		struct strbuf sb = STRBUF_INIT;
-		if (get_common_dir(&sb, ref_git))
-			die(_("reference repository '%s' as a linked checkout is not supported yet."),
-			    item->string);
-		die(_("reference repository '%s' is not a local repository."),
-		    item->string);
-	}
+	struct strbuf sb = STRBUF_INIT;
+	char *ref_git = compute_alternate_path(item->string, &sb);
 
-	if (!access(mkpath("%s/shallow", ref_git), F_OK))
-		die(_("reference repository '%s' is shallow"), item->string);
+	if (!ref_git)
+		die("%s", sb.buf);
 
-	if (!access(mkpath("%s/info/grafts", ref_git), F_OK))
-		die(_("reference repository '%s' is grafted"), item->string);
+	strbuf_addf(&sb, "%s/objects", ref_git);
+	add_to_alternates_file(sb.buf);
 
-	strbuf_addf(&alternate, "%s/objects", ref_git);
-	add_to_alternates_file(alternate.buf);
-	strbuf_release(&alternate);
-	free(ref_git);
+	strbuf_release(&sb);
 	return 0;
 }
 
diff --git a/cache.h b/cache.h
index 95a0bd3..35f41f7 100644
--- a/cache.h
+++ b/cache.h
@@ -1344,6 +1344,7 @@ extern struct alternate_object_database {
 } *alt_odb_list;
 extern void prepare_alt_odb(void);
 extern void read_info_alternates(const char * relative_base, int depth);
+extern char *compute_alternate_path(const char *path, struct strbuf *err);
 extern void add_to_alternates_file(const char *reference);
 typedef int alt_odb_fn(struct alternate_object_database *, void *);
 extern int foreach_alt_odb(alt_odb_fn, void*);
diff --git a/sha1_file.c b/sha1_file.c
index 02940f1..7351d8c 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -418,6 +418,80 @@ void add_to_alternates_file(const char *reference)
 	free(alts);
 }
 
+/*
+ * Compute the exact path an alternate is at and returns it. In case of
+ * error NULL is returned and the human readable error is added to `err`
+ * `path` may be relative and should point to $GITDIR.
+ * `err` must not be null.
+ */
+char *compute_alternate_path(const char *path, struct strbuf *err)
+{
+	char *ref_git = NULL;
+	const char *repo, *ref_git_s;
+	struct strbuf err_buf = STRBUF_INIT;
+
+	ref_git_s = real_path_if_valid(path);
+	if (!ref_git_s) {
+		strbuf_addf(&err_buf, _("path '%s' does not exist"), path);
+		goto out;
+	} else
+		/*
+		 * Beware: read_gitfile(), real_path() and mkpath()
+		 * return static buffer
+		 */
+		ref_git = xstrdup(ref_git_s);
+
+	repo = read_gitfile(ref_git);
+	if (!repo)
+		repo = read_gitfile(mkpath("%s/.git", ref_git));
+	if (repo) {
+		free(ref_git);
+		ref_git = xstrdup(repo);
+	}
+
+	if (!repo && is_directory(mkpath("%s/.git/objects", ref_git))) {
+		char *ref_git_git = mkpathdup("%s/.git", ref_git);
+		free(ref_git);
+		ref_git = ref_git_git;
+	} else if (!is_directory(mkpath("%s/objects", ref_git))) {
+		struct strbuf sb = STRBUF_INIT;
+		if (get_common_dir(&sb, ref_git)) {
+			strbuf_addf(&err_buf,
+				    _("reference repository '%s' as a linked "
+				      "checkout is not supported yet."),
+				    path);
+			goto out;
+		}
+
+		strbuf_addf(&err_buf, _("reference repository '%s' is not a "
+					"local repository."), path);
+		goto out;
+	}
+
+	if (!access(mkpath("%s/shallow", ref_git), F_OK)) {
+		strbuf_addf(&err_buf, _("reference repository '%s' is shallow"),
+			    path);
+		goto out;
+	}
+
+	if (!access(mkpath("%s/info/grafts", ref_git), F_OK)) {
+		strbuf_addf(&err_buf,
+			    _("reference repository '%s' is grafted"),
+			    path);
+		goto out;
+	}
+
+out:
+	if (err_buf.len) {
+		strbuf_addbuf(err, &err_buf);
+		free(ref_git);
+		ref_git = NULL;
+	}
+
+	strbuf_release(&err_buf);
+	return ref_git;
+}
+
 int foreach_alt_odb(alt_odb_fn fn, void *cb)
 {
 	struct alternate_object_database *ent;
-- 
2.9.2.737.g4a14654
Previous: Stefan BellerNext: Junio C Hamano
Message 6 of 18 in “[PATCHv4 0/6] git clone: Marry --recursive and --reference”
  1. Stefan BellerAug 11, 2016
  2. 1/8 t7408: modernize styleStefan Beller, Aug 11, 2016
  3. 2/8 t7408: merge short tests, factor out testing methodStefan Beller, Aug 11, 2016
  4. 3/8 submodule--helper module-clone: allow multiple referencesStefan Beller, Aug 11, 2016
  5. 4/8 submodule--helper update-clone: allow multiple referencesStefan Beller, Aug 11, 2016
  6. 5/8 clone: factor out checking for an alternate pathStefan Beller, Aug 11, 2016
  7. Junio C HamanoAug 12, 2016
  8. Stefan BellerAug 15, 2016
  9. Junio C HamanoAug 15, 2016
  10. Stefan BellerAug 15, 2016
  11. 7/8 clone: implement optional referencesStefan Beller, Aug 11, 2016
  12. 6/8 clone: clarify option_reference as requiredStefan Beller, Aug 11, 2016
  13. 8/8 clone: recursive and reference option triggers submodule alternatesStefan Beller, Aug 11, 2016
  14. Junio C HamanoAug 12, 2016
  15. Junio C HamanoAug 17, 2016
  16. Stefan BellerAug 17, 2016
  17. Junio C HamanoAug 17, 2016
  18. Stefan BellerAug 17, 2016

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.