Merge branch 'nd/sparse-co-fix'
* nd/sparse-co-fix: sparse checkout: do not eagerly decide the fate for whole directory t1011: fix sparse-checkout initialization and add new file
This commit is contained in:
commit
2d220862d4
@ -17,19 +17,21 @@ test_expect_success 'setup' '
|
||||
cat >expected <<-\EOF &&
|
||||
100644 77f0ba1734ed79d12881f81b36ee134de6a3327b 0 init.t
|
||||
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 sub/added
|
||||
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 sub/addedtoo
|
||||
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 subsub/added
|
||||
EOF
|
||||
cat >expected.swt <<-\EOF &&
|
||||
H init.t
|
||||
H sub/added
|
||||
H sub/addedtoo
|
||||
H subsub/added
|
||||
EOF
|
||||
|
||||
test_commit init &&
|
||||
echo modified >>init.t &&
|
||||
mkdir sub subsub &&
|
||||
touch sub/added subsub/added &&
|
||||
git add init.t sub/added subsub/added &&
|
||||
touch sub/added sub/addedtoo subsub/added &&
|
||||
git add init.t sub/added sub/addedtoo subsub/added &&
|
||||
git commit -m "modified and added" &&
|
||||
git tag top &&
|
||||
git rm sub/added &&
|
||||
@ -83,6 +85,7 @@ test_expect_success 'match directories with trailing slash' '
|
||||
cat >expected.swt-noinit <<-\EOF &&
|
||||
S init.t
|
||||
H sub/added
|
||||
H sub/addedtoo
|
||||
S subsub/added
|
||||
EOF
|
||||
|
||||
@ -95,7 +98,7 @@ test_expect_success 'match directories with trailing slash' '
|
||||
'
|
||||
|
||||
test_expect_success 'match directories without trailing slash' '
|
||||
echo sub >>.git/info/sparse-checkout &&
|
||||
echo sub >.git/info/sparse-checkout &&
|
||||
git read-tree -m -u HEAD &&
|
||||
git ls-files -t >result &&
|
||||
test_cmp expected.swt-noinit result &&
|
||||
@ -103,8 +106,49 @@ test_expect_success 'match directories without trailing slash' '
|
||||
test -f sub/added
|
||||
'
|
||||
|
||||
test_expect_success 'match directories with negated patterns' '
|
||||
cat >expected.swt-negation <<\EOF &&
|
||||
S init.t
|
||||
S sub/added
|
||||
H sub/addedtoo
|
||||
S subsub/added
|
||||
EOF
|
||||
|
||||
cat >.git/info/sparse-checkout <<\EOF &&
|
||||
sub
|
||||
!sub/added
|
||||
EOF
|
||||
git read-tree -m -u HEAD &&
|
||||
git ls-files -t >result &&
|
||||
test_cmp expected.swt-negation result &&
|
||||
test ! -f init.t &&
|
||||
test ! -f sub/added &&
|
||||
test -f sub/addedtoo
|
||||
'
|
||||
|
||||
test_expect_success 'match directories with negated patterns (2)' '
|
||||
cat >expected.swt-negation2 <<\EOF &&
|
||||
H init.t
|
||||
H sub/added
|
||||
S sub/addedtoo
|
||||
H subsub/added
|
||||
EOF
|
||||
|
||||
cat >.git/info/sparse-checkout <<\EOF &&
|
||||
/*
|
||||
!sub
|
||||
sub/added
|
||||
EOF
|
||||
git read-tree -m -u HEAD &&
|
||||
git ls-files -t >result &&
|
||||
test_cmp expected.swt-negation2 result &&
|
||||
test -f init.t &&
|
||||
test -f sub/added &&
|
||||
test ! -f sub/addedtoo
|
||||
'
|
||||
|
||||
test_expect_success 'match directory pattern' '
|
||||
echo "s?b" >>.git/info/sparse-checkout &&
|
||||
echo "s?b" >.git/info/sparse-checkout &&
|
||||
git read-tree -m -u HEAD &&
|
||||
git ls-files -t >result &&
|
||||
test_cmp expected.swt-noinit result &&
|
||||
@ -116,6 +160,7 @@ test_expect_success 'checkout area changes' '
|
||||
cat >expected.swt-nosub <<-\EOF &&
|
||||
H init.t
|
||||
S sub/added
|
||||
S sub/addedtoo
|
||||
S subsub/added
|
||||
EOF
|
||||
|
||||
|
@ -814,43 +814,45 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
|
||||
return mask;
|
||||
}
|
||||
|
||||
static int clear_ce_flags_1(struct cache_entry **cache, int nr,
|
||||
char *prefix, int prefix_len,
|
||||
int select_mask, int clear_mask,
|
||||
struct exclude_list *el, int defval);
|
||||
|
||||
/* Whole directory matching */
|
||||
static int clear_ce_flags_dir(struct cache_entry **cache, int nr,
|
||||
char *prefix, int prefix_len,
|
||||
char *basename,
|
||||
int select_mask, int clear_mask,
|
||||
struct exclude_list *el)
|
||||
struct exclude_list *el, int defval)
|
||||
{
|
||||
struct cache_entry **cache_end = cache + nr;
|
||||
struct cache_entry **cache_end;
|
||||
int dtype = DT_DIR;
|
||||
int ret = excluded_from_list(prefix, prefix_len, basename, &dtype, el);
|
||||
|
||||
prefix[prefix_len++] = '/';
|
||||
|
||||
/* included, no clearing for any entries under this directory */
|
||||
if (!ret) {
|
||||
for (; cache != cache_end; cache++) {
|
||||
struct cache_entry *ce = *cache;
|
||||
/* If undecided, use matching result of parent dir in defval */
|
||||
if (ret < 0)
|
||||
ret = defval;
|
||||
|
||||
for (cache_end = cache; cache_end != cache + nr; cache_end++) {
|
||||
struct cache_entry *ce = *cache_end;
|
||||
if (strncmp(ce->name, prefix, prefix_len))
|
||||
break;
|
||||
}
|
||||
return nr - (cache_end - cache);
|
||||
}
|
||||
|
||||
/* excluded, clear all selected entries under this directory. */
|
||||
if (ret == 1) {
|
||||
for (; cache != cache_end; cache++) {
|
||||
struct cache_entry *ce = *cache;
|
||||
if (select_mask && !(ce->ce_flags & select_mask))
|
||||
continue;
|
||||
if (strncmp(ce->name, prefix, prefix_len))
|
||||
break;
|
||||
ce->ce_flags &= ~clear_mask;
|
||||
}
|
||||
return nr - (cache_end - cache);
|
||||
}
|
||||
|
||||
return 0;
|
||||
/*
|
||||
* TODO: check el, if there are no patterns that may conflict
|
||||
* with ret (iow, we know in advance the incl/excl
|
||||
* decision for the entire directory), clear flag here without
|
||||
* calling clear_ce_flags_1(). That function will call
|
||||
* the expensive excluded_from_list() on every entry.
|
||||
*/
|
||||
return clear_ce_flags_1(cache, cache_end - cache,
|
||||
prefix, prefix_len,
|
||||
select_mask, clear_mask,
|
||||
el, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -871,7 +873,7 @@ static int clear_ce_flags_dir(struct cache_entry **cache, int nr,
|
||||
static int clear_ce_flags_1(struct cache_entry **cache, int nr,
|
||||
char *prefix, int prefix_len,
|
||||
int select_mask, int clear_mask,
|
||||
struct exclude_list *el)
|
||||
struct exclude_list *el, int defval)
|
||||
{
|
||||
struct cache_entry **cache_end = cache + nr;
|
||||
|
||||
@ -882,7 +884,7 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr,
|
||||
while(cache != cache_end) {
|
||||
struct cache_entry *ce = *cache;
|
||||
const char *name, *slash;
|
||||
int len, dtype;
|
||||
int len, dtype, ret;
|
||||
|
||||
if (select_mask && !(ce->ce_flags & select_mask)) {
|
||||
cache++;
|
||||
@ -911,7 +913,7 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr,
|
||||
prefix, prefix_len + len,
|
||||
prefix + prefix_len,
|
||||
select_mask, clear_mask,
|
||||
el);
|
||||
el, defval);
|
||||
|
||||
/* clear_c_f_dir eats a whole dir already? */
|
||||
if (processed) {
|
||||
@ -922,13 +924,16 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr,
|
||||
prefix[prefix_len + len++] = '/';
|
||||
cache += clear_ce_flags_1(cache, cache_end - cache,
|
||||
prefix, prefix_len + len,
|
||||
select_mask, clear_mask, el);
|
||||
select_mask, clear_mask, el, defval);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Non-directory */
|
||||
dtype = ce_to_dtype(ce);
|
||||
if (excluded_from_list(ce->name, ce_namelen(ce), name, &dtype, el) > 0)
|
||||
ret = excluded_from_list(ce->name, ce_namelen(ce), name, &dtype, el);
|
||||
if (ret < 0)
|
||||
ret = defval;
|
||||
if (ret > 0)
|
||||
ce->ce_flags &= ~clear_mask;
|
||||
cache++;
|
||||
}
|
||||
@ -943,7 +948,7 @@ static int clear_ce_flags(struct cache_entry **cache, int nr,
|
||||
return clear_ce_flags_1(cache, nr,
|
||||
prefix, 0,
|
||||
select_mask, clear_mask,
|
||||
el);
|
||||
el, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user