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

[PATCH v5 3/3] Use simpler relative_path when set_git_dir

From
Jiang Xin <worldhello.net@gmail.com>
Date
Oct 14, 2013, 02:29 UTC
Message-ID
<f4c0808819d91003a90860b67e2b4121c673a5db.1381717700.git.worldhello.net@gmail.com>
In-Reply-To
<cover.1381717700.git.worldhello.net@gmail.com>

Using a relative_path as git_dir first appears in v1.5.6-1-g044bbbc. It will make git_dir shorter only if git_dir is inside work_tree, and this will increase performance. But my last refactor effort on relative_path function (commit v1.8.3-rc2-12-ge02ca72) changed that. Always use relative_path as git_dir may bring troubles like $gmane/234434.

Because new relative_path is a combination of original relative_path from path.c and original path_relative from quote.c, so in order to restore the origin implementation, save the original relative_path as remove_leading_path, and call it in setup.c.

Suggested-by: Karsten Blees <karsten.blees@gmail.com>
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 cache.h |  1 +
 path.c  | 45 +++++++++++++++++++++++++++++++++++++++++++++
 setup.c |  5 +----
 3 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/cache.h b/cache.h
index 8e42256..94475bd 100644
--- a/cache.h
+++ b/cache.h
@@ -737,6 +737,7 @@ int is_directory(const char *);
 const char *real_path(const char *path);
 const char *real_path_if_valid(const char *path);
 const char *absolute_path(const char *path);
+const char *remove_leading_path(const char *in, const char *prefix);
 const char *relative_path(const char *in, const char *prefix, struct strbuf *sb);
 int normalize_path_copy(char *dst, const char *src);
 int longest_ancestor_length(const char *path, struct string_list *prefixes);
diff --git a/path.c b/path.c
index 0c16dc5..fa62da5 100644
--- a/path.c
+++ b/path.c
@@ -558,6 +558,51 @@ const char *relative_path(const char *in, const char *prefix,
 }
 
 /*
+ * A simpler implementation of relative_path
+ *
+ * Get relative path by removing "prefix" from "in". This function
+ * first appears in v1.5.6-1-g044bbbc, and makes git_dir shorter
+ * to increase performance when traversing the path to work_tree.
+ */
+const char *remove_leading_path(const char *in, const char *prefix)
+{
+	static char buf[PATH_MAX + 1];
+	int i = 0, j = 0;
+
+	if (!prefix || !prefix[0])
+		return in;
+	while (prefix[i]) {
+		if (is_dir_sep(prefix[i])) {
+			if (!is_dir_sep(in[j]))
+				return in;
+			while (is_dir_sep(prefix[i]))
+				i++;
+			while (is_dir_sep(in[j]))
+				j++;
+			continue;
+		} else if (in[j] != prefix[i]) {
+			return in;
+		}
+		i++;
+		j++;
+	}
+	if (
+	    /* "/foo" is a prefix of "/foo" */
+	    in[j] &&
+	    /* "/foo" is not a prefix of "/foobar" */
+	    !is_dir_sep(prefix[i-1]) && !is_dir_sep(in[j])
+	   )
+		return in;
+	while (is_dir_sep(in[j]))
+		j++;
+	if (!in[j])
+		strcpy(buf, ".");
+	else
+		strcpy(buf, in + j);
+	return buf;
+}
+
+/*
  * It is okay if dst == src, but they should not overlap otherwise.
  *
  * Performs the following normalizations on src, storing the result in dst:
diff --git a/setup.c b/setup.c
index 0d9ea62..dad39c1 100644
--- a/setup.c
+++ b/setup.c
@@ -360,7 +360,6 @@ int is_inside_work_tree(void)
 
 void setup_work_tree(void)
 {
-	struct strbuf sb = STRBUF_INIT;
 	const char *work_tree, *git_dir;
 	static int initialized = 0;
 
@@ -380,10 +379,8 @@ void setup_work_tree(void)
 	if (getenv(GIT_WORK_TREE_ENVIRONMENT))
 		setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
 
-	set_git_dir(relative_path(git_dir, work_tree, &sb));
+	set_git_dir(remove_leading_path(git_dir, work_tree));
 	initialized = 1;
-
-	strbuf_release(&sb);
 }
 
 static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
-- 
1.8.4
Previous: Jiang XinNext: Jiang Xin
Message 42 of 48 in “Regression in e02ca72: git svn rebase is broken on Windows”
  1. TvangesteSep 10, 2013
  2. Johannes SchindelinSep 10, 2013
  3. TvangesteSep 10, 2013
  4. Johannes SchindelinSep 10, 2013
  5. TvangesteSep 10, 2013
  6. Johannes SixtSep 10, 2013
  7. TvangesteSep 10, 2013
  8. Junio C HamanoSep 10, 2013
  9. Karsten BleesSep 10, 2013
  10. Jiang XinSep 11, 2013
  11. Jiang XinSep 11, 2013
  12. Johannes SixtSep 11, 2013
  13. 1/2 relative_path should honor dos_drive_prefixJiang Xin, Sep 12, 2013
  14. 2/2 Use simpler relative_path when set_git_dirJiang Xin, Sep 12, 2013
  15. Johannes SixtSep 12, 2013
  16. TvangesteSep 12, 2013
  17. Torsten BögershausenSep 12, 2013
  18. Junio C HamanoSep 12, 2013
  19. Johannes SixtSep 12, 2013
  20. Junio C HamanoSep 12, 2013
  21. Jiang XinSep 13, 2013
  22. Junio C HamanoSep 13, 2013
  23. Jiang XinSep 17, 2013
  24. 1/3 test: use unambigous leading path (/foo) for mingwJiang Xin, Sep 17, 2013
  25. 2/3 relative_path should honor DOS and UNC pathsJiang Xin, Sep 17, 2013
  26. Junio C HamanoSep 17, 2013
  27. Jiang XinSep 18, 2013
  28. Junio C HamanoSep 18, 2013
  29. 3/3 Use simpler relative_path when set_git_dirJiang Xin, Sep 17, 2013
  30. Johannes SixtSep 17, 2013
  31. Torsten BögershausenSep 18, 2013
  32. Jiang XinSep 20, 2013
  33. 0/3 relative path regression fixJiang Xin, Sep 20, 2013
  34. 1/3 test: use unambigous leading path (/foo) for mingwJiang Xin, Sep 20, 2013
  35. Sebastian SchuberthOct 10, 2013
  36. Jiang XinOct 14, 2013
  37. 0/3 relative path regression fixJiang Xin, Oct 14, 2013
  38. 1/3 test: use unambigous leading path (/foo) for MSYSJiang Xin, Oct 14, 2013
  39. Sebastian SchuberthOct 14, 2013
  40. Eric SunshineOct 14, 2013
  41. 2/3 relative_path should honor dos-drive-prefixJiang Xin, Oct 14, 2013
  42. 3/3 Use simpler relative_path when set_git_dirJiang Xin, Oct 14, 2013
  43. 2/3 relative_path should honor dos-driver-prefixJiang Xin, Sep 20, 2013
  44. Sebastian SchuberthOct 10, 2013
  45. 3/3 Use simpler relative_path when set_git_dirJiang Xin, Sep 20, 2013
  46. Torsten BögershausenSep 13, 2013
  47. Karsten BleesSep 12, 2013
  48. Torsten BögershausenSep 18, 2013

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.