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

Re: [PATCH] Handle double slashes in make_relative_path()

From
Junio C Hamano <gitster@pobox.com>
Date
Jan 22, 2010, 03:05 UTC
Message-ID
<7vmy06et5c.fsf@alter.siamese.dyndns.org>
In-Reply-To
<7vpr52gbmu.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> I would actually have expected to see something like this, but I haven't
> even compile tested it, so... 

Ok, here is a compile and "make test" tested one, together with your addition to the test script.

I am still curious how you managed to end up with a wrong function name in the context header, though. The patch below has "set_shared_perm" because that is the header we find before the context of the hunk, so it is sort of understandable; we might want to squelch the hunk header string when the first context line of the hunk already matches the funcname pattern, though.

-- >8 --
Subject: ignore duplicated slashes in make_relative_path()

The function takes two paths, an early part of abs is supposed to match base; otherwise abs is not a path under base and the function returns the full path of abs. The caller can easily confuse the implementation by giving duplicated and needless slashes in these path arguments.

Credit for test script, motivation and initial patch goes to Thomas Rast, but the bugs in the implementation of this patch are mine..

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 path.c              |   32 +++++++++++++++++++++++---------
 t/t1501-worktree.sh |    6 ++++++
 2 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/path.c b/path.c
index 2ec950b..5906fa3 100644
--- a/path.c
+++ b/path.c
@@ -394,17 +394,31 @@ int set_shared_perm(const char *path, int mode)
 const char *make_relative_path(const char *abs, const char *base)
 {
 	static char buf[PATH_MAX + 1];
-	int baselen;
+	int i = 0, j = 0;
+
 	if (!base)
 		return abs;
-	baselen = strlen(base);
-	if (prefixcmp(abs, base))
-		return abs;
-	if (abs[baselen] == '/')
-		baselen++;
-	else if (base[baselen - 1] != '/')
-		return abs;
-	strcpy(buf, abs + baselen);
+	while (base[i]) {
+		if (base[i] == '/') {
+			if (abs[j] != '/')
+				return abs;
+			while (base[i] == '/')
+				i++;
+			while (abs[j] == '/')
+				j++;
+			continue;
+		} else if (abs[j] != base[i]) {
+			return abs;
+		}
+		i++;
+		j++;
+	}
+	while (abs[j] == '/')
+		j++;
+	if (!abs[j])
+		strcpy(buf, ".");
+	else
+		strcpy(buf, abs + j);
 	return buf;
 }
 
diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh
index 74e6443..9df3012 100755
--- a/t/t1501-worktree.sh
+++ b/t/t1501-worktree.sh
@@ -189,4 +189,10 @@ test_expect_success 'absolute pathspec should fail gracefully' '
 	)
 '
 
+test_expect_success 'make_relative_path handles double slashes in GIT_DIR' '
+	: > dummy_file
+	echo git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file &&
+	git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file
+'
+
 test_done
Previous: Junio C HamanoNext: Johannes Sixt
Message 3 of 20 in “Handle double slashes in make_relative_path()”
  1. Handle double slashes in make_relative_path()Thomas Rast, Jan 22, 2010
  2. Junio C HamanoJan 22, 2010
  3. Junio C HamanoJan 22, 2010
  4. Johannes SixtJan 22, 2010
  5. Robin RosenbergJan 23, 2010
  6. Johannes SixtJan 23, 2010
  7. Robin RosenbergJan 23, 2010
  8. Johannes SixtJan 23, 2010
  9. Junio C HamanoJan 23, 2010
  10. Junio C HamanoJan 23, 2010
  11. Johannes SixtJan 23, 2010
  12. Sverre RabbelierJan 23, 2010
  13. Thomas RastJan 24, 2010
  14. Bernhard R. LinkJan 24, 2010
  15. Junio C HamanoJan 24, 2010
  16. Johannes SixtJan 24, 2010
  17. Junio C HamanoJan 24, 2010
  18. Robin RosenbergJan 25, 2010
  19. Thomas RastJan 22, 2010
  20. Junio C HamanoJan 22, 2010

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.