Show changes to 7 files +39 −17
builtin/clean.c, builtin/ls-files.c, builtin/sparse-checkout.c, dir.c, dir.h, t/helper/test-path-walk.c, t/t1091-sparse-checkout-builtin.sh
diff --git a/builtin/clean.c b/builtin/clean.c
index 1d5e7e5366..73408da5c2 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -707,7 +707,7 @@ static int filter_by_patterns_cmd(void)
item = &ignore_list.items[i];
if (!*item->string)
continue;
- add_pattern(item->string, "", 0, pl, -(i+1));
+ add_pattern(item->string, "", 0, pl, -(i+1), 0);
}
changed = 0;
@@ -1018,7 +1018,7 @@ int cmd_clean(int argc,
pl = add_pattern_list(&dir, EXC_CMDL, "--exclude option");
for (i = 0; i < exclude_list.nr; i++)
- add_pattern(exclude_list.items[i].string, "", 0, pl, -(i+1));
+ add_pattern(exclude_list.items[i].string, "", 0, pl, -(i+1), 0);
parse_pathspec(&pathspec, 0,
PATHSPEC_PREFER_CWD,
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index b044520f9e..d1cc7e92f4 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -685,7 +685,7 @@ int cmd_ls_files(int argc,
ls_files_usage, 0);
pl = add_pattern_list(&dir, EXC_CMDL, "--exclude option");
for (i = 0; i < exclude_list.nr; i++) {
- add_pattern(exclude_list.items[i].string, "", 0, pl, --exclude_args);
+ add_pattern(exclude_list.items[i].string, "", 0, pl, --exclude_args, 0);
}
if (format && (show_stage || show_others || show_killed ||
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index 83981e2b1e..615007148e 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -455,6 +455,8 @@ static struct sparse_checkout_init_opts {
int sparse_index;
} init_opts;
+#define PATTERN_DISALLOW_PRECIOUS (1<<1)
+
static int sparse_checkout_init(int argc, const char **argv, const char *prefix,
struct repository *repo)
{
@@ -487,7 +489,8 @@ static int sparse_checkout_init(int argc, const char **argv, const char *prefix,
memset(&pl, 0, sizeof(pl));
sparse_filename = get_sparse_checkout_filename();
- res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL, 0);
+ res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL,
+ PATTERN_DISALLOW_PRECIOUS);
/* If we already have a sparse-checkout file, use it. */
if (res >= 0) {
@@ -515,8 +518,8 @@ static int sparse_checkout_init(int argc, const char **argv, const char *prefix,
free(sparse_filename);
- add_pattern("/*", empty_base, 0, &pl, 0);
- add_pattern("!/*/", empty_base, 0, &pl, 0);
+ add_pattern("/*", empty_base, 0, &pl, 0, 0);
+ add_pattern("!/*/", empty_base, 0, &pl, 0, 0);
pl.use_cone_patterns = init_opts.cone_mode;
return write_patterns_and_update(repo, &pl);
@@ -618,12 +621,12 @@ static void add_patterns_from_input(struct pattern_list *pl,
struct strbuf line = STRBUF_INIT;
while (!strbuf_getline(&line, file))
- add_pattern(line.buf, empty_base, 0, pl, 0);
+ add_pattern(line.buf, empty_base, 0, pl, 0, 0);
strbuf_release(&line);
} else {
for (i = 0; i < argc; i++)
- add_pattern(argv[i], empty_base, 0, pl, 0);
+ add_pattern(argv[i], empty_base, 0, pl, 0, 0);
}
}
}
@@ -1079,7 +1082,7 @@ static int sparse_checkout_disable(int argc, const char **argv,
pl.use_cone_patterns = 0;
cfg->apply_sparse_checkout = 1;
- add_pattern("/*", empty_base, 0, &pl, 0);
+ add_pattern("/*", empty_base, 0, &pl, 0, 0);
prepare_repo_settings(the_repository);
repo->settings.sparse_index = 0;
diff --git a/dir.c b/dir.c
index c6f1bed429..9aba1716a6 100644
--- a/dir.c
+++ b/dir.c
@@ -993,7 +993,8 @@ int hashmap_contains_parent(struct hashmap *map,
* which are negated precious-files.
*/
void add_pattern(const char *string, const char *base,
- int baselen, struct pattern_list *pl, int srcpos)
+ int baselen, struct pattern_list *pl, int srcpos,
+ int disable_precious)
{
struct path_pattern *pattern;
int patternlen;
@@ -1004,6 +1005,12 @@ void add_pattern(const char *string, const char *base,
warning(_("pattern '%s' is problematic, skipping"), string);
return;
}
+
+ if (disable_precious && (flags & PATTERN_FLAG_PRECIOUS)) {
+ warning(_("'$%s' precious-files pattern not allowed here, skipping"),
+ string);
+ return;
+ }
FLEX_ALLOC_MEM(pattern, pattern, string, patternlen);
pattern->patternlen = patternlen;
pattern->nowildcardlen = nowildcardlen;
@@ -1162,6 +1169,7 @@ static void invalidate_directory(struct untracked_cache *uc,
/* Flags for add_patterns() */
#define PATTERN_NOFOLLOW (1<<0)
+#define PATTERN_DISALLOW_PRECIOUS (1<<1)
/*
* Given a file with name "fname", read it (either from disk, or from
@@ -1244,14 +1252,15 @@ static int add_patterns(const char *fname, const char *base, int baselen,
return -1;
}
- add_patterns_from_buffer(buf, size, base, baselen, pl);
+ add_patterns_from_buffer(buf, size, base, baselen, pl,
+ flags & PATTERN_DISALLOW_PRECIOUS);
free(buf);
return 0;
}
int add_patterns_from_buffer(char *buf, size_t size,
const char *base, int baselen,
- struct pattern_list *pl)
+ struct pattern_list *pl, int disable_precious)
{
char *orig = buf;
int i, lineno = 1;
@@ -1270,7 +1279,8 @@ int add_patterns_from_buffer(char *buf, size_t size,
if (entry != buf + i && entry[0] != '#') {
buf[i - (i && buf[i-1] == '\r')] = 0;
trim_trailing_spaces(entry);
- add_pattern(entry, base, baselen, pl, lineno);
+ add_pattern(entry, base, baselen, pl, lineno,
+ disable_precious);
}
lineno++;
entry = buf + i + 1;
@@ -1307,7 +1317,7 @@ int add_patterns_from_blob_to_list(
return -1;
}
- add_patterns_from_buffer(buf, size, base, baselen, pl);
+ add_patterns_from_buffer(buf, size, base, baselen, pl, 0);
free(buf);
return 0;
}
diff --git a/dir.h b/dir.h
index 5cda2cdba7..a6977149b8 100644
--- a/dir.h
+++ b/dir.h
@@ -464,10 +464,11 @@ int add_patterns_from_blob_to_list(struct object_id *oid,
struct pattern_list *pl);
int add_patterns_from_buffer(char *buf, size_t size,
const char *base, int baselen,
- struct pattern_list *pl);
+ struct pattern_list *pl, int disable_precious);
int parse_path_pattern(const char **string, int *patternlen, enum pattern_flags *flags, int *nowildcardlen);
void add_pattern(const char *string, const char *base,
- int baselen, struct pattern_list *pl, int srcpos);
+ int baselen, struct pattern_list *pl, int srcpos,
+ int disable_precious);
void clear_pattern_list(struct pattern_list *pl);
void dir_clear(struct dir_struct *dir);
diff --git a/t/helper/test-path-walk.c b/t/helper/test-path-walk.c
index 4233badb58..fefe885ec6 100644
--- a/t/helper/test-path-walk.c
+++ b/t/helper/test-path-walk.c
@@ -124,7 +124,7 @@ int cmd__path_walk(int argc, const char **argv)
info.pl->use_cone_patterns = 1;
strbuf_fread(&in, 2048, stdin);
- add_patterns_from_buffer(in.buf, in.len, "", 0, info.pl);
+ add_patterns_from_buffer(in.buf, in.len, "", 0, info.pl, 0);
strbuf_release(&in);
}
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
index 74b1761e0c..caae112037 100755
--- a/t/t1091-sparse-checkout-builtin.sh
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -252,6 +252,14 @@ test_expect_success 'sparse-checkout disable' '
check_files repo a deep folder1 folder2
'
+test_expect_success 'skip precious-file pattern in $GIT_DIR/info/sparse-checkout' "
+ test_when_finished rm actual .git/info/sparse-checkout &&
+ test_when_finished git sparse-checkout disable &&
+ echo \"$/ciao\" > .git/info/sparse-checkout &&
+ git sparse-checkout init >actual 2>&1 &&
+ test_grep \"warning: '$/ciao' precious-files pattern not allowed here, skipping\" actual
+"
+
test_expect_success 'sparse-index enabled and disabled' '
git -C repo sparse-checkout init --cone --sparse-index &&
test_cmp_config -C repo true index.sparse &&