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

[PATCH 1/6] Remote helper: accept ':<value> <name>' as a response to 'list'

From
Tomas Carnecky <tom@dbservice.com>
Date
Oct 3, 2010, 12:21 UTC
Message-ID
<1286108511-55876-1-git-send-email-tom@dbservice.com>
In-Reply-To
<4CA86A12.6080905@dbservice.com>

Parse <value> as the remote-specific revision indicator. The ref is first stored as 'impure', meaning that it doesn't have any representation within git. Only after the remote helper fetches that version into git, it can tell us which git object (SHA1) that revision maps to. That is done with the new reply 'map <value> <sha1>' to the 'list' command.

Signed-off-by: Tomas Carnecky <tom@dbservice.com>
---
 builtin/ls-remote.c |    7 ++++++-
 cache.h             |    2 +-
 remote.c            |    8 +++++++-
 transport-helper.c  |   41 +++++++++++++++++++++++++++++++++++++++--
 4 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 97eed40..23dd0d2 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -109,7 +109,12 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 			continue;
 		if (!tail_match(pattern, ref->name))
 			continue;
-		printf("%s	%s\n", sha1_to_hex(ref->old_sha1), ref->name);
+		if (ref->impure) {
+			int len = strlen(ref->impure) + strlen(" (impure)");
+			printf("%s (impure)%*s  %s\n", ref->impure, 40 - len, " ", ref->name);
+		} else {
+			printf("%s      %s\n", sha1_to_hex(ref->old_sha1), ref->name);
+		}
 	}
 	return 0;
 }
diff --git a/cache.h b/cache.h
index 2ef2fa3..23b43a6 100644
--- a/cache.h
+++ b/cache.h
@@ -905,7 +905,7 @@ struct ref {
 	struct ref *next;
 	unsigned char old_sha1[20];
 	unsigned char new_sha1[20];
-	char *symref;
+	char *symref, *impure;
 	unsigned int force:1,
 		merge:1,
 		nonfastforward:1,
diff --git a/remote.c b/remote.c
index 9143ec7..c355f11 100644
--- a/remote.c
+++ b/remote.c
@@ -907,6 +907,7 @@ static struct ref *copy_ref(const struct ref *ref)
 	memcpy(cpy, ref, sizeof(struct ref) + len + 1);
 	cpy->next = NULL;
 	cpy->symref = ref->symref ? xstrdup(ref->symref) : NULL;
+	cpy->impure = ref->impure ? xstrdup(ref->impure) : NULL;
 	cpy->remote_status = ref->remote_status ? xstrdup(ref->remote_status) : NULL;
 	cpy->peer_ref = copy_ref(ref->peer_ref);
 	return cpy;
@@ -931,6 +932,7 @@ static void free_ref(struct ref *ref)
 	free_ref(ref->peer_ref);
 	free(ref->remote_status);
 	free(ref->symref);
+	free(ref->impure);
 	free(ref);
 }
 
@@ -1453,7 +1455,11 @@ int resolve_remote_symref(struct ref *ref, struct ref *list)
 		return 0;
 	for (; list; list = list->next)
 		if (!strcmp(ref->symref, list->name)) {
-			hashcpy(ref->old_sha1, list->old_sha1);
+			if (list->impure) {
+				ref->impure = xstrdup(list->impure);
+			} else {
+				hashcpy(ref->old_sha1, list->old_sha1);
+			}
 			return 0;
 		}
 	return 1;
diff --git a/transport-helper.c b/transport-helper.c
index acfc88e..0fe886e 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -307,6 +307,29 @@ static int release_helper(struct transport *transport)
 	return 0;
 }
 
+/* Map an impure ref to its actual value within Git. */
+static void map_impure_ref(int nr_heads, struct ref **to_fetch, char *map)
+{
+	int i;
+	char *eov;
+
+	eov = strchr(map, ' ');
+	if (!eov)
+		die("Malformed impure ref mapping: %s", map);
+	*eov = '\0';
+
+	/* There may be multiple impure refs with the same value, be sure to
+	 * map all of them. */
+	for (i = 0; i < nr_heads; i++) {
+		struct ref *posn = to_fetch[i];
+		if (posn->impure && !strcmp(map, posn->impure)) {
+			get_sha1_hex(eov + 1, posn->old_sha1);
+			free(posn->impure);
+			posn->impure = NULL;
+		}
+	}
+}
+
 static int fetch_with_fetch(struct transport *transport,
 			    int nr_heads, struct ref **to_fetch)
 {
@@ -318,11 +341,17 @@ static int fetch_with_fetch(struct transport *transport,
 
 	for (i = 0; i < nr_heads; i++) {
 		const struct ref *posn = to_fetch[i];
+
 		if (posn->status & REF_STATUS_UPTODATE)
 			continue;
 
-		strbuf_addf(&buf, "fetch %s %s\n",
+		if (posn->impure) {
+			strbuf_addf(&buf, "fetch %s %s\n",
+				posn->impure, posn->name);
+		} else {
+			strbuf_addf(&buf, "fetch %s %s\n",
 			    sha1_to_hex(posn->old_sha1), posn->name);
+		}
 	}
 
 	strbuf_addch(&buf, '\n');
@@ -337,12 +366,18 @@ static int fetch_with_fetch(struct transport *transport,
 				warning("%s also locked %s", data->name, name);
 			else
 				transport->pack_lockfile = xstrdup(name);
+		} else if (!prefixcmp(buf.buf, "map ")) {
+			map_impure_ref(nr_heads, to_fetch, buf.buf + 4);
 		}
 		else if (!buf.len)
 			break;
 		else
 			warning("%s unexpectedly said: '%s'", data->name, buf.buf);
 	}
+
+	/* The helper may have created one or more new packs. */
+	reprepare_packed_git();
+
 	strbuf_release(&buf);
 	return 0;
 }
@@ -824,7 +859,9 @@ static struct ref *get_refs_list(struct transport *transport, int for_push)
 		*tail = alloc_ref(eov + 1);
 		if (buf.buf[0] == '@')
 			(*tail)->symref = xstrdup(buf.buf + 1);
-		else if (buf.buf[0] != '?')
+		else if (buf.buf[0] == ':') {
+			(*tail)->impure = xstrdup(buf.buf + 1);
+		} else if (buf.buf[0] != '?')
 			get_sha1_hex(buf.buf, (*tail)->old_sha1);
 		if (eon) {
 			if (has_attribute(eon + 1, "unchanged")) {
-- 
1.7.3.37.gb6088b
Previous: Tomas CarneckyNext: Jonathan Nieder
Message 2 of 21 in “[RFC] New type of remote helpers”
  1. Tomas CarneckyOct 3, 2010
  2. 1/6 Remote helper: accept ':<value> <name>' as a response to 'list'Tomas Carnecky, Oct 3, 2010
  3. Jonathan NiederOct 5, 2010
  4. Sverre RabbelierOct 7, 2010
  5. 2/6 Allow more than one keepfile in the transportTomas Carnecky, Oct 3, 2010
  6. Jonathan NiederOct 5, 2010
  7. 3/6 Allow the transport fetch command to add additional refsTomas Carnecky, Oct 3, 2010
  8. Jonathan NiederOct 5, 2010
  9. 4/6 Rename get_mode() to decode_tree_mode() and export itTomas Carnecky, Oct 3, 2010
  10. Jonathan NiederOct 5, 2010
  11. 5/6 Introduce the git fast-import-helperTomas Carnecky, Oct 3, 2010
  12. Jonathan NiederOct 3, 2010
  13. Tomas CarneckyOct 3, 2010
  14. Sverre RabbelierOct 3, 2010
  15. Tomas CarneckyOct 3, 2010
  16. Sverre RabbelierOct 3, 2010
  17. 6/6 Add git-remote-svnTomas Carnecky, Oct 3, 2010
  18. Jonathan NiederOct 5, 2010
  19. Sverre RabbelierOct 3, 2010
  20. Jonathan NiederOct 3, 2010
  21. Ramkumar RamachandraOct 3, 2010

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.