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

[PATCH] Support ent:relative_path

From
DHDana How <danahow@gmail.com>
Date
May 4, 2007, 07:18 UTC
Message-ID
<463ADE51.2030108@gmail.com>
Most commands accept relative paths,  but this is
not true of arguments in ent:path format.  This
patch makes all 3 of the following git-show commands
work in the git source tree (not just the first):
 % cd xdiff
 % git-show v1.5.2-rc0:xdiff/xemit.h
 % git-show v1.5.2-rc0:./xemit.h
 % git-config --bool core.relativepaths yes
 % git-show v1.5.2-rc0:xemit.h
Signed-off-by: Dana L. How <danahow@gmail.com>
---
 cache.h       |    2 ++
 config.c      |    5 +++++
 environment.c |    1 +
 setup.c       |    5 ++++-
 sha1_name.c   |   27 ++++++++++++++++++++++++---
 5 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/cache.h b/cache.h
index 8e76152..fc3fcb1 100644
--- a/cache.h
+++ b/cache.h
@@ -215,6 +215,7 @@ extern char *get_graft_file(void);
 
 #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
 
+extern const char *prefix_to_cwd;
 extern const char **get_pathspec(const char *prefix, const char **pathspec);
 extern const char *setup_git_directory_gently(int *);
 extern const char *setup_git_directory(void);
@@ -276,6 +277,7 @@ extern int delete_ref(const char *, const unsigned char *sha1);
 extern int use_legacy_headers;
 extern int trust_executable_bit;
 extern int has_symlinks;
+extern int assume_relative_paths;
 extern int assume_unchanged;
 extern int prefer_symlink_refs;
 extern int log_all_ref_updates;
diff --git a/config.c b/config.c
index 70d1055..7525965 100644
--- a/config.c
+++ b/config.c
@@ -279,6 +279,11 @@ int git_default_config(const char *var, const char *value)
 		return 0;
 	}
 
+	if (!strcmp(var, "core.relativepaths")) {
+		assume_relative_paths = git_config_bool(var, value);
+		return 0;
+	}
+
 	if (!strcmp(var, "core.ignorestat")) {
 		assume_unchanged = git_config_bool(var, value);
 		return 0;
diff --git a/environment.c b/environment.c
index 2231659..f1b867d 100644
--- a/environment.c
+++ b/environment.c
@@ -14,6 +14,7 @@ char git_default_name[MAX_GITNAME];
 int use_legacy_headers = 1;
 int trust_executable_bit = 1;
 int has_symlinks = 1;
+int assume_relative_paths;
 int assume_unchanged;
 int prefer_symlink_refs;
 int is_bare_repository_cfg = -1; /* unspecified */
diff --git a/setup.c b/setup.c
index a45ea83..46ae6e3 100644
--- a/setup.c
+++ b/setup.c
@@ -1,5 +1,7 @@
 #include "cache.h"
 
+const char *prefix_to_cwd;
+
 const char *prefix_path(const char *prefix, int len, const char *path)
 {
 	const char *orig = path;
@@ -252,7 +254,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
 	cwd[len++] = '/';
 	cwd[len] = 0;
 	inside_git_dir = !prefixcmp(cwd + offset, ".git/");
-	return cwd + offset;
+	prefix_to_cwd = cwd + offset;
+	return prefix_to_cwd;
 }
 
 int git_config_perm(const char *var, const char *value)
diff --git a/sha1_name.c b/sha1_name.c
index 55f25a2..0b9e92c 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -592,6 +592,24 @@ static int handle_one_ref(const char *path,
 	return 0;
 }
 
+static void prepend_prefix(const char **cp, int *namelen)
+{
+	static char fullpath[PATH_MAX];
+	if (*namelen > 2 && !memcmp(*cp, "./", 2)) {
+		*cp += 2;
+		*namelen -= 2;
+	} else
+	if (!assume_relative_paths || !prefix_to_cwd)
+		return;
+
+	*namelen += strlen(prefix_to_cwd);
+	if (*namelen >= PATH_MAX)
+		die("path too long");
+	strcpy(fullpath, prefix_to_cwd);
+	strcat(fullpath, *cp);
+	*cp = fullpath;
+}
+
 /*
  * This interprets names like ':/Initial revision of "git"' by searching
  * through history and returning the first commit whose message starts
@@ -681,6 +699,7 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
 			read_cache();
 		if (active_nr < 0)
 			return -1;
+		prepend_prefix(&cp, &namelen);
 		pos = cache_name_pos(cp, namelen);
 		if (pos < 0)
 			pos = -pos - 1;
@@ -708,9 +727,11 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
 	}
 	if (*cp == ':') {
 		unsigned char tree_sha1[20];
-		if (!get_sha1_1(name, cp-name, tree_sha1))
-			return get_tree_entry(tree_sha1, cp+1, sha1,
-					      mode);
+		if (!get_sha1_1(name, cp - name, tree_sha1)) {
+			namelen -= ++cp - name;
+			prepend_prefix(&cp, &namelen);
+			return get_tree_entry(tree_sha1, cp, sha1, mode);
+		}
 	}
 	return ret;
 }
-- 
1.5.2.rc0.787.g0014
Next: Dana How
Message 1 of 28 in “Support ent:relative_path”
  1. Support ent:relative_pathDana How, May 4, 2007
  2. Dana HowMay 4, 2007
  3. Junio C HamanoMay 4, 2007
  4. Dana HowMay 4, 2007
  5. Alex RiesenMay 4, 2007
  6. Dana HowMay 4, 2007
  7. Alex RiesenMay 4, 2007
  8. Dana HowMay 4, 2007
  9. Alex RiesenMay 4, 2007
  10. Dana HowMay 4, 2007
  11. Alex RiesenMay 4, 2007
  12. Johannes SchindelinMay 4, 2007
  13. Alex RiesenMay 4, 2007
  14. Johannes SixtMay 4, 2007
  15. Junio C HamanoMay 4, 2007
  16. Dana HowMay 4, 2007
  17. Johannes SchindelinMay 4, 2007
  18. Junio C HamanoMay 4, 2007
  19. Johannes SchindelinMay 4, 2007
  20. Junio C HamanoMay 4, 2007
  21. Johannes SchindelinMay 4, 2007
  22. Alex RiesenMay 4, 2007
  23. Jakub NarebskiMay 4, 2007
  24. Junio C HamanoMay 5, 2007
  25. Dana HowMay 5, 2007
  26. Jakub NarebskiMay 5, 2007
  27. Junio C HamanoMay 5, 2007
  28. Alex RiesenMay 4, 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.