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

[PATCH v2 16/38] resolve_gitlink_ref(): implement using resolve_ref_recursively()

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Sep 4, 2016, 16:08 UTC
Message-ID
<1e7e45a2a96e1ae7d45a1072c3c965bc7c02105c.1473003903.git.mhagger@alum.mit.edu>
In-Reply-To
<cover.1473003902.git.mhagger@alum.mit.edu>

resolve_ref_recursively() can handle references in arbitrary files reference stores, so use it to resolve "gitlink" (i.e., submodule) references. Aside from removing redundant code, this allows submodule lookups to benefit from the much more robust code that we use for reading non-submodule references. And, since the code is now agnostic about reference backends, it will work for any future references backend (so move its definition to refs.c).

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 refs.c               | 24 +++++++++++++++++++
 refs/files-backend.c | 67 ----------------------------------------------------
 2 files changed, 24 insertions(+), 67 deletions(-)
diff --git a/refs.c b/refs.c
index 3723169..647ead5 100644
--- a/refs.c
+++ b/refs.c
@@ -1299,6 +1299,30 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
 				       resolve_flags, sha1, flags);
 }
 
+int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
+{
+	int len = strlen(path);
+	struct strbuf submodule = STRBUF_INIT;
+	struct ref_store *refs;
+	int flags;
+
+	while (len && path[len-1] == '/')
+		len--;
+	if (!len)
+		return -1;
+
+	strbuf_add(&submodule, path, len);
+	refs = get_ref_store(submodule.buf);
+	strbuf_release(&submodule);
+	if (!refs)
+		return -1;
+
+	if (!resolve_ref_recursively(refs, refname, 0, sha1, &flags) ||
+	    is_null_sha1(sha1))
+		return -1;
+	return 0;
+}
+
 /* A pointer to the ref_store for the main repository: */
 static struct ref_store *main_ref_store;
 
diff --git a/refs/files-backend.c b/refs/files-backend.c
index ce6fe94..6382c6b 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1494,73 +1494,6 @@ static void unlock_ref(struct ref_lock *lock)
 	free(lock);
 }
 
-#define MAXREFLEN (1024)
-
-static int resolve_gitlink_ref_recursive(struct files_ref_store *refs,
-					 const char *refname, unsigned char *sha1,
-					 int recursion)
-{
-	int fd, len;
-	char buffer[128], *p;
-	char *path;
-
-	if (recursion > SYMREF_MAXDEPTH || strlen(refname) > MAXREFLEN)
-		return -1;
-	path = *refs->base.submodule
-		? git_pathdup_submodule(refs->base.submodule, "%s", refname)
-		: git_pathdup("%s", refname);
-	fd = open(path, O_RDONLY);
-	free(path);
-	if (fd < 0) {
-		unsigned int flags;
-
-		return resolve_packed_ref(refs, refname, sha1, &flags);
-	}
-
-	len = read(fd, buffer, sizeof(buffer)-1);
-	close(fd);
-	if (len < 0)
-		return -1;
-	while (len && isspace(buffer[len-1]))
-		len--;
-	buffer[len] = 0;
-
-	/* Was it a detached head or an old-fashioned symlink? */
-	if (!get_sha1_hex(buffer, sha1))
-		return 0;
-
-	/* Symref? */
-	if (strncmp(buffer, "ref:", 4))
-		return -1;
-	p = buffer + 4;
-	while (isspace(*p))
-		p++;
-
-	return resolve_gitlink_ref_recursive(refs, p, sha1, recursion+1);
-}
-
-int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
-{
-	int len = strlen(path);
-	struct strbuf submodule = STRBUF_INIT;
-	struct files_ref_store *refs;
-
-	while (len && path[len-1] == '/')
-		len--;
-	if (!len)
-		return -1;
-
-	strbuf_add(&submodule, path, len);
-	refs = get_files_ref_store(submodule.buf, "resolve_gitlink_ref");
-	if (!refs) {
-		strbuf_release(&submodule);
-		return -1;
-	}
-	strbuf_release(&submodule);
-
-	return resolve_gitlink_ref_recursive(refs, refname, sha1, 0);
-}
-
 /*
  * Lock refname, without following symrefs, and set *lock_p to point
  * at a newly-allocated lock object. Fill in lock->old_oid, referent,
-- 
2.9.3
Previous: Michael HaggertyNext: Michael Haggerty
Message 13 of 49 in “Virtualization of the refs API”
  1. 00/38 Virtualization of the refs APIMichael Haggerty, Sep 4, 2016
  2. 06/38 add_packed_ref(): add a files_ref_store argumentMichael Haggerty, Sep 4, 2016
  3. 02/38 rename_ref_available(): add docstringMichael Haggerty, Sep 4, 2016
  4. Jakub NarębskiSep 6, 2016
  5. Michael HaggertySep 7, 2016
  6. 01/38 resolve_gitlink_ref(): eliminate temporary variableMichael Haggerty, Sep 4, 2016
  7. 04/38 refs: add a backend method structureMichael Haggerty, Sep 4, 2016
  8. David TurnerSep 4, 2016
  9. 07/38 get_packed_ref(): add a files_ref_store argumentMichael Haggerty, Sep 4, 2016
  10. 14/38 read_raw_ref(): take a (struct ref_store *) argumentMichael Haggerty, Sep 4, 2016
  11. 10/38 refs: add a transaction_commit() methodMichael Haggerty, Sep 4, 2016
  12. 03/38 refs: rename struct ref_cache to files_ref_storeMichael Haggerty, Sep 4, 2016
  13. 16/38 resolve_gitlink_ref(): implement using resolve_ref_recursively()Michael Haggerty, Sep 4, 2016
  14. 18/38 resolve_gitlink_ref(): rename path parameter to submoduleMichael Haggerty, Sep 4, 2016
  15. 08/38 resolve_missing_loose_ref(): add a files_ref_store argumentMichael Haggerty, Sep 4, 2016
  16. 31/38 refs: add method iterator_beginMichael Haggerty, Sep 4, 2016
  17. 35/38 refs: add methods to init refs dbMichael Haggerty, Sep 4, 2016
  18. 38/38 refs: implement iteration over only per-worktree refsMichael Haggerty, Sep 4, 2016
  19. David TurnerSep 8, 2016
  20. 32/38 refs: add methods for reflogMichael Haggerty, Sep 4, 2016
  21. 33/38 refs: add method for initial ref transaction commitMichael Haggerty, Sep 4, 2016
  22. 29/38 split_symref_update(): add a files_ref_store argumentMichael Haggerty, Sep 4, 2016
  23. 37/38 refs: make lock genericMichael Haggerty, Sep 4, 2016
  24. 30/38 files_ref_iterator_begin(): take a ref_store argumentMichael Haggerty, Sep 4, 2016
  25. 22/38 refs: make create_symref() virtualMichael Haggerty, Sep 4, 2016
  26. 15/38 resolve_ref_recursively(): new functionMichael Haggerty, Sep 4, 2016
  27. 27/38 lock_ref_for_update(): add a files_ref_store argumentMichael Haggerty, Sep 4, 2016
  28. 36/38 refs: add method to rename refsMichael Haggerty, Sep 4, 2016
  29. 26/38 commit_ref_update(): add a files_ref_store argumentMichael Haggerty, Sep 4, 2016
  30. 28/38 lock_ref_sha1_basic(): add a files_ref_store argumentMichael Haggerty, Sep 4, 2016
  31. 34/38 refs: make delete_refs() virtualMichael Haggerty, Sep 4, 2016
  32. 12/38 resolve_packed_ref(): rename function from resolve_missing_loose_ref()Michael Haggerty, Sep 4, 2016
  33. 13/38 resolve_gitlink_packed_ref(): remove functionMichael Haggerty, Sep 4, 2016
  34. 19/38 refs: make read_raw_ref() virtualMichael Haggerty, Sep 4, 2016
  35. 25/38 lock_raw_ref(): add a files_ref_store argumentMichael Haggerty, Sep 4, 2016
  36. 11/38 refs: reorder definitionsMichael Haggerty, Sep 4, 2016
  37. 17/38 resolve_gitlink_ref(): avoid memory allocation in many casesMichael Haggerty, Sep 4, 2016
  38. 24/38 repack_without_refs(): add a files_ref_store argumentMichael Haggerty, Sep 4, 2016
  39. 20/38 refs: make verify_refname_available() virtualMichael Haggerty, Sep 4, 2016
  40. 05/38 refs: create a base class "ref_store" for files_ref_storeMichael Haggerty, Sep 4, 2016
  41. David TurnerSep 4, 2016
  42. Michael HaggertySep 5, 2016
  43. Stefan BellerSep 5, 2016
  44. David TurnerSep 5, 2016
  45. 09/38 {lock,commit,rollback}_packed_refs(): add files_ref_store argumentsMichael Haggerty, Sep 4, 2016
  46. 21/38 refs: make pack_refs() virtualMichael Haggerty, Sep 4, 2016
  47. 23/38 refs: make peel_ref() virtualMichael Haggerty, Sep 4, 2016
  48. Junio C HamanoSep 7, 2016
  49. Michael HaggertySep 8, 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.