提交 22c09307 编写于 作者: J Junio C Hamano

Merge branch 'kh/diff-tree'

* kh/diff-tree:
  Add test for diff-tree --stdin with two trees
  Teach git diff-tree --stdin to diff trees
  diff-tree: Note that the commit ID is printed with --stdin
  Refactoring: Split up diff_tree_stdin
...@@ -49,13 +49,22 @@ include::diff-options.txt[] ...@@ -49,13 +49,22 @@ include::diff-options.txt[]
--stdin:: --stdin::
When '--stdin' is specified, the command does not take When '--stdin' is specified, the command does not take
<tree-ish> arguments from the command line. Instead, it <tree-ish> arguments from the command line. Instead, it
reads either one <commit> or a list of <commit> reads lines containing either two <tree>, one <commit>, or a
separated with a single space from its standard input. list of <commit> from its standard input. (Use a single space
as separator.)
+ +
When a single commit is given on one line of such input, it compares When two trees are given, it compares the first tree with the second.
the commit with its parents. The following flags further affects its When a single commit is given, it compares the commit with its
behavior. The remaining commits, when given, are used as if they are parents. The remaining commits, when given, are used as if they are
parents of the first commit. parents of the first commit.
+
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 the behavior when comparing
commits (but not trees).
-m:: -m::
By default, 'git-diff-tree --stdin' does not show By default, 'git-diff-tree --stdin' does not show
......
...@@ -14,20 +14,10 @@ static int diff_tree_commit_sha1(const unsigned char *sha1) ...@@ -14,20 +14,10 @@ static int diff_tree_commit_sha1(const unsigned char *sha1)
return log_tree_commit(&log_tree_opt, commit); 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]; 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)) { if (isspace(line[40]) && !get_sha1_hex(line+41, sha1)) {
/* Graft the fake parents locally to the commit */ /* Graft the fake parents locally to the commit */
int pos = 41; int pos = 41;
...@@ -52,6 +42,48 @@ static int diff_tree_stdin(char *line) ...@@ -52,6 +42,48 @@ static int diff_tree_stdin(char *line)
return log_tree_commit(&log_tree_opt, commit); 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 object *obj;
if (!len || line[len-1] != '\n')
return -1;
line[len-1] = 0;
if (get_sha1_hex(line, sha1))
return -1;
obj = lookup_object(sha1);
obj = obj ? obj : parse_object(sha1);
if (!obj)
return -1;
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[] = static const char diff_tree_usage[] =
"git diff-tree [--stdin] [-m] [-c] [--cc] [-s] [-v] [--pretty] [-t] [-r] [--root] " "git diff-tree [--stdin] [-m] [-c] [--cc] [-s] [-v] [--pretty] [-t] [-r] [--root] "
"[<common diff options>] <tree-ish> [<tree-ish>] [<path>...]\n" "[<common diff options>] <tree-ish> [<tree-ish>] [<path>...]\n"
......
...@@ -168,6 +168,20 @@ test_expect_success \ ...@@ -168,6 +168,20 @@ test_expect_success \
'git diff-tree -r $tree_A $tree_B >.test-a && 'git diff-tree -r $tree_A $tree_B >.test-a &&
cmp -s .test-a .test-recursive-AB' 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 \ test_expect_success \
'diff-cache O with A in cache' \ 'diff-cache O with A in cache' \
'git read-tree $tree_A && 'git read-tree $tree_A &&
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册