Junio C Hamano [off-list ref] writes:
I suspect that the right approach might be something like the
attached patch. It introduces a version of prefix_path() that
sanitizes path (but not prefix part, which comes from git itself
and hopefully there should not be a need to sanitize it) while
doing the prefixing. It also strips the leading absolute path
to the repository by comparing it with the value of work_tree.
A few things to note.
* Your mv fix is rolled in.
* This allows you to name a in-repository file as `pwd`/file,
or `pwd`//file (iow, double-slash is also sanitized). It may
kill the bird in another thread nearby.
* get_pathspec() drops paths outside of repository, so the
caller may end up getting a smaller number of paths than it
originally gave it. If an existing caller expects the same
number of paths to come back, it needs to be adjusted (I did
not check). We could alternatively die() but I couldn't
decide which one is a better behaviour.
This is the kind of "fixing existing callers" that would be
needed if we take this approach.
builtin-ls-files.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 0f0ab2d..3801cf4 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -572,8 +572,17 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
pathspec = get_pathspec(prefix, argv + i);
/* Verify that the pathspec matches the prefix */
- if (pathspec)
+ if (pathspec) {
+ if (argc != i) {
+ int cnt;
+ for (cnt = 0; pathspec[cnt]; cnt++)
+ ;
+ if (cnt != (argc - i))
+ exit(1); /* error message already given */
+ }
prefix = verify_pathspec(prefix);
+ } else if (argc != i)
+ exit(1); /* error message already given */
/* Treat unmatching pathspec elements as errors */
if (pathspec && error_unmatch) {