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@xxxxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html