diff options
-rw-r--r-- | Documentation/git-diff-tree.txt | 15 | ||||
-rw-r--r-- | builtin-diff-tree.c | 33 |
2 files changed, 39 insertions, 9 deletions
diff --git a/Documentation/git-diff-tree.txt b/Documentation/git-diff-tree.txt index 1f4b91ed45..5d48664e62 100644 --- a/Documentation/git-diff-tree.txt +++ b/Documentation/git-diff-tree.txt @@ -49,17 +49,22 @@ include::diff-options.txt[] --stdin:: When '--stdin' is specified, the command does not take <tree-ish> arguments from the command line. Instead, it - reads either one <commit> or a list of <commit> - separated with a single space from its standard input. + reads lines containing either two <tree>, one <commit>, or a + list of <commit> from its standard input. (Use a single space + as separator.) + +When two trees are given, it compares the first tree with the second. When a single commit is given, it compares the commit with its parents. The remaining commits, when given, are used as if they are parents of the first commit. + -The ID of the first (or only) commit, followed by a newline, is -printed before the differences. +When comparing two trees, the ID of both trees (separated by a space +and terminated by a newline) is printed before the difference. When +comparing commits, the ID of the first (or only) commit, followed by a +newline, is printed. + -The following flags further affects its behavior. +The following flags further affects the behavior when comparing +commits (but not trees). -m:: By default, 'git-diff-tree --stdin' does not show diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c index ebbd6317c3..1138c2da73 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[] = |