From a57114c81832a70efda4991131b9b99d1b112ea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Hasselstr=C3=B6m?= Date: Fri, 8 Aug 2008 22:48:23 +0200 Subject: [PATCH 1/4] Refactoring: Split up diff_tree_stdin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Into a first half that determines what operation to do, and a second half that does it. Currently the only operation is diffing one or more commits, but a later patch will add diffing of trees, at which point this refactoring will pay off. Signed-off-by: Karl Hasselström Signed-off-by: Junio C Hamano --- builtin-diff-tree.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c index 415cb1612f..ebbd6317c3 100644 --- a/builtin-diff-tree.c +++ b/builtin-diff-tree.c @@ -14,20 +14,10 @@ static int diff_tree_commit_sha1(const unsigned char *sha1) return log_tree_commit(&log_tree_opt, commit); } -static int diff_tree_stdin(char *line) +/* Diff one or more commits. */ +static int stdin_diff_commit(struct commit *commit, char *line, int len) { - int len = strlen(line); unsigned char sha1[20]; - struct commit *commit; - - 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)) - return -1; if (isspace(line[40]) && !get_sha1_hex(line+41, sha1)) { /* Graft the fake parents locally to the commit */ int pos = 41; @@ -52,6 +42,23 @@ static int diff_tree_stdin(char *line) return log_tree_commit(&log_tree_opt, commit); } +static int diff_tree_stdin(char *line) +{ + int len = strlen(line); + unsigned char sha1[20]; + struct commit *commit; + + 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)) + return -1; + return stdin_diff_commit(commit, line, len); +} + static const char diff_tree_usage[] = "git diff-tree [--stdin] [-m] [-c] [--cc] [-s] [-v] [--pretty] [-t] [-r] [--root] " "[] [] [...]\n" From 7cccfaa2809a09cb321a5f1276c5b91a71594527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Hasselstr=C3=B6m?= Date: Sun, 10 Aug 2008 18:12:53 +0200 Subject: [PATCH 2/4] diff-tree: Note that the commit ID is printed with --stdin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's sort of already documented with the --no-commit-id command-line flag, but let's not hide important information from the user. Signed-off-by: Karl Hasselström Signed-off-by: Junio C Hamano --- Documentation/git-diff-tree.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Documentation/git-diff-tree.txt b/Documentation/git-diff-tree.txt index 1fdf20dcc9..1f4b91ed45 100644 --- a/Documentation/git-diff-tree.txt +++ b/Documentation/git-diff-tree.txt @@ -52,10 +52,14 @@ include::diff-options.txt[] reads either one or a list of separated with a single space from its standard input. + -When a single commit is given on one line of such input, it compares -the commit with its parents. The following flags further affects its -behavior. The remaining commits, when given, are used as if they are +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. ++ +The following flags further affects its behavior. -m:: By default, 'git-diff-tree --stdin' does not show From 140b378d07229e3bcef0613e11aa0a04e4db3ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Hasselstr=C3=B6m?= Date: Sun, 10 Aug 2008 18:12:58 +0200 Subject: [PATCH 3/4] Teach git diff-tree --stdin to diff trees MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Junio C Hamano --- Documentation/git-diff-tree.txt | 15 ++++++++++----- 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 arguments from the command line. Instead, it - reads either one or a list of - separated with a single space from its standard input. + reads lines containing either two , one , or a + list of 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[] = From 5bf707cde14f60b7a066bdab5dbdefaec1a1d0a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Hasselstr=C3=B6m?= Date: Sun, 10 Aug 2008 18:13:04 +0200 Subject: [PATCH 4/4] Add test for diff-tree --stdin with two trees MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Karl Hasselström Signed-off-by: Junio C Hamano --- t/t4002-diff-basic.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh index a4cfde6b29..27743c4c59 100755 --- a/t/t4002-diff-basic.sh +++ b/t/t4002-diff-basic.sh @@ -168,6 +168,20 @@ test_expect_success \ 'git diff-tree -r $tree_A $tree_B >.test-a && cmp -s .test-a .test-recursive-AB' +test_expect_success \ + 'diff-tree --stdin of known trees.' \ + 'echo $tree_A $tree_B | git diff-tree --stdin > .test-a && + echo $tree_A $tree_B > .test-plain-ABx && + cat .test-plain-AB >> .test-plain-ABx && + cmp -s .test-a .test-plain-ABx' + +test_expect_success \ + 'diff-tree --stdin of known trees.' \ + 'echo $tree_A $tree_B | git diff-tree -r --stdin > .test-a && + echo $tree_A $tree_B > .test-recursive-ABx && + cat .test-recursive-AB >> .test-recursive-ABx && + cmp -s .test-a .test-recursive-ABx' + test_expect_success \ 'diff-cache O with A in cache' \ 'git read-tree $tree_A &&