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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---

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

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux