[PATCH] Rename and extend read_tree_with_tree_or_commit_sha1
authorJunio C Hamano <junkio@cox.net>
Thu, 28 Apr 2005 23:42:27 +0000 (16:42 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 28 Apr 2005 23:42:27 +0000 (16:42 -0700)
This patch renames read_tree_with_tree_or_commit_sha1() to
read_object_with_reference() and extends it to automatically
dereference not just "commit" objects but "tag" objects.  With
this patch, you can say e.g.:

    ls-tree $tag
    read-tree -m $(merge-base $tag $HEAD) $tag $HEAD
    diff-cache $tag
    diff-tree $tag $HEAD

Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
cache.h
diff-cache.c
diff-tree.c
git-mktag.c
ls-tree.c
read-tree.c
sha1_file.c

diff --git a/cache.h b/cache.h
index 3277d48..aca98f3 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -143,9 +143,10 @@ extern int error(const char *err, ...);
 
 extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2);
 
-extern void *read_tree_with_tree_or_commit_sha1(const unsigned char *sha1,
-                                               unsigned long *size,
-                                               unsigned char *tree_sha1_ret);
+extern void *read_object_with_reference(const unsigned char *sha1,
+                                       const unsigned char *required_type,
+                                       unsigned long *size,
+                                       unsigned char *sha1_ret);
 
 static inline void *xmalloc(int size)
 {
index e365f71..899e373 100644 (file)
@@ -180,7 +180,7 @@ int main(int argc, char **argv)
 
        mark_merge_entries();
 
-       tree = read_tree_with_tree_or_commit_sha1(tree_sha1, &size, 0);
+       tree = read_object_with_reference(tree_sha1, "tree", &size, 0);
        if (!tree)
                die("bad tree object %s", argv[1]);
        if (read_tree(tree, size, 1))
index 5a1ad34..e7a5b7c 100644 (file)
@@ -238,10 +238,10 @@ static int diff_tree_sha1(const unsigned char *old, const unsigned char *new, co
        unsigned long size1, size2;
        int retval;
 
-       tree1 = read_tree_with_tree_or_commit_sha1(old, &size1, 0);
+       tree1 = read_object_with_reference(old, "tree", &size1, 0);
        if (!tree1)
                die("unable to read source tree (%s)", sha1_to_hex(old));
-       tree2 = read_tree_with_tree_or_commit_sha1(new, &size2, 0);
+       tree2 = read_object_with_reference(new, "tree", &size2, 0);
        if (!tree2)
                die("unable to read destination tree (%s)", sha1_to_hex(new));
        retval = diff_tree(tree1, size1, tree2, size2, base);
index 5d2830d..8605802 100644 (file)
@@ -114,7 +114,7 @@ int main(int argc, char **argv)
        // Read the signature
        size = read(0, buffer, MAXSIZE);
 
-       // Verify it for some basic sanity: it needs to start with "object <sha1>\ntag "
+       // Verify it for some basic sanity: it needs to start with "object <sha1>\ntype "
        if (verify_tag(buffer, size) < 0)
                die("invalid tag signature file");
 
index bd99f9a..d2ab02e 100644 (file)
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -73,7 +73,7 @@ static int list(unsigned char *sha1)
        void *buffer;
        unsigned long size;
 
-       buffer = read_tree_with_tree_or_commit_sha1(sha1, &size, 0);
+       buffer = read_object_with_reference(sha1, "tree", &size, 0);
        if (!buffer)
                die("unable to read sha1 file");
        list_recursive(buffer, "tree", size, NULL);
index 7b50fe6..604884a 100644 (file)
@@ -12,7 +12,7 @@ static int unpack_tree(unsigned char *sha1)
        void *buffer;
        unsigned long size;
 
-       buffer = read_tree_with_tree_or_commit_sha1(sha1, &size, 0);
+       buffer = read_object_with_reference(sha1, "tree", &size, 0);
        if (!buffer)
                return -1;
        return read_tree(buffer, size, stage);
index db2880e..29f48d5 100644 (file)
@@ -189,44 +189,49 @@ void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size
        return NULL;
 }
 
-void *read_tree_with_tree_or_commit_sha1(const unsigned char *sha1,
-                                        unsigned long *size,
-                                        unsigned char *tree_sha1_return)
+void *read_object_with_reference(const unsigned char *sha1,
+                                const unsigned char *required_type,
+                                unsigned long *size,
+                                unsigned char *actual_sha1_return)
 {
        char type[20];
        void *buffer;
        unsigned long isize;
-       int was_commit = 0;
-       unsigned char tree_sha1[20];
-
-       buffer = read_sha1_file(sha1, type, &isize);
-
-       /* 
-        * We might have read a commit instead of a tree, in which case
-        * we parse out the tree_sha1 and attempt to read from there.
-        * (buffer + 5) is because the tree sha1 is always at offset 5
-        * in a commit record ("tree ").
-        */
-       if (buffer &&
-           !strcmp(type, "commit") &&
-           !get_sha1_hex(buffer + 5, tree_sha1)) {
-               free(buffer);
-               buffer = read_sha1_file(tree_sha1, type, &isize);
-               was_commit = 1;
-       }
+       unsigned char actual_sha1[20];
 
-       /*
-        * Now do we have something and if so is it a tree?
-        */
-       if (!buffer || strcmp(type, "tree")) {
-               free(buffer);
-               return NULL;
-       }
+       memcpy(actual_sha1, sha1, 20);
+       while (1) {
+               int ref_length = -1;
+               const char *ref_type = NULL;
 
-       *size = isize;
-       if (tree_sha1_return)
-               memcpy(tree_sha1_return, was_commit ? tree_sha1 : sha1, 20);
-       return buffer;
+               buffer = read_sha1_file(actual_sha1, type, &isize);
+               if (!buffer)
+                       return NULL;
+               if (!strcmp(type, required_type)) {
+                       *size = isize;
+                       if (actual_sha1_return)
+                               memcpy(actual_sha1_return, actual_sha1, 20);
+                       return buffer;
+               }
+               /* Handle references */
+               else if (!strcmp(type, "commit"))
+                       ref_type = "tree ";
+               else if (!strcmp(type, "tag"))
+                       ref_type = "object ";
+               else {
+                       free(buffer);
+                       return NULL;
+               }
+               ref_length = strlen(ref_type);
+
+               if (memcmp(buffer, ref_type, ref_length) ||
+                   get_sha1_hex(buffer + ref_length, actual_sha1)) {
+                       free(buffer);
+                       return NULL;
+               }
+               /* Now we have the ID of the referred-to object in
+                * actual_sha1.  Check again. */
+       }
 }
 
 int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned char *returnsha1)