git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v3 3/4] Teach git diff-tree --stdin to diff trees

From
Karl Hasselström <kha@treskal.com>
Date
Aug 10, 2008, 16:12 UTC
Message-ID
<20080810161258.7116.33770.stgit@yoghurt>
In-Reply-To
<20080810161035.7116.2171.stgit@yoghurt>

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 require three trees, which is not supported (yet).

Signed-off-by: Karl Hasselström <kha@treskal.com>
---
 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 1f4b91e..5d48664 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 ebbd631..5a56178 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 precisely 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[] =
Previous: Karl HasselströmNext: Karl Hasselström
Message 4 of 6 in “Teach git diff-tree --stdin to diff trees”
  1. 0/4 Teach git diff-tree --stdin to diff treesKarl Hasselström, Aug 10, 2008
  2. 1/4 Refactoring: Split up diff_tree_stdinKarl Hasselström, Aug 10, 2008
  3. 2/4 diff-tree: Note that the commit ID is printed with --stdinKarl Hasselström, Aug 10, 2008
  4. 3/4 Teach git diff-tree --stdin to diff treesKarl Hasselström, Aug 10, 2008
  5. 4/4 Add test for diff-tree --stdin with two treesKarl Hasselström, Aug 10, 2008
  6. Karl HasselströmAug 10, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.