builtin-help: fallback to GIT_MAN_VIEWER before man
[gitweb.git] / builtin-diff-tree.c
index ebbd6317c3b2a38a79a9e8f6605a6596a5d9d45e..1138c2da733bfe2730bbcb95d2a281de12595bde 100644 (file)
@@ -42,21 +42,46 @@ static int stdin_diff_commit(struct commit *commit, char *line, int len)
        return log_tree_commit(&log_tree_opt, commit);
 }
 
+/* Diff two trees. */
+static int stdin_diff_trees(struct tree *tree1, char *line, int len)
+{
+       unsigned char sha1[20];
+       struct tree *tree2;
+       if (len != 82 || !isspace(line[40]) || get_sha1_hex(line + 41, sha1))
+               return error("Need exactly two trees, separated by a space");
+       tree2 = lookup_tree(sha1);
+       if (!tree2 || parse_tree(tree2))
+               return -1;
+       printf("%s %s\n", sha1_to_hex(tree1->object.sha1),
+                         sha1_to_hex(tree2->object.sha1));
+       diff_tree_sha1(tree1->object.sha1, tree2->object.sha1,
+                      "", &log_tree_opt.diffopt);
+       log_tree_diff_flush(&log_tree_opt);
+       return 0;
+}
+
 static int diff_tree_stdin(char *line)
 {
        int len = strlen(line);
        unsigned char sha1[20];
-       struct commit *commit;
+       struct object *obj;
 
        if (!len || line[len-1] != '\n')
                return -1;
        line[len-1] = 0;
        if (get_sha1_hex(line, sha1))
                return -1;
-       commit = lookup_commit(sha1);
-       if (!commit || parse_commit(commit))
+       obj = lookup_object(sha1);
+       obj = obj ? obj : parse_object(sha1);
+       if (!obj)
                return -1;
-       return stdin_diff_commit(commit, line, len);
+       if (obj->type == OBJ_COMMIT)
+               return stdin_diff_commit((struct commit *)obj, line, len);
+       if (obj->type == OBJ_TREE)
+               return stdin_diff_trees((struct tree *)obj, line, len);
+       error("Object %s is a %s, not a commit or tree",
+             sha1_to_hex(sha1), typename(obj->type));
+       return -1;
 }
 
 static const char diff_tree_usage[] =