Signed-off-by: Elijah Newren <newren@xxxxxxxxx> --- diff.h | 1 - t/t5720-sparse-repository-basics.sh | 10 +++--- tree-diff.c | 2 +- tree-walk.c | 48 ++++++++++++++++++++++++++++++---- tree-walk.h | 3 ++ 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/diff.h b/diff.h index 986a015..e17383c 100644 --- a/diff.h +++ b/diff.h @@ -171,7 +171,6 @@ extern int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const char *base, struct diff_options *opt); extern int diff_root_tree_sha1(const unsigned char *new, const char *base, struct diff_options *opt); -extern int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt); struct combine_diff_path { struct combine_diff_path *next; diff --git a/t/t5720-sparse-repository-basics.sh b/t/t5720-sparse-repository-basics.sh index b8e9a3a..b946c23 100755 --- a/t/t5720-sparse-repository-basics.sh +++ b/t/t5720-sparse-repository-basics.sh @@ -41,7 +41,7 @@ test_expect_success 'setup' ' ) ' -test_expect_failure 'make sparse repository' ' +test_expect_success 'make sparse repository' ' git clone -q "file://$(pwd)/src" dst && ( cd dst && @@ -55,7 +55,7 @@ test_expect_failure 'make sparse repository' ' cd dst 2>/dev/null || test_done srcgit="--git-dir=../src/.git" -test_expect_failure 'plumbing: ls-files works' ' +test_expect_success 'plumbing: ls-files works' ' git ls-files > output && test "sub/b/file" = "$(cat output)" ' @@ -98,19 +98,19 @@ test_expect_failure 'basic: diff works' ' git diff master~3 ' -test_expect_failure 'basic: checkout works' ' +test_expect_success 'basic: checkout works' ' git checkout master~2 && git checkout master ' -test_expect_failure 'basic: status works with modified stuff' ' +test_expect_success 'basic: status works with modified stuff' ' git status && echo more content >> sub/b/file && echo newfile content >> sub/b/whatever && git status ' -test_expect_failure 'basic: add works' ' +test_expect_success 'basic: add works' ' git add sub/b/file && git add sub/b/whatever ' diff --git a/tree-diff.c b/tree-diff.c index 951b53b..95e956e 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -261,7 +261,7 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree } } -static void skip_uninteresting(struct tree_desc *t, const char *base, int baselen, struct diff_options *opt, int *all_interesting) +void skip_uninteresting(struct tree_desc *t, const char *base, int baselen, struct diff_options *opt, int *all_interesting) { while (t->size) { int show = tree_entry_interesting(t, base, baselen, opt); diff --git a/tree-walk.c b/tree-walk.c index a9bbf4e..a584dd8 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -66,8 +66,19 @@ static void entry_clear(struct name_entry *a) memset(a, 0, sizeof(*a)); } -static void entry_extract(struct tree_desc *t, struct name_entry *a) +struct tree_sparse_info { + int all_interesting; + const char *base; + int baselen; + struct diff_options *diffopt; /* really is const too */ +}; + +static void entry_extract(struct tree_desc *t, struct name_entry *a, + struct tree_sparse_info *i) { + if (!i->all_interesting) + skip_uninteresting(t, i->base, i->baselen, + i->diffopt, &i->all_interesting); *a = t->entry; } @@ -219,7 +230,8 @@ static int check_entry_match(const char *a, int a_len, const char *b, int b_len) static void extended_entry_extract(struct tree_desc_x *t, struct name_entry *a, const char *first, - int first_len) + int first_len, + struct tree_sparse_info *i) { const char *path; int len; @@ -235,7 +247,7 @@ static void extended_entry_extract(struct tree_desc_x *t, entry_clear(a); break; /* not found */ } - entry_extract(&t->d, a); + entry_extract(&t->d, a, i); for (skip = t->skip; skip; skip = skip->prev) if (a->path == skip->ptr) break; /* found */ @@ -268,7 +280,7 @@ static void extended_entry_extract(struct tree_desc_x *t, */ probe = t->d; while (probe.size) { - entry_extract(&probe, a); + entry_extract(&probe, a, i); path = a->path; len = tree_entry_len(a->path, a->sha1); switch (check_entry_match(first, first_len, path, len)) { @@ -315,6 +327,28 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info) struct name_entry *entry = xmalloc(n*sizeof(*entry)); int i; struct tree_desc_x *tx = xcalloc(n, sizeof(*tx)); + char prefix[PATH_MAX]; + struct tree_sparse_info sparse_info; + if (!git_sparse_pathspecs) + sparse_info.all_interesting = 1; + else { + if (info->prev) + make_traverse_path(prefix, info->prev, &info->name); + else + strcpy(prefix, info->name.path); + sparse_info.baselen = strlen(prefix); + + /* prefix must be slash terminated if non-empty */ + if (sparse_info.baselen) { + sparse_info.baselen += 1; + prefix[sparse_info.baselen-1] = '/'; + prefix[sparse_info.baselen] = '\0'; + } + + sparse_info.all_interesting = 0; + sparse_info.base = prefix; + sparse_info.diffopt = &git_sparse_diffopts; + } for (i = 0; i < n; i++) tx[i].d = t[i]; @@ -328,7 +362,7 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info) for (i = 0; i < n; i++) { e = entry + i; - extended_entry_extract(tx + i, e, NULL, 0); + extended_entry_extract(tx + i, e, NULL, 0, &sparse_info); } /* @@ -356,7 +390,9 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info) if (first) { for (i = 0; i < n; i++) { e = entry + i; - extended_entry_extract(tx + i, e, first, first_len); + extended_entry_extract(tx + i, e, + first, first_len, + &sparse_info); /* Cull the ones that are not the earliest */ if (!e->path) continue; diff --git a/tree-walk.h b/tree-walk.h index 7e3e0b5..eae1997 100644 --- a/tree-walk.h +++ b/tree-walk.h @@ -60,4 +60,7 @@ static inline int traverse_path_len(const struct traverse_info *info, const stru return info->pathlen + tree_entry_len(n->path, n->sha1); } +void skip_uninteresting(struct tree_desc *t, const char *base, int baselen, struct diff_options *opt, int *all_interesting); +int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt); + #endif -- 1.7.2.2.140.gd06af -- 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