git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Incorrect git-blame result if I use full path to file

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Dec 3, 2007, 17:26 UTC
Message-ID
<alpine.LFD.0.9999.0712030922250.8458@woody.linux-foundation.org>
In-Reply-To
<7vhcj0seok.fsf@gitster.siamese.dyndns.org>
On Sun, 2 Dec 2007, Junio C Hamano wrote:
Show 9 quoted lines
> "Anatol Pomozov" <anatol.pomozov@gmail.com> writes:
> >
> > I just start learning git and I found a bug (but sorry if the
> > functionality I am trying to blame as a bug not actually bug and it
> > was made by intention)
> 
> I think it is rather a sloppy error checking than a bug.  It should be
> throwing a stone back at you when you feed it a full path, or converting
> it back to work tree relative path before using.
How about this patch?

It makes "get_pathspec()" make all the paths it returns relative, if it can. HOWEVER! I think it should actually die() if it sees an absolute path that it cannot convert (because it really cannot do anything sane about it), but I commented that out for now because that requires some test case change: right now we actually have a few test cases for insane filename arguments, and they expect the old behaviour.

Comments? This changes behaviour subtly (and if we enable the "die(..)" logic, not-so-subtly), but I think that in any case where it changes behaviour, the new behaviour would be an improvement, and the old one would be nonsensical (ie you get *some* results with an absolute pathname, just not the ones you'd expect!)

Note the die() comment in the bad case in "make_relative()".
		Linus
---
 setup.c |   34 +++++++++++++++++++++++++++++++++-
 1 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/setup.c b/setup.c
index 2c7b5cb..fadf4ee 100644
--- a/setup.c
+++ b/setup.c
@@ -111,11 +111,26 @@ void verify_non_filename(const char *prefix, const char *arg)
 		die("'%s': %s", arg, strerror(errno));
 }
 
+static const char *make_relative(const char *file, const char *pwd, int pwdlen)
+{
+	if (strncmp(file, pwd, pwdlen))
+		goto bad;
+	if (file[pwdlen] != '/')
+		goto bad;
+	return file + pwdlen + 1;
+
+bad:
+	/* Should we die() here or just do a "return file"? */
+	/* die("pathname '%s' is not in the repository", file); */
+	return file;
+}
+
 const char **get_pathspec(const char *prefix, const char **pathspec)
 {
+	const char *pwd;
 	const char *entry = *pathspec;
 	const char **p;
-	int prefixlen;
+	int prefixlen, pwdlen;
 
 	if (!prefix && !entry)
 		return NULL;
@@ -127,9 +142,26 @@ const char **get_pathspec(const char *prefix, const char **pathspec)
 		return spec;
 	}
 
+	pwd = NULL;
+	pwdlen = 0;
+	p = pathspec;
+	do {
+		if (*entry == '/') {
+			if (!pwd) {
+				char buffer[PATH_MAX + 1];
+				if (!getcwd(buffer, sizeof(buffer)))
+					break;
+				pwd = buffer;
+				pwdlen = strlen(buffer);
+			}
+			*p = make_relative(entry, pwd, pwdlen);
+		}
+	} while ((entry = *++p) != NULL);
+
 	/* Otherwise we have to re-write the entries.. */
 	p = pathspec;
 	prefixlen = prefix ? strlen(prefix) : 0;
+	entry = *p;
 	do {
 		*p = prefix_path(prefix, prefixlen, entry);
 	} while ((entry = *++p) != NULL);
Previous: Jeff KingNext: Johannes Schindelin
Message 4 of 21 in “Incorrect git-blame result if I use full path to file”
  1. Anatol PomozovDec 3, 2007
  2. Junio C HamanoDec 3, 2007
  3. Jeff KingDec 3, 2007
  4. Linus TorvaldsDec 3, 2007
  5. Johannes SchindelinDec 3, 2007
  6. Linus TorvaldsDec 3, 2007
  7. Linus TorvaldsDec 3, 2007
  8. Jeff KingDec 3, 2007
  9. Junio C HamanoDec 3, 2007
  10. Jeff KingDec 3, 2007
  11. Robin RosenbergDec 3, 2007
  12. Make Git accept absolute path names for files within the work treeRobin Rosenberg, Dec 3, 2007
  13. Junio C HamanoDec 3, 2007
  14. Jeff KingDec 4, 2007
  15. Johannes SchindelinDec 4, 2007
  16. Robin RosenbergDec 4, 2007
  17. Johannes SchindelinDec 4, 2007
  18. Linus TorvaldsDec 4, 2007
  19. Jeff KingDec 4, 2007
  20. Linus TorvaldsDec 4, 2007
  21. Jeff KingDec 6, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.