summaryrefslogtreecommitdiff
path: root/builtin-diff-tree.c
diff options
context:
space:
mode:
authorKarl Hasselström <kha@treskal.com>2008-08-10 16:12:58 (GMT)
committerJunio C Hamano <gitster@pobox.com>2008-08-11 08:35:47 (GMT)
commit140b378d07229e3bcef0613e11aa0a04e4db3ecf (patch)
treecf495414d9322aa8a1916560f1d74ae75687faa9 /builtin-diff-tree.c
parent7cccfaa2809a09cb321a5f1276c5b91a71594527 (diff)
downloadgit-140b378d07229e3bcef0613e11aa0a04e4db3ecf.zip
git-140b378d07229e3bcef0613e11aa0a04e4db3ecf.tar.gz
git-140b378d07229e3bcef0613e11aa0a04e4db3ecf.tar.bz2
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two trees, not three nor one; --stdin now supports this "two tree" form on its input, in addition to accepting lines with one or more commits. When diffing trees (either specified on the command line or from the standard input), the -s, -v, --pretty, --abbrev-commit, --encoding, --no-commit-id, and --always options are ignored, since they do not apply to trees; and the -m, -c, and --cc options are ignored since they would be meaningful only with three or more trees, which is not supported (yet). Signed-off-by: Karl Hasselström <kha@treskal.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-diff-tree.c')
-rw-r--r--builtin-diff-tree.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c
index ebbd631..1138c2d 100644
--- a/builtin-diff-tree.c
+++ b/builtin-diff-tree.c
@@ -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[] =