From: "Elijah Newren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Victoria Dye <vdye@github.com>, Derrick Stolee <stolee@gmail.com>,
Lessley Dennington <lessleydennington@gmail.com>,
Derrick Stolee <derrickstolee@github.com>,
Elijah Newren <newren@gmail.com>,
Elijah Newren <newren@gmail.com>,
Elijah Newren <newren@gmail.com>
Subject: [PATCH v3 4/5] sparse-checkout: error or warn when given individual files
Date: Wed, 16 Feb 2022 04:21:22 +0000 [thread overview]
Message-ID: <1fdebc1953fcc30a6a08b3efd62dcdb31f7e4704.1644985283.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1118.v3.git.1644985283.gitgitgadget@gmail.com>
From: Elijah Newren <newren@gmail.com>
The set and add subcommands accept multiple positional arguments.
The meaning of these arguments differs slightly in the two modes:
Cone mode only accepts directories. If given a file, it would
previously treat it as a directory, causing not just the file itself to
be included but all sibling files as well -- likely against users'
expectations. Throw an error if the specified path is a file in the
index. Provide a --skip-checks argument to allow users to override
(e.g. for the case when the given path IS a directory on another
branch).
Non-cone mode accepts general gitignore patterns. There are many
reasons to avoid this mode, but one possible reason to use it instead of
cone mode: to be able to select individual files within a directory.
However, if a file is passed to set/add in non-cone mode, you won't be
selecting a single file, you'll be selecting a file with the same name
in any directory. Thus users will likely want to prefix any paths they
specify with a leading '/' character; warn users if the patterns they
specify exactly name a file because it means they are likely missing
such a missing leading slash.
Reviewed-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
---
builtin/sparse-checkout.c | 43 +++++++++++++++++++++++++-----
t/t1091-sparse-checkout-builtin.sh | 16 ++++++++++-
2 files changed, 52 insertions(+), 7 deletions(-)
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index a2192a69219..64583fa704f 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -1,4 +1,5 @@
#include "builtin.h"
+#include "cache.h"
#include "config.h"
#include "dir.h"
#include "parse-options.h"
@@ -684,8 +685,11 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin,
return result;
}
-static void sanitize_paths(int argc, const char **argv, const char *prefix)
+static void sanitize_paths(int argc, const char **argv,
+ const char *prefix, int skip_checks)
{
+ int i;
+
if (!argc)
return;
@@ -694,7 +698,6 @@ static void sanitize_paths(int argc, const char **argv, const char *prefix)
* The args are not pathspecs, so unfortunately we
* cannot imitate how cmd_add() uses parse_pathspec().
*/
- int i;
int prefix_len = strlen(prefix);
if (!core_sparse_checkout_cone)
@@ -703,20 +706,44 @@ static void sanitize_paths(int argc, const char **argv, const char *prefix)
for (i = 0; i < argc; i++)
argv[i] = prefix_path(prefix, prefix_len, argv[i]);
}
+
+ if (skip_checks)
+ return;
+
+ for (i = 0; i < argc; i++) {
+ struct cache_entry *ce;
+ struct index_state *index = the_repository->index;
+ int pos = index_name_pos(index, argv[i], strlen(argv[i]));
+
+ if (pos < 0)
+ continue;
+ ce = index->cache[pos];
+ if (S_ISSPARSEDIR(ce->ce_mode))
+ continue;
+
+ if (core_sparse_checkout_cone)
+ die(_("\"%s\" is not a directory; to treat it as a directory anyway, rerun with --skip-checks"), argv[i]);
+ else
+ warning(_("pass a leading slash before paths such as \"%s\" if you want a single file (see NON-CONE PROBLEMS in the git-sparse-checkout manual)."), argv[i]);
+ }
}
static char const * const builtin_sparse_checkout_add_usage[] = {
- N_("git sparse-checkout add (--stdin | <patterns>)"),
+ N_("git sparse-checkout add [--skip-checks] (--stdin | <patterns>)"),
NULL
};
static struct sparse_checkout_add_opts {
+ int skip_checks;
int use_stdin;
} add_opts;
static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
{
static struct option builtin_sparse_checkout_add_options[] = {
+ OPT_BOOL_F(0, "skip-checks", &add_opts.skip_checks,
+ N_("skip some sanity checks on the given paths that might give false positives"),
+ PARSE_OPT_NONEG),
OPT_BOOL(0, "stdin", &add_opts.use_stdin,
N_("read patterns from standard in")),
OPT_END(),
@@ -732,19 +759,20 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
builtin_sparse_checkout_add_usage,
PARSE_OPT_KEEP_UNKNOWN);
- sanitize_paths(argc, argv, prefix);
+ sanitize_paths(argc, argv, prefix, add_opts.skip_checks);
return modify_pattern_list(argc, argv, add_opts.use_stdin, ADD);
}
static char const * const builtin_sparse_checkout_set_usage[] = {
- N_("git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] (--stdin | <patterns>)"),
+ N_("git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] [--skip-checks] (--stdin | <patterns>)"),
NULL
};
static struct sparse_checkout_set_opts {
int cone_mode;
int sparse_index;
+ int skip_checks;
int use_stdin;
} set_opts;
@@ -758,6 +786,9 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
N_("initialize the sparse-checkout in cone mode")),
OPT_BOOL(0, "sparse-index", &set_opts.sparse_index,
N_("toggle the use of a sparse index")),
+ OPT_BOOL_F(0, "skip-checks", &set_opts.skip_checks,
+ N_("skip some sanity checks on the given paths that might give false positives"),
+ PARSE_OPT_NONEG),
OPT_BOOL_F(0, "stdin", &set_opts.use_stdin,
N_("read patterns from standard in"),
PARSE_OPT_NONEG),
@@ -786,7 +817,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
argv = default_patterns;
argc = default_patterns_nr;
} else {
- sanitize_paths(argc, argv, prefix);
+ sanitize_paths(argc, argv, prefix, set_opts.skip_checks);
}
return modify_pattern_list(argc, argv, set_opts.use_stdin, REPLACE);
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
index c1f86b0e02e..3b39329266b 100755
--- a/t/t1091-sparse-checkout-builtin.sh
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -562,7 +562,7 @@ test_expect_success 'different sparse-checkouts with worktrees' '
'
test_expect_success 'set using filename keeps file on-disk' '
- git -C repo sparse-checkout set a deep &&
+ git -C repo sparse-checkout set --skip-checks a deep &&
cat >expect <<-\EOF &&
/*
!/*/
@@ -839,4 +839,18 @@ test_expect_success 'set from subdir in non-cone mode throws an error' '
grep "run from the toplevel directory in non-cone mode" error
'
+test_expect_success 'by default, cone mode will error out when passed files' '
+ git -C repo sparse-checkout reapply --cone &&
+ test_must_fail git -C repo sparse-checkout add .gitignore 2>error &&
+
+ grep ".gitignore.*is not a directory" error
+'
+
+test_expect_success 'by default, non-cone mode will warn on individual files' '
+ git -C repo sparse-checkout reapply --no-cone &&
+ git -C repo sparse-checkout add .gitignore 2>warning &&
+
+ grep "pass a leading slash before paths.*if you want a single file" warning
+'
+
test_done
--
gitgitgadget
next prev parent reply other threads:[~2022-02-16 4:21 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-13 0:39 [PATCH 0/7] RFC: sparse checkout: make --cone mode the default, and check add/set argument validity Elijah Newren via GitGitGadget
2022-02-13 0:39 ` [PATCH 1/7] sparse-checkout: correct reapply's handling of options Elijah Newren via GitGitGadget
2022-02-13 0:39 ` [PATCH 2/7] sparse-checkout: correctly set non-cone mode when expected Elijah Newren via GitGitGadget
2022-02-14 15:44 ` Derrick Stolee
2022-02-15 3:18 ` Elijah Newren
2022-02-13 0:39 ` [PATCH 3/7] sparse-checkout: pay attention to prefix for {set, add} Elijah Newren via GitGitGadget
2022-02-14 15:49 ` Derrick Stolee
2022-02-15 3:52 ` Elijah Newren
2022-02-15 14:53 ` Derrick Stolee
2022-02-13 0:39 ` [PATCH 4/7] sparse-checkout: error or warn when given individual files Elijah Newren via GitGitGadget
2022-02-14 15:56 ` Derrick Stolee
2022-02-15 4:17 ` Elijah Newren
2022-02-15 15:03 ` Derrick Stolee
2022-02-13 0:39 ` [PATCH 5/7] sparse-checkout: reject non-cone-mode patterns starting with a '#' Elijah Newren via GitGitGadget
2022-02-14 17:59 ` Junio C Hamano
2022-02-15 4:31 ` Elijah Newren
2022-02-16 1:07 ` Junio C Hamano
2022-02-16 2:23 ` Elijah Newren
2022-02-16 3:05 ` Junio C Hamano
2022-02-13 0:39 ` [PATCH 6/7] sparse-checkout: reject arguments in cone-mode that look like patterns Elijah Newren via GitGitGadget
2022-02-13 0:39 ` [PATCH 7/7] sparse-checkout: make --cone the default and deprecate --no-cone Elijah Newren via GitGitGadget
2022-02-14 16:14 ` Derrick Stolee
2022-02-15 5:01 ` Elijah Newren
2022-02-14 16:19 ` [PATCH 0/7] RFC: sparse checkout: make --cone mode the default, and check add/set argument validity Derrick Stolee
2022-02-15 5:12 ` Elijah Newren
2022-02-15 15:12 ` Derrick Stolee
2022-02-15 8:32 ` [PATCH v2 0/6] sparse checkout: fix a few bugs and check argument validity for set/add Elijah Newren via GitGitGadget
2022-02-15 8:32 ` [PATCH v2 1/6] sparse-checkout: correct reapply's handling of options Elijah Newren via GitGitGadget
2022-02-15 8:32 ` [PATCH v2 2/6] sparse-checkout: correctly set non-cone mode when expected Elijah Newren via GitGitGadget
2022-02-15 8:32 ` [PATCH v2 3/6] sparse-checkout: pay attention to prefix for {set, add} Elijah Newren via GitGitGadget
2022-02-17 9:04 ` Ævar Arnfjörð Bjarmason
2022-02-18 6:04 ` Elijah Newren
2022-02-15 8:32 ` [PATCH v2 4/6] sparse-checkout: error or warn when given individual files Elijah Newren via GitGitGadget
2022-02-17 9:05 ` Ævar Arnfjörð Bjarmason
2022-02-15 8:32 ` [PATCH v2 5/6] sparse-checkout: reject non-cone-mode patterns starting with a '#' Elijah Newren via GitGitGadget
2022-02-15 8:32 ` [PATCH v2 6/6] sparse-checkout: reject arguments in cone-mode that look like patterns Elijah Newren via GitGitGadget
2022-02-15 15:15 ` [PATCH v2 0/6] sparse checkout: fix a few bugs and check argument validity for set/add Derrick Stolee
2022-02-16 4:21 ` [PATCH v3 0/5] " Elijah Newren via GitGitGadget
2022-02-16 4:21 ` [PATCH v3 1/5] sparse-checkout: correct reapply's handling of options Elijah Newren via GitGitGadget
2022-02-16 4:21 ` [PATCH v3 2/5] sparse-checkout: correctly set non-cone mode when expected Elijah Newren via GitGitGadget
2022-02-16 4:21 ` [PATCH v3 3/5] sparse-checkout: pay attention to prefix for {set, add} Elijah Newren via GitGitGadget
2022-02-16 4:21 ` Elijah Newren via GitGitGadget [this message]
2022-02-16 4:21 ` [PATCH v3 5/5] sparse-checkout: reject arguments in cone-mode that look like patterns Elijah Newren via GitGitGadget
2022-02-16 9:53 ` Ævar Arnfjörð Bjarmason
2022-02-16 16:54 ` Elijah Newren
2022-02-16 17:20 ` Victoria Dye
2022-02-16 18:49 ` Junio C Hamano
2022-02-17 1:46 ` Elijah Newren
2022-02-17 17:34 ` Junio C Hamano
2022-02-17 1:43 ` Elijah Newren
2022-02-17 2:26 ` Elijah Newren
2022-02-16 7:19 ` [PATCH v3 0/5] sparse checkout: fix a few bugs and check argument validity for set/add Junio C Hamano
2022-02-17 6:54 ` [PATCH v4 " Elijah Newren via GitGitGadget
2022-02-17 6:54 ` [PATCH v4 1/5] sparse-checkout: correct reapply's handling of options Elijah Newren via GitGitGadget
2022-02-17 6:54 ` [PATCH v4 2/5] sparse-checkout: correctly set non-cone mode when expected Elijah Newren via GitGitGadget
2022-02-17 6:54 ` [PATCH v4 3/5] sparse-checkout: pay attention to prefix for {set, add} Elijah Newren via GitGitGadget
2022-02-17 17:53 ` Junio C Hamano
2022-02-17 6:54 ` [PATCH v4 4/5] sparse-checkout: error or warn when given individual files Elijah Newren via GitGitGadget
2022-02-17 18:07 ` Junio C Hamano
2022-02-18 6:11 ` Elijah Newren
2022-02-17 6:54 ` [PATCH v4 5/5] sparse-checkout: reject arguments in cone-mode that look like patterns Elijah Newren via GitGitGadget
2022-02-17 9:13 ` [PATCH v4 0/5] sparse checkout: fix a few bugs and check argument validity for set/add Ævar Arnfjörð Bjarmason
2022-02-19 16:44 ` [PATCH v5 " Elijah Newren via GitGitGadget
2022-02-19 16:44 ` [PATCH v5 1/5] sparse-checkout: correct reapply's handling of options Elijah Newren via GitGitGadget
2022-02-19 16:44 ` [PATCH v5 2/5] sparse-checkout: correctly set non-cone mode when expected Elijah Newren via GitGitGadget
2022-02-19 16:44 ` [PATCH v5 3/5] sparse-checkout: pay attention to prefix for {set, add} Elijah Newren via GitGitGadget
2022-02-19 16:44 ` [PATCH v5 4/5] sparse-checkout: error or warn when given individual files Elijah Newren via GitGitGadget
2022-02-19 16:44 ` [PATCH v5 5/5] sparse-checkout: reject arguments in cone-mode that look like patterns Elijah Newren via GitGitGadget
2022-02-20 19:44 ` [PATCH v5 0/5] sparse checkout: fix a few bugs and check argument validity for set/add Derrick Stolee
2022-02-20 20:13 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1fdebc1953fcc30a6a08b3efd62dcdb31f7e4704.1644985283.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=derrickstolee@github.com \
--cc=git@vger.kernel.org \
--cc=lessleydennington@gmail.com \
--cc=newren@gmail.com \
--cc=stolee@gmail.com \
--cc=vdye@github.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.