Merge branch 'jk/submodule-init-segv-fix'
[gitweb.git] / builtin / diff-tree.c
index 8ce00480cd484e10b0b46d931c934fcd3ba7b71e..326f88b6576d6c02e9a0bcecb5a0b402bb257372 100644 (file)
@@ -7,46 +7,44 @@
 
 static struct rev_info log_tree_opt;
 
-static int diff_tree_commit_sha1(const unsigned char *sha1)
+static int diff_tree_commit_sha1(const struct object_id *oid)
 {
-       struct commit *commit = lookup_commit_reference(sha1);
+       struct commit *commit = lookup_commit_reference(oid->hash);
        if (!commit)
                return -1;
        return log_tree_commit(&log_tree_opt, commit);
 }
 
 /* Diff one or more commits. */
-static int stdin_diff_commit(struct commit *commit, char *line, int len)
+static int stdin_diff_commit(struct commit *commit, const char *p)
 {
-       unsigned char sha1[20];
-       if (isspace(line[40]) && !get_sha1_hex(line+41, sha1)) {
-               /* Graft the fake parents locally to the commit */
-               int pos = 41;
-               struct commit_list **pptr;
-
-               /* Free the real parent list */
-               free_commit_list(commit->parents);
-               commit->parents = NULL;
-               pptr = &(commit->parents);
-               while (line[pos] && !get_sha1_hex(line + pos, sha1)) {
-                       struct commit *parent = lookup_commit(sha1);
-                       if (parent) {
-                               pptr = &commit_list_insert(parent, pptr)->next;
-                       }
-                       pos += 41;
+       struct object_id oid;
+       struct commit_list **pptr = NULL;
+
+       /* Graft the fake parents locally to the commit */
+       while (isspace(*p++) && !parse_oid_hex(p, &oid, &p)) {
+               struct commit *parent = lookup_commit(oid.hash);
+               if (!pptr) {
+                       /* Free the real parent list */
+                       free_commit_list(commit->parents);
+                       commit->parents = NULL;
+                       pptr = &(commit->parents);
+               }
+               if (parent) {
+                       pptr = &commit_list_insert(parent, pptr)->next;
                }
        }
        return log_tree_commit(&log_tree_opt, commit);
 }
 
 /* Diff two trees. */
-static int stdin_diff_trees(struct tree *tree1, char *line, int len)
+static int stdin_diff_trees(struct tree *tree1, const char *p)
 {
-       unsigned char sha1[20];
+       struct object_id oid;
        struct tree *tree2;
-       if (len != 82 || !isspace(line[40]) || get_sha1_hex(line + 41, sha1))
+       if (!isspace(*p++) || parse_oid_hex(p, &oid, &p) || *p)
                return error("Need exactly two trees, separated by a space");
-       tree2 = lookup_tree(sha1);
+       tree2 = lookup_tree(oid.hash);
        if (!tree2 || parse_tree(tree2))
                return -1;
        printf("%s %s\n", oid_to_hex(&tree1->object.oid),
@@ -60,23 +58,24 @@ static int stdin_diff_trees(struct tree *tree1, char *line, int len)
 static int diff_tree_stdin(char *line)
 {
        int len = strlen(line);
-       unsigned char sha1[20];
+       struct object_id oid;
        struct object *obj;
+       const char *p;
 
        if (!len || line[len-1] != '\n')
                return -1;
        line[len-1] = 0;
-       if (get_sha1_hex(line, sha1))
+       if (parse_oid_hex(line, &oid, &p))
                return -1;
-       obj = parse_object(sha1);
+       obj = parse_object(oid.hash);
        if (!obj)
                return -1;
        if (obj->type == OBJ_COMMIT)
-               return stdin_diff_commit((struct commit *)obj, line, len);
+               return stdin_diff_commit((struct commit *)obj, p);
        if (obj->type == OBJ_TREE)
-               return stdin_diff_trees((struct tree *)obj, line, len);
+               return stdin_diff_trees((struct tree *)obj, p);
        error("Object %s is a %s, not a commit or tree",
-             sha1_to_hex(sha1), typename(obj->type));
+             oid_to_hex(&oid), typename(obj->type));
        return -1;
 }
 
@@ -141,7 +140,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
                break;
        case 1:
                tree1 = opt->pending.objects[0].item;
-               diff_tree_commit_sha1(tree1->oid.hash);
+               diff_tree_commit_sha1(&tree1->oid);
                break;
        case 2:
                tree1 = opt->pending.objects[0].item;
@@ -164,9 +163,9 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
                        opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
                                               DIFF_SETUP_USE_CACHE);
                while (fgets(line, sizeof(line), stdin)) {
-                       unsigned char sha1[20];
+                       struct object_id oid;
 
-                       if (get_sha1_hex(line, sha1)) {
+                       if (get_oid_hex(line, &oid)) {
                                fputs(line, stdout);
                                fflush(stdout);
                        }