All of lore.kernel.org
 help / color / mirror / Atom feed
* lstat() call in rev-parse.c
@ 2006-04-23 12:03 Paul Mackerras
  2006-04-23 16:19 ` Linus Torvalds
  0 siblings, 1 reply; 8+ messages in thread
From: Paul Mackerras @ 2006-04-23 12:03 UTC (permalink / raw)
  To: git

Why does git-rev-parse do an lstat on some of its arguments, at line
345 of rev-parse.c, and die if the lstat fails?  It doesn't seem to do
anything with the result.

The effect is that if you do "gitk a b", it works as long as a and b
exist (as files or directories), but fails if they don't, and some
users have found this confusing.  Yes they should put in a --, but
it's not obvious to users why this should make it work in the case
when a or b doesn't exist.

(And yes I just took out the git-rev-parse call from gitk, but I'm
going to need to do git-rev-parse --no-refs --no-flags for some
changes I'm doing at the moment.)

Paul.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: lstat() call in rev-parse.c
  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
  0 siblings, 2 replies; 8+ messages in thread
From: Linus Torvalds @ 2006-04-23 16:19 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: git



On Sun, 23 Apr 2006, Paul Mackerras wrote:
>
> Why does git-rev-parse do an lstat on some of its arguments, at line
> 345 of rev-parse.c, and die if the lstat fails?  It doesn't seem to do
> anything with the result.
> 
> The effect is that if you do "gitk a b", it works as long as a and b
> exist (as files or directories), but fails if they don't, and some
> users have found this confusing.

Because it's even _more_ common to do

	gitk v2.6.16

(in the git directory) and be very confused when that returns an empty 
history. 

So the rule is: if you don't give that "--", then we have to be able to 
confirm that the filenames are really files. Not a misspelled revision 
name, or a revision name that was correctly spelled, but for the wrong 
project, because you were in the wrong subdirectory ;)

And yes, this actually happened to me. I was demonstrating git before we 
did that fix, and I used the wrong tag-name, and gitk would think for a 
minute and them show "No commits selected" with no error, because 
"v2.6.16" didn't exist at that time, and it used the "tag-name" as a 
filename, and that filename didn't actually exist, so the number of 
commits that changed it was exactly zero.

So now, if you do "gitk v2.6.16" in the git directory, it will return a 
nice and understandable 

	Error reading commits: fatal: 'v2.6.16': No such file or directory

which is _exactly_ what you want. The only problem is that gitk will 
actually open the big window too, and the error window is small and can be 
non-obvious if the window manager hides it in some corner. So I actually 
think you should try to make the error window come up smack dab in front 
of the main gitk window and make the error clearer.

So the rules are simple:
 - the filenames are _always_ separated by "--"
 - we have a short-hand, which allows the "--" to be dropped iff it is 
   unambiguous

Where "unambiguous" means that
 - the revision name cannot possible be interpreted as a filename (we 
   don't check this part yet, but I think we should)
 - all filenames are obviously not revision names, since they not 
   only aren't valid revisions, they actually exist as files.

Otherwise, misspellings, typos, and thinkos result in total confusion.

		Linus

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: lstat() call in rev-parse.c
  2006-04-23 16:19 ` Linus Torvalds
@ 2006-04-24 23:23   ` Paul Mackerras
  2006-04-26 15:28   ` Matthias Lederhofer
  1 sibling, 0 replies; 8+ messages in thread
From: Paul Mackerras @ 2006-04-24 23:23 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git

Linus Torvalds writes:

> So the rule is: if you don't give that "--", then we have to be able to 
> confirm that the filenames are really files. Not a misspelled revision 
> name, or a revision name that was correctly spelled, but for the wrong 
> project, because you were in the wrong subdirectory ;)

OK, fair enough.  In that case we need a better error message, so I
don't get people complaining that gitk can't show the history of files
that don't exist any more.  How about something like:

Argument "foo" is ambiguous - revision name or file/directory name?
Please put "--" before the list of filenames.

I'll hack up a patch to this effect.

Paul.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: lstat() call in rev-parse.c
  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
  1 sibling, 1 reply; 8+ messages in thread
From: Matthias Lederhofer @ 2006-04-26 15:28 UTC (permalink / raw)
  To: git

> So the rule is: if you don't give that "--", then we have to be able to 
> confirm that the filenames are really files. Not a misspelled revision 
> name, or a revision name that was correctly spelled, but for the wrong 
> project, because you were in the wrong subdirectory ;)

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 --.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: lstat() call in rev-parse.c
  2006-04-26 15:28   ` Matthias Lederhofer
@ 2006-04-26 15:43     ` Linus Torvalds
  2006-04-26 17:15       ` [PATCH] Fix filename verification when in a subdirectory Linus Torvalds
  0 siblings, 1 reply; 8+ messages in thread
From: Linus Torvalds @ 2006-04-26 15:43 UTC (permalink / raw)
  To: Matthias Lederhofer; +Cc: git



On Wed, 26 Apr 2006, Matthias Lederhofer wrote:

> > So the rule is: if you don't give that "--", then we have to be able 
> > to confirm that the filenames are really files. Not a misspelled 
> > revision name, or a revision name that was correctly spelled, but for 
> > the wrong project, because you were in the wrong subdirectory ;)
> 
> 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.

So the "lstat()" should probably take "revs->prefix" into account, the 
way get_pathspec() does. Ie we should probably use

	char *name = argv[i];
	if (rev->prefix)
		name = prefix_filename(rev->prefix, strlen(rev->prefix), name);
	if (lstat(name, ..) < 0)
		die(...)

instead of just a plain lstat().

Probably worth doing as a small helper funtion of its own (and get rid of 
the current "die_badfile()" - and do all of that inside the helper 
function).

Somebody?

		Linus

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] Fix filename verification when in a subdirectory
  2006-04-26 15:43     ` Linus Torvalds
@ 2006-04-26 17:15       ` Linus Torvalds
  2006-04-26 18:05         ` Timo Hirvonen
  0 siblings, 1 reply; 8+ messages in thread
From: Linus Torvalds @ 2006-04-26 17:15 UTC (permalink / raw)
  To: Junio C Hamano, Matthias Lederhofer; +Cc: Git Mailing List, Paul Mackerras


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;

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] Fix filename verification when in a subdirectory
  2006-04-26 17:15       ` [PATCH] Fix filename verification when in a subdirectory Linus Torvalds
@ 2006-04-26 18:05         ` Timo Hirvonen
  2006-04-26 18:14           ` Linus Torvalds
  0 siblings, 1 reply; 8+ messages in thread
From: Timo Hirvonen @ 2006-04-26 18:05 UTC (permalink / raw)
  To: torvalds; +Cc: junkio, matled, git, paulus

Linus Torvalds <torvalds@osdl.org> wrote:

> +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);

Extra semicolon.

-- 
http://onion.dynserv.net/~timo/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Fix filename verification when in a subdirectory
  2006-04-26 18:05         ` Timo Hirvonen
@ 2006-04-26 18:14           ` Linus Torvalds
  0 siblings, 0 replies; 8+ messages in thread
From: Linus Torvalds @ 2006-04-26 18:14 UTC (permalink / raw)
  To: Timo Hirvonen; +Cc: junkio, matled, git, paulus



On Wed, 26 Apr 2006, Timo Hirvonen wrote:
> 
> Extra semicolon.

Duh, indeed. It just didn't show up in any of the normal cases.

Junio, just apply without that stupid semicolon..

		Linus

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-04-26 18:14 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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       ` [PATCH] Fix filename verification when in a subdirectory Linus Torvalds
2006-04-26 18:05         ` Timo Hirvonen
2006-04-26 18:14           ` Linus Torvalds

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.