From: Linus Torvalds <torvalds@osdl.org>
To: Junio C Hamano <junkio@cox.net>, Matthias Lederhofer <matled@gmx.net>
Cc: Git Mailing List <git@vger.kernel.org>,
Paul Mackerras <paulus@samba.org>
Subject: [PATCH] Fix filename verification when in a subdirectory
Date: Wed, 26 Apr 2006 10:15:54 -0700 (PDT) [thread overview]
Message-ID: <Pine.LNX.4.64.0604261010390.3701@g5.osdl.org> (raw)
In-Reply-To: <Pine.LNX.4.64.0604260832240.3701@g5.osdl.org>
When we are in a subdirectory of a git archive, we need to take the prefix
of that subdirectory into accoung when we verify filename arguments.
Noted by Matthias Lederhofer
This also uses the improved error reporting for all the other git commands
that use the revision parsing interfaces, not just git-rev-parse. Also, it
makes the error reporting for mixed filenames and argument flags clearer
(you cannot put flags after the start of the pathname list).
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
On Wed, 26 Apr 2006, Linus Torvalds wrote:
> >
> > Shouldn't git rev-parse try to stat the file (additionally?) in the
> > current directory instead of the top git directory? git (diff|log|..)
> > seem to fail everytime in a subdirectory without --.
>
> Good point. However, the reason for that is that it actually _does_ stat
> the file in the current directory, but it has done the
>
> revs->prefix = setup_git_directory();
>
> in the init path (and it does need to do that, since that's what figures
> out where the .git directory is, so that we can parse the revisions
> correctly).
>
> And that "setup_git_directory()" will chdir() to the root of the project.
diff --git a/cache.h b/cache.h
index 69801b0..4d8fabc 100644
--- a/cache.h
+++ b/cache.h
@@ -134,6 +134,7 @@ extern const char *setup_git_directory_g
extern const char *setup_git_directory(void);
extern const char *prefix_path(const char *prefix, int len, const char *path);
extern const char *prefix_filename(const char *prefix, int len, const char *path);
+extern void verify_filename(const char *prefix, const char *name);
#define alloc_nr(x) (((x)+16)*3/2)
diff --git a/rev-parse.c b/rev-parse.c
index 7f66ae2..62e16af 100644
--- a/rev-parse.c
+++ b/rev-parse.c
@@ -160,14 +160,6 @@ static int show_file(const char *arg)
return 0;
}
-static void die_badfile(const char *arg)
-{
- if (errno != ENOENT)
- die("'%s': %s", arg, strerror(errno));
- die("'%s' is ambiguous - revision name or file/directory name?\n"
- "Please put '--' before the list of filenames.", arg);
-}
-
int main(int argc, char **argv)
{
int i, as_is = 0, verify = 0;
@@ -177,14 +169,12 @@ int main(int argc, char **argv)
git_config(git_default_config);
for (i = 1; i < argc; i++) {
- struct stat st;
char *arg = argv[i];
char *dotdot;
if (as_is) {
if (show_file(arg) && as_is < 2)
- if (lstat(arg, &st) < 0)
- die_badfile(arg);
+ verify_filename(prefix, arg);
continue;
}
if (!strcmp(arg,"-n")) {
@@ -350,8 +340,7 @@ int main(int argc, char **argv)
continue;
if (verify)
die("Needed a single revision");
- if (lstat(arg, &st) < 0)
- die_badfile(arg);
+ verify_filename(prefix, arg);
}
show_default();
if (verify && revs_count != 1)
diff --git a/revision.c b/revision.c
index f9c7d15..f2a9f25 100644
--- a/revision.c
+++ b/revision.c
@@ -752,17 +752,15 @@ int setup_revisions(int argc, const char
arg++;
}
if (get_sha1(arg, sha1) < 0) {
- struct stat st;
int j;
if (seen_dashdash || local_flags)
die("bad revision '%s'", arg);
/* If we didn't have a "--", all filenames must exist */
- for (j = i; j < argc; j++) {
- if (lstat(argv[j], &st) < 0)
- die("'%s': %s", argv[j], strerror(errno));
- }
+ for (j = i; j < argc; j++)
+ verify_filename(revs->prefix, argv[j]);
+
revs->prune_data = get_pathspec(revs->prefix, argv + i);
break;
}
diff --git a/setup.c b/setup.c
index 36ede3d..119ef7d 100644
--- a/setup.c
+++ b/setup.c
@@ -62,6 +62,29 @@ const char *prefix_filename(const char *
return path;
}
+/*
+ * Verify a filename that we got as an argument for a pathspec
+ * entry. Note that a filename that begins with "-" never verifies
+ * as true, because even if such a filename were to exist, we want
+ * it to be preceded by the "--" marker (or we want the user to
+ * use a format like "./-filename")
+ */
+void verify_filename(const char *prefix, const char *arg)
+{
+ const char *name;
+ struct stat st;
+
+ if (*arg == '-')
+ die("bad flag '%s' used after filename", arg);
+ name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
+ if (!lstat(name, &st))
+ return;
+ if (errno == ENOENT);
+ die("ambiguous argument '%s': unknown revision or filename\n"
+ "Use '--' to separate filenames from revisions", arg);
+ die("'%s': %s", arg, strerror(errno));
+}
+
const char **get_pathspec(const char *prefix, const char **pathspec)
{
const char *entry = *pathspec;
next prev parent reply other threads:[~2006-04-26 17:16 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-23 12:03 lstat() call in rev-parse.c Paul Mackerras
2006-04-23 16:19 ` Linus Torvalds
2006-04-24 23:23 ` Paul Mackerras
2006-04-26 15:28 ` Matthias Lederhofer
2006-04-26 15:43 ` Linus Torvalds
2006-04-26 17:15 ` Linus Torvalds [this message]
2006-04-26 18:05 ` [PATCH] Fix filename verification when in a subdirectory Timo Hirvonen
2006-04-26 18:14 ` Linus Torvalds
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=Pine.LNX.4.64.0604261010390.3701@g5.osdl.org \
--to=torvalds@osdl.org \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
--cc=matled@gmx.net \
--cc=paulus@samba.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).