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

[PATCH 06/17] {fetch,upload}-pack: support narrow repository

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Sep 5, 2010, 06:47 UTC
Message-ID
<1283669264-15759-7-git-send-email-pclouds@gmail.com>
In-Reply-To
<1283669264-15759-1-git-send-email-pclouds@gmail.com>

If $GIT_DIR/narrow is set, fetch-pack will send "narrow-tree" lines to upload-pack, where the prefixes are passed to rev-list mechanism to produce a narrow pack.

"narrow-tree" capability is required for this to work.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/git-fetch-pack.txt          |    3 ++
 Documentation/technical/pack-protocol.txt |    3 ++
 builtin/fetch-pack.c                      |    9 +++++++
 upload-pack.c                             |   38 +++++++++++++++++++++++++++-
 4 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
index 4a8487c..19b0d92 100644
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -25,6 +25,9 @@ This command degenerates to download everything to complete the
 asked refs from the remote side when the local side does not
 have a common ancestor commit.
 
+In narrow repositories, it asks 'git-upload-pack' to send only objects
+within narrow area defined in $GIT_DIR/narrow.
+
 
 OPTIONS
 -------
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index 369f91d..39474d2 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -215,6 +215,9 @@ discovery phase as 'want' lines. Clients MUST send at least one
 obj-id in a 'want' command which did not appear in the response
 obtained through ref discovery.
 
+If client is requesting narrow clone, it must send 'narrow-tree'
+lines before 'want' lines.
+
 If client is requesting a shallow clone, it will now send a 'deepen'
 line with the depth it is requesting.
 
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index dbd8b7b..591e0e4 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -37,6 +37,7 @@ static int marked;
 
 static struct commit_list *rev_list;
 static int non_common_revs, multi_ack, use_sideband;
+const char **narrow_prefix;
 
 static void rev_list_push(struct commit *commit, int mark)
 {
@@ -237,6 +238,12 @@ static int find_common(int fd[2], unsigned char *result_sha1,
 	for_each_ref(rev_list_insert_ref, NULL);
 
 	fetching = 0;
+	narrow_prefix = get_narrow_prefix();
+	if (narrow_prefix) {
+		const char **p = narrow_prefix;
+		while (*p)
+			packet_buf_write(&req_buf, "narrow-tree %s\n", *p++);
+	}
 	for ( ; refs ; refs = refs->next) {
 		unsigned char *remote = refs->old_sha1;
 		const char *remote_hex;
@@ -692,6 +699,8 @@ static struct ref *do_fetch_pack(int fd[2],
 
 	if (is_repository_shallow() && !server_supports("shallow"))
 		die("Server does not support shallow clients");
+	if (narrow_prefix && !server_supports("narrow-tree"))
+		die("Server does not support narrow-tree");
 	if (server_supports("multi_ack_detailed")) {
 		if (args.verbose)
 			fprintf(stderr, "Server supports multi_ack_detailed\n");
diff --git a/upload-pack.c b/upload-pack.c
index cc1983f..f3747e5 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -41,6 +41,8 @@ static int use_sideband;
 static int debug_fd;
 static int advertise_refs;
 static int stateless_rpc;
+const char **narrow_prefix;
+int narrow_prefix_nr;
 
 static void reset_timeout(void)
 {
@@ -118,6 +120,10 @@ static int do_rev_list(int in, int out, void *user_data)
 	revs.simplify_history = 0;
 	if (use_thin_pack)
 		revs.edge_hint = 1;
+	if (narrow_prefix) {
+		revs.prune_data = narrow_prefix;
+		narrow_prefix[narrow_prefix_nr] = NULL;
+	}
 
 	for (i = 0; i < want_obj.nr; i++) {
 		struct object *o = want_obj.objects[i].item;
@@ -154,9 +160,10 @@ static void create_pack_file(void)
 		"corruption on the remote side.";
 	int buffered = -1;
 	ssize_t sz;
-	const char *argv[10];
+	const char **argv;
 	int arg = 0;
 
+	argv = xmalloc(sizeof(*argv)*(11+narrow_prefix_nr));
 	if (shallow_nr) {
 		memset(&rev_list, 0, sizeof(rev_list));
 		rev_list.proc = do_rev_list;
@@ -180,6 +187,11 @@ static void create_pack_file(void)
 		argv[arg++] = "--delta-base-offset";
 	if (use_include_tag)
 		argv[arg++] = "--include-tag";
+	if (narrow_prefix) {
+		argv[arg++] = "--";
+		memcpy(argv+arg, narrow_prefix, narrow_prefix_nr*sizeof(*argv));
+		arg += narrow_prefix_nr;
+	}
 	argv[arg++] = NULL;
 
 	memset(&pack_objects, 0, sizeof(pack_objects));
@@ -307,6 +319,7 @@ static void create_pack_file(void)
 		error("git upload-pack: git-pack-objects died with error.");
 		goto fail;
 	}
+	free(argv);
 	if (shallow_nr && finish_async(&rev_list))
 		goto fail;	/* error was already reported */
 
@@ -500,6 +513,22 @@ static void receive_needs(void)
 		if (debug_fd)
 			write_in_full(debug_fd, line, len);
 
+		if (!prefixcmp(line, "narrow-tree ")) {
+			char *s;
+			int len;
+			len = strlen(line+12);
+			s = malloc(len+1);
+			memcpy(s, line+12, len-1);
+			s[len-1] = '\0'; /* \n */
+			if (s[len-2] == '/')
+				die("trailing slash in narrow prefix not allowed, %s", line);
+
+			narrow_prefix_nr++;
+			narrow_prefix = xrealloc(narrow_prefix,
+						 sizeof(*narrow_prefix)*(narrow_prefix_nr+1));
+			narrow_prefix[narrow_prefix_nr-1] = s;
+			continue;
+		}
 		if (!prefixcmp(line, "shallow ")) {
 			unsigned char sha1[20];
 			struct object *object;
@@ -563,6 +592,9 @@ static void receive_needs(void)
 	if (!use_sideband && daemon_mode)
 		no_progress = 1;
 
+	if (narrow_prefix)
+		use_thin_pack = 0;
+
 	if (depth == 0 && shallows.nr == 0)
 		return;
 	if (depth > 0) {
@@ -620,7 +652,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
 {
 	static const char *capabilities = "multi_ack thin-pack side-band"
 		" side-band-64k ofs-delta shallow no-progress"
-		" include-tag multi_ack_detailed";
+		" include-tag multi_ack_detailed narrow-tree";
 	struct object *o = parse_object(sha1);
 
 	if (!o)
@@ -725,6 +757,8 @@ int main(int argc, char **argv)
 		die("'%s' does not appear to be a git repository", dir);
 	if (is_repository_shallow())
 		die("attempt to fetch/clone from a shallow repository");
+	if (get_narrow_prefix())
+		die("attempt to fetch/clone from a narrow repository");
 	if (getenv("GIT_DEBUG_SEND_PACK"))
 		debug_fd = atoi(getenv("GIT_DEBUG_SEND_PACK"));
 	upload_pack();
-- 
1.7.1.rc1.69.g24c2f7
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 7 of 25 in “Narrow clone v3 (was subtree clone)”
  1. 00/17 Narrow clone v3 (was subtree clone)Nguyễn Thái Ngọc Duy, Sep 5, 2010
  2. 01/17 rev-list: do not do commit simplification if simplify_history = 0Nguyễn Thái Ngọc Duy, Sep 5, 2010
  3. 02/17 tree.c: add path_to_sha1()Nguyễn Thái Ngọc Duy, Sep 5, 2010
  4. 03/17 Introduce $GIT_DIR/narrowNguyễn Thái Ngọc Duy, Sep 5, 2010
  5. 04/17 index: make narrow index incompatible with older gitNguyễn Thái Ngọc Duy, Sep 5, 2010
  6. 05/17 pack-objects: support narrow packs with pathspecsNguyễn Thái Ngọc Duy, Sep 5, 2010
  7. 06/17 {fetch,upload}-pack: support narrow repositoryNguyễn Thái Ngọc Duy, Sep 5, 2010
  8. 07/17 unpack-trees: split traverse_trees() code into a separate functionNguyễn Thái Ngọc Duy, Sep 5, 2010
  9. 08/17 unpack-trees: support unpack trees in narrow repositoryNguyễn Thái Ngọc Duy, Sep 5, 2010
  10. 09/17 cache-tree: only cache tree within narrow areaNguyễn Thái Ngọc Duy, Sep 5, 2010
  11. 10/17 get_pathspec(): support narrow pathspec rewritingNguyễn Thái Ngọc Duy, Sep 5, 2010
  12. 11/17 pathspec retrieval fixNguyễn Thái Ngọc Duy, Sep 5, 2010
  13. 12/17 clone: support --narrow optionNguyễn Thái Ngọc Duy, Sep 5, 2010
  14. 13/17 commit: add narrow's commit_tree versionNguyễn Thái Ngọc Duy, Sep 5, 2010
  15. 14/17 commit: use commit_narrow_tree() to support narrow repoNguyễn Thái Ngọc Duy, Sep 5, 2010
  16. 15/17 write-tree: requires --narrow-base in narrow repositoryNguyễn Thái Ngọc Duy, Sep 5, 2010
  17. 16/17 merge: try to do local merge if possible in narrow repoNguyễn Thái Ngọc Duy, Sep 5, 2010
  18. 17/17 Add narrow clone demonstration testNguyễn Thái Ngọc Duy, Sep 5, 2010
  19. Sverre RabbelierSep 5, 2010
  20. Nguyen Thai Ngoc DuySep 5, 2010
  21. Elijah NewrenSep 5, 2010
  22. Elijah NewrenSep 6, 2010
  23. Nguyen Thai Ngoc DuySep 6, 2010
  24. Sverre RabbelierSep 6, 2010
  25. Elijah NewrenSep 6, 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.