excluded_from_list() is designed to be work with a directory structure, where there are files and directories. Index however is a list of files, no directories, not really fit in excluded_from_list() design. Commit c84de70 (excluded_1(): support exclude files in index - 2009-08-20) helped make it work somewhat. Although the lack of proper dtype means pattern "blah" won't match entries "blah/..." in the index. clear_ce_flags() is now used to match the index against sparse patterns. It does generate directories for excluded_from_list() so the "blah" case should now work. Also revert c84de70 because it is no longer needed. Signed-off-by: Nguyán ThÃi Ngác Duy <pclouds@xxxxxxxxx> --- Documentation/git-read-tree.txt | 7 ------- dir.c | 6 ------ t/t1011-read-tree-sparse-checkout.sh | 14 +++++++++++--- unpack-trees.c | 33 ++++++++++++++++++--------------- 4 files changed, 29 insertions(+), 31 deletions(-) diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index e88e9c2..634423a 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -416,13 +416,6 @@ turn `core.sparseCheckout` on in order to have sparse checkout support. -BUGS ----- -In order to match a directory with $GIT_DIR/info/sparse-checkout, -trailing slash must be used. The form without trailing slash, while -works with .gitignore, does not work with sparse checkout. - - SEE ALSO -------- linkgit:git-write-tree[1]; linkgit:git-ls-files[1]; diff --git a/dir.c b/dir.c index d1e5e5e..2b38f94 100644 --- a/dir.c +++ b/dir.c @@ -359,12 +359,6 @@ int excluded_from_list(const char *pathname, int to_exclude = x->to_exclude; if (x->flags & EXC_FLAG_MUSTBEDIR) { - if (!dtype) { - if (!prefixcmp(pathname, exclude)) - return to_exclude; - else - continue; - } if (*dtype == DT_UNKNOWN) *dtype = get_dtype(NULL, pathname, pathlen); if (*dtype != DT_DIR) diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh index 9a07de1..50f7dfe 100755 --- a/t/t1011-read-tree-sparse-checkout.sh +++ b/t/t1011-read-tree-sparse-checkout.sh @@ -91,12 +91,20 @@ test_expect_success 'match directories with trailing slash' ' test -f sub/added ' -test_expect_failure 'match directories without trailing slash' ' - echo init.t >.git/info/sparse-checkout && +test_expect_success 'match directories without trailing slash' ' echo sub >>.git/info/sparse-checkout && git read-tree -m -u HEAD && git ls-files -t >result && - test_cmp expected.swt result && + test_cmp expected.swt-noinit result && + test ! -f init.t && + test -f sub/added +' + +test_expect_success 'match directory pattern' ' + echo "s?b" >>.git/info/sparse-checkout && + git read-tree -m -u HEAD && + git ls-files -t >result && + test_cmp expected.swt-noinit result && test ! -f init.t && test -f sub/added ' diff --git a/unpack-trees.c b/unpack-trees.c index 6c266ef..f005454 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -245,15 +245,6 @@ static int check_updates(struct unpack_trees_options *o) static int verify_uptodate_sparse(struct cache_entry *ce, struct unpack_trees_options *o); static int verify_absent_sparse(struct cache_entry *ce, enum unpack_trees_error_types, struct unpack_trees_options *o); -static int will_have_skip_worktree(const struct cache_entry *ce, struct unpack_trees_options *o) -{ - const char *basename; - - basename = strrchr(ce->name, '/'); - basename = basename ? basename+1 : ce->name; - return excluded_from_list(ce->name, ce_namelen(ce), basename, NULL, o->el) <= 0; -} - static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_options *o) { int was_skip_worktree = ce_skip_worktree(ce); @@ -926,14 +917,19 @@ static void set_new_skip_worktree_1(struct unpack_trees_options *o) { int i; + /* Mark everything out (except staged entries) */ for (i = 0;i < o->src_index->cache_nr;i++) { struct cache_entry *ce = o->src_index->cache[i]; ce->ce_flags &= ~CE_ADDED; - if (!ce_stage(ce) && will_have_skip_worktree(ce, o)) + if (!ce_stage(ce)) ce->ce_flags |= CE_NEW_SKIP_WORKTREE; else ce->ce_flags &= ~CE_NEW_SKIP_WORKTREE; } + + /* Then mark some of them in again according to o->el */ + clear_ce_flags(o->src_index->cache, o->src_index->cache_nr, + 0, CE_NEW_SKIP_WORKTREE, o); } static int verify_absent(struct cache_entry *, enum unpack_trees_error_types, struct unpack_trees_options *); @@ -943,19 +939,26 @@ static int set_new_skip_worktree_2(struct unpack_trees_options *o) /* * CE_ADDED marks new index entries. These have not been processed - * by set_new_skip_worktree_1() so we do it here. + * by set_new_skip_worktree_1() so we do it here. Mark every new + * entries out. */ for (i = 0;i < o->result.cache_nr;i++) { struct cache_entry *ce = o->result.cache[i]; + if (ce->ce_flags & CE_ADDED) + ce->ce_flags |= CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE; + } + + /* Then mark some of them in again */ + clear_ce_flags(o->result.cache, o->result.cache_nr, CE_ADDED, + CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE, o); + + for (i = 0;i < o->result.cache_nr;i++) { + struct cache_entry *ce = o->result.cache[i]; if (!(ce->ce_flags & CE_ADDED)) continue; ce->ce_flags &= ~CE_ADDED; - if (!ce_stage(ce) && will_have_skip_worktree(ce, o)) - ce->ce_flags |= CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE; - else - ce->ce_flags &= ~(CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE); /* Left-over checks from merged_entry when old == NULL */ if (verify_absent(ce, ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o)) -- 1.7.3.2.210.g045198 -- 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