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

[PATCH] Simple support for tree entry specification with relative pathnames

From
Alex Riesen <raa.lkml@gmail.com>
Date
Dec 18, 2007, 20:47 UTC
Message-ID
<20071218204752.GD2875@steel.home>
In-Reply-To
<20071218204623.GC2875@steel.home>
This allows git show to understand something like this:
    $ test -f DIR/file && cd DIR &&  git show rev:file
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
---
This is a bit too simplistic and can be fooled easily:
    .../t$ git show HEAD:../t/test-lib.sh
wont work. It is short, though.
 cache.h     |    1 +
 revision.c  |    4 ++--
 sha1_name.c |   27 ++++++++++++++++++++++++---
 3 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/cache.h b/cache.h
index 39331c2..054f106 100644
--- a/cache.h
+++ b/cache.h
@@ -416,6 +416,7 @@ static inline unsigned int hexval(unsigned char c)
 
 extern int get_sha1(const char *str, unsigned char *sha1);
 extern int get_sha1_with_mode(const char *str, unsigned char *sha1, unsigned *mode);
+extern int get_sha1_with_prefix(const char *prefix, const char *name, unsigned char *sha1, unsigned *mode);
 extern int get_sha1_hex(const char *hex, unsigned char *sha1);
 extern char *sha1_to_hex(const unsigned char *sha1);	/* static buffer result! */
 extern int read_ref(const char *filename, unsigned char *sha1);
diff --git a/revision.c b/revision.c
index 7e2f4f1..cac283c 100644
--- a/revision.c
+++ b/revision.c
@@ -855,7 +855,7 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
 		local_flags = UNINTERESTING;
 		arg++;
 	}
-	if (get_sha1_with_mode(arg, sha1, &mode))
+	if (get_sha1_with_prefix(revs->prefix, arg, sha1, &mode))
 		return -1;
 	if (!cant_be_filename)
 		verify_non_filename(revs->prefix, arg);
@@ -1280,7 +1280,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 		unsigned char sha1[20];
 		struct object *object;
 		unsigned mode;
-		if (get_sha1_with_mode(def, sha1, &mode))
+		if (get_sha1_with_prefix(revs->prefix, def, sha1, &mode))
 			die("bad default revision '%s'", def);
 		object = get_reference(revs, def, sha1, 0);
 		add_pending_object_with_mode(revs, object, def, mode);
diff --git a/sha1_name.c b/sha1_name.c
index 13e1164..358aab7 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -656,6 +656,12 @@ int get_sha1(const char *name, unsigned char *sha1)
 
 int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
 {
+	return get_sha1_with_prefix(NULL, name, sha1, mode);
+}
+
+int get_sha1_with_prefix(const char *prefix, const char *name, unsigned char *sha1, unsigned *mode)
+{
+	char *prefixpath;
 	int ret, bracket_depth;
 	int namelen = strlen(name);
 	const char *cp;
@@ -664,6 +670,9 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
 	ret = get_sha1_1(name, namelen, sha1);
 	if (!ret)
 		return ret;
+
+	prefixpath = prefix ? xmalloc(strlen(prefix) + namelen + 1): NULL;
+
 	/* sha1:path --> object name of path in ent sha1
 	 * :path -> object name of path in index
 	 * :[0-3]:path -> object name of path in index at stage
@@ -685,6 +694,10 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
 		namelen = namelen - (cp - name);
 		if (!active_cache)
 			read_cache();
+		if (prefix) {
+			namelen = sprintf(prefixpath, "%s%s", prefix, cp);
+			cp = prefixpath;
+		}
 		pos = cache_name_pos(cp, namelen);
 		if (pos < 0)
 			pos = -pos - 1;
@@ -696,10 +709,12 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
 			if (ce_stage(ce) == stage) {
 				hashcpy(sha1, ce->sha1);
 				*mode = ntohl(ce->ce_mode);
+				free(prefixpath);
 				return 0;
 			}
 			pos++;
 		}
+		free(prefixpath);
 		return -1;
 	}
 	for (cp = name, bracket_depth = 0; *cp; cp++) {
@@ -712,9 +727,15 @@ 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)) {
+			if (!prefix)
+				ret = get_tree_entry(tree_sha1, cp + 1, sha1, mode);
+			else {
+				sprintf(prefixpath, "%s%s", prefix, cp + 1);
+				ret = get_tree_entry(tree_sha1, prefixpath, sha1, mode);
+				free(prefixpath);
+			}
+		}
 	}
 	return ret;
 }
-- 
1.5.4.rc0.86.g30f5
Previous: Alex RiesenNext: Alex Riesen
Message 4 of 43 in “log/show: relative pathnames do not work in rev:path”
  1. Alex RiesenDec 18, 2007
  2. Jakub NarebskiDec 18, 2007
  3. Alex RiesenDec 18, 2007
  4. Simple support for tree entry specification with relative pathnamesAlex Riesen, Dec 18, 2007
  5. Introduce pathexpand: syntax-level chdir into the given cwdAlex Riesen, Dec 18, 2007
  6. Use pathexpand to preparse the relative pathnames in blob referencesAlex Riesen, Dec 18, 2007
  7. Dana HowDec 18, 2007
  8. Jeff KingDec 19, 2007
  9. Dana HowDec 18, 2007
  10. Alex RiesenDec 18, 2007
  11. Jakub NarebskiDec 18, 2007
  12. Linus TorvaldsDec 18, 2007
  13. Dana HowDec 18, 2007
  14. Alex RiesenDec 18, 2007
  15. Junio C HamanoDec 18, 2007
  16. Dana HowDec 18, 2007
  17. Johannes SchindelinDec 18, 2007
  18. Junio C HamanoDec 19, 2007
  19. Alex RiesenDec 18, 2007
  20. Johannes SchindelinDec 18, 2007
  21. Dana HowDec 18, 2007
  22. Johannes SchindelinDec 18, 2007
  23. Linus TorvaldsDec 19, 2007
  24. Dana HowDec 19, 2007
  25. Alex RiesenDec 19, 2007
  26. Jakub NarebskiDec 19, 2007
  27. Dana HowDec 19, 2007
  28. Jakub NarebskiDec 19, 2007
  29. sha1_name: grok <revision>:./<relative-path>Johannes Schindelin, Dec 19, 2007
  30. Jeff KingDec 19, 2007
  31. Dana HowDec 19, 2007
  32. Alex RiesenDec 19, 2007
  33. Junio C HamanoDec 20, 2007
  34. Johannes SchindelinDec 20, 2007
  35. Nguyen Thai Ngoc DuyDec 21, 2007
  36. Junio C HamanoDec 21, 2007
  37. Nguyen Thai Ngoc DuyDec 21, 2007
  38. Johannes SchindelinDec 22, 2007
  39. Jakub NarebskiDec 18, 2007
  40. Dana HowDec 18, 2007
  41. Junio C HamanoDec 18, 2007
  42. Jakub NarebskiDec 18, 2007
  43. Alex RiesenDec 19, 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.