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

[PATCH 03/17] Introduce $GIT_DIR/narrow

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

This file contains a sorted list of narrow prefix, used in narrow repositories.

rev-parse also learns --narrow-prefix to print $GIT_DIR/narrow out
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/git-rev-parse.txt        |    3 +
 Documentation/gitrepository-layout.txt |    5 ++
 Makefile                               |    2 +
 builtin/rev-parse.c                    |    8 +++
 cache.h                                |    3 +
 environment.c                          |    2 +
 narrow-tree.c                          |  106 ++++++++++++++++++++++++++++++++
 narrow-tree.h                          |    3 +
 t/t0063-narrow-repo.sh                 |   46 ++++++++++++++
 9 files changed, 178 insertions(+), 0 deletions(-)
 create mode 100644 narrow-tree.c
 create mode 100644 narrow-tree.h
 create mode 100755 t/t0063-narrow-repo.sh
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index be4c053..5d5e77b 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -148,6 +148,9 @@ shown.  If the pattern does not contain a globbing character (`?`,
 --is-bare-repository::
 	When the repository is bare print "true", otherwise "false".
 
+--narrow-prefix::
+	Print narrow prefix git reads from $GIT_DIR/narrow.
+
 --local-env-vars::
 	List the GIT_* environment variables that are local to the
 	repository (e.g. GIT_DIR or GIT_WORK_TREE, but not GIT_EDITOR).
diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt
index eb3d040..82e0350 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -193,6 +193,11 @@ shallow::
 	and maintained by shallow clone mechanism.  See `--depth`
 	option to linkgit:git-clone[1] and linkgit:git-fetch[1].
 
+narrow::
+	This file contains narrow prefix in sorted order. It is
+	internally used and maintained by narrow clone mechanism.
+	See `--narrow-tree` option to linkgit:git-clone[1].
+
 SEE ALSO
 --------
 linkgit:git-init[1],
diff --git a/Makefile b/Makefile
index b4745a5..f1aaba9 100644
--- a/Makefile
+++ b/Makefile
@@ -525,6 +525,7 @@ LIB_H += sigchain.h
 LIB_H += strbuf.h
 LIB_H += string-list.h
 LIB_H += submodule.h
+LIB_H += narrow-tree.h
 LIB_H += tag.h
 LIB_H += transport.h
 LIB_H += tree.h
@@ -629,6 +630,7 @@ LIB_OBJS += sigchain.o
 LIB_OBJS += strbuf.o
 LIB_OBJS += string-list.o
 LIB_OBJS += submodule.o
+LIB_OBJS += narrow-tree.o
 LIB_OBJS += symlinks.o
 LIB_OBJS += tag.o
 LIB_OBJS += trace.o
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index a5a1c86..590df6f 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -675,6 +675,14 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 						: "false");
 				continue;
 			}
+			if (!strcmp(arg, "--narrow-prefix")) {
+				const char **p = get_narrow_prefix();
+				if (!p)
+					continue;
+				while (*p)
+					printf("%s\n", *p++);
+				continue;
+			}
 			if (!prefixcmp(arg, "--since=")) {
 				show_datestring("--max-age=", arg+8);
 				continue;
diff --git a/cache.h b/cache.h
index eb77e1d..d09c4fc 100644
--- a/cache.h
+++ b/cache.h
@@ -1105,4 +1105,7 @@ const char *split_cmdline_strerror(int cmdline_errno);
 /* builtin/merge.c */
 int checkout_fast_forward(const unsigned char *from, const unsigned char *to);
 
+/* narrow-tree.c */
+extern const char **get_narrow_prefix();
+
 #endif /* CACHE_H */
diff --git a/environment.c b/environment.c
index 83d38d3..41fcbd4 100644
--- a/environment.c
+++ b/environment.c
@@ -8,6 +8,7 @@
  * are.
  */
 #include "cache.h"
+#include "narrow-tree.h"
 
 char git_default_email[MAX_GITNAME];
 char git_default_name[MAX_GITNAME];
@@ -105,6 +106,7 @@ static void setup_git_env(void)
 		git_graft_file = git_pathdup("info/grafts");
 	if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
 		read_replace_refs = 0;
+	check_narrow_prefix();
 }
 
 int is_bare_repository(void)
diff --git a/narrow-tree.c b/narrow-tree.c
new file mode 100644
index 0000000..85dbab4
--- /dev/null
+++ b/narrow-tree.c
@@ -0,0 +1,106 @@
+#include "cache.h"
+#include "narrow-tree.h"
+
+static const char **narrow_prefix;
+static char *narrow_buf;
+
+int valid_narrow_prefix(const char *prefix, const char *prev_prefix, int quiet)
+{
+	int len = strlen(prefix);
+
+	if (!*prefix) {
+		if (!quiet)
+			error("Empty line in $GIT_DIR/narrow");
+		return 0;
+	}
+
+	if (prefix[len-1] == '/') {
+		if (!quiet)
+			error("Trailing slash not allowed in $GIT_DIR: %s", prefix);
+		return 0;
+	}
+
+	if (prev_prefix) {
+		if (strcmp(prev_prefix, prefix) >= 0) {
+			if (!quiet)
+				error("$GIT_DIR/narrow is unsorted at %s", prefix);
+			return 0;
+		}
+		len = strlen(prev_prefix);
+		if (!strncmp(prev_prefix, prefix, len) &&
+		    prefix[len] == '/') {
+			if (!quiet) {
+				error("$GIT_DIR/narrow has nested prefix (%s and %s)",
+				      prev_prefix, prefix);
+				return 0;
+			}
+		}
+	}
+	return 1;
+}
+
+int check_narrow_prefix()
+{
+	struct stat st;
+	int fd, i, n, len;
+	char *p, *pp;
+
+	if (stat(git_path("narrow"), &st) || st.st_size == 0)
+		return 0;
+
+	narrow_buf = xmalloc(st.st_size+2); /* NULL and \n */
+
+	fd = open(git_path("narrow"), O_RDONLY);
+	if (fd == -1)
+		return 0;
+
+	if (xread(fd, narrow_buf, st.st_size) != st.st_size)
+		die("failed to read $GIT_DIR/narrow");
+	close(fd);
+
+	if (narrow_buf[st.st_size-1] == '\n')
+		narrow_buf[st.st_size] = '\0';
+	else {
+		narrow_buf[st.st_size] = '\n';
+		narrow_buf[st.st_size+1] = '\0';
+	}
+	n = 0;
+	for (p = narrow_buf; *p; p = strchr(p, '\n')+1)
+		n++;
+	if (!n)
+		return 0;
+	narrow_prefix = xmalloc(sizeof(*narrow_prefix)*(n+1));
+	p = narrow_buf;
+	for (i = 0; i < n; i++) {
+		pp = p;
+		p = strchr(p, '\n') + 1;
+		len = p - pp;
+		while (len &&
+		       (pp[len-1] == '\n' ||
+			pp[len-1] == '\r'))
+			len--;
+		pp[len] = '\0';
+		if (!valid_narrow_prefix(pp, i ? narrow_prefix[i-1] : NULL, 0))
+			die("Invalid $GIT_DIR/narrow");
+		narrow_prefix[i] = pp;
+	}
+	narrow_prefix[n] = NULL;
+	return 0;
+}
+
+const char **get_narrow_prefix()
+{
+	return narrow_prefix;
+}
+
+char *get_narrow_string()
+{
+	struct strbuf sb = STRBUF_INIT;
+	const char **prefix = get_narrow_prefix();
+	while (*prefix) {
+		strbuf_addstr(&sb, *prefix);
+		strbuf_addch(&sb, '\n');
+		prefix++;
+	}
+	return strbuf_detach(&sb, NULL);
+}
diff --git a/narrow-tree.h b/narrow-tree.h
new file mode 100644
index 0000000..2097436
--- /dev/null
+++ b/narrow-tree.h
@@ -0,0 +1,3 @@
+extern int valid_narrow_prefix(const char *prefix, const char *prev_prefix, int quiet);
+extern int check_narrow_prefix();
+extern char *get_narrow_string();
diff --git a/t/t0063-narrow-repo.sh b/t/t0063-narrow-repo.sh
new file mode 100755
index 0000000..51b753d
--- /dev/null
+++ b/t/t0063-narrow-repo.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+test_description='narrow index'
+
+. ./test-lib.sh
+
+test_expect_success 'empty $GIT_DIR/narrow' '
+	: >.git/narrow &&
+	git rev-parse --narrow-prefix >result &&
+	: >expected
+	test_cmp expected result
+'
+
+test_expect_success 'empty line' '
+	echo >.git/narrow &&
+	test_must_fail git rev-parse --narrow-prefix
+'
+
+test_expect_success 'single prefix' '
+	echo a >.git/narrow &&
+	git rev-parse --narrow-prefix >result &&
+	echo a >expected
+	test_cmp expected result
+'
+
+test_expect_success 'trailing slash in prefix' '
+	echo a/ >.git/narrow &&
+	test_must_fail git rev-parse --narrow-prefix
+'
+
+test_expect_success 'sorted multiple prefix' '
+	echo a >.git/narrow &&
+	echo b >>.git/narrow &&
+	git rev-parse --narrow-prefix >result &&
+	echo a >expected
+	echo b >>expected
+	test_cmp expected result
+'
+
+test_expect_success 'unsorted multiple prefix' '
+	echo b >.git/narrow &&
+	echo a >>.git/narrow &&
+	test_must_fail git rev-parse --narrow-prefix
+'
+
+test_done
-- 
1.7.1.rc1.69.g24c2f7
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 4 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.