git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Alex Riesen" <raa.lkml@gmail.com>
To: "Johannes Schindelin" <Johannes.Schindelin@gmx.de>
Cc: "Junio C Hamano" <junkio@cox.net>, git@vger.kernel.org
Subject: [PATCH] Allow git-diff exit with codes similar to diff(1)
Date: Wed, 14 Mar 2007 01:17:04 +0100	[thread overview]
Message-ID: <81b0412b0703131717k7106ee1cg964628f0bda2c83e@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 914 bytes --]

This introduces a new command-line option: --exit-code. The diff
programs will return 1 for differences, return 0 for equality, and
something else for errors.

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
---

Still working on my e-mail problems. Sorry for duplications.

As promised on irc. I'm somewhat confused about diff_tree: it used to
unconditionally return 0, yet every caller of it saves and passes the
value!

 Documentation/diff-options.txt |    5 ++++
 builtin-diff-tree.c            |   12 +++++----
 builtin-diff.c                 |    5 ++-
 diff-lib.c                     |   12 +++++++--
 diff.c                         |    2 +
 diff.h                         |    3 +-
 t/t4017-diff-retval.sh         |   51 ++++++++++++++++++++++++++++++++++++++++
 tree-diff.c                    |   11 +++++++-
 8 files changed, 88 insertions(+), 13 deletions(-)
 create mode 100755 t/t4017-diff-retval.sh

[-- Attachment #2: 0001-Allow-git-diff-exit-with-codes-similar-to-diff-1.patch --]
[-- Type: text/x-patch, Size: 8599 bytes --]

From 2309f82f88274a0ddac0d5b06c5df580f5cb7d81 Mon Sep 17 00:00:00 2001
From: Alex Riesen <raa.lkml@gmail.com>
Date: Tue, 13 Mar 2007 18:06:08 +0100
Subject: [PATCH] Allow git-diff exit with codes similar to diff(1)

This introduces a new command-line option: --exit-code. The diff
programs will return 1 for differences, return 0 for equality, and
something else for errors.

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
---
 Documentation/diff-options.txt |    5 ++++
 builtin-diff-tree.c            |   12 +++++----
 builtin-diff.c                 |    5 ++-
 diff-lib.c                     |   12 +++++++--
 diff.c                         |    2 +
 diff.h                         |    3 +-
 t/t4017-diff-retval.sh         |   51 ++++++++++++++++++++++++++++++++++++++++
 tree-diff.c                    |   11 +++++++-
 8 files changed, 88 insertions(+), 13 deletions(-)
 create mode 100755 t/t4017-diff-retval.sh

diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index d8696b7..77a3f78 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -159,5 +159,10 @@
 -w::
 	Shorthand for "--ignore-all-space".
 
+--exit-code::
+	Make the program exit with codes similar to diff(1).
+	That is, it exits with 1 if there were differences and
+	0 means no differences.
+
 For more detailed explanation on these common options, see also
 link:diffcore.html[diffcore documentation].
diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c
index 24cb2d7..d293a5e 100644
--- a/builtin-diff-tree.c
+++ b/builtin-diff-tree.c
@@ -61,6 +61,7 @@ COMMON_DIFF_OPTIONS_HELP;
 
 int cmd_diff_tree(int argc, const char **argv, const char *prefix)
 {
+	int result = 0;
 	int nr_sha1;
 	char line[1000];
 	struct object *tree1, *tree2;
@@ -110,7 +111,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
 			tree2 = tree1;
 			tree1 = tmp;
 		}
-		diff_tree_sha1(tree1->sha1,
+		result = diff_tree_sha1(tree1->sha1,
 			       tree2->sha1,
 			       "", &opt->diffopt);
 		log_tree_diff_flush(opt);
@@ -118,7 +119,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
 	}
 
 	if (!read_stdin)
-		return 0;
+		return opt->diffopt.diff_exit_code ? result: 0;
 
 	if (opt->diffopt.detect_rename)
 		opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
@@ -130,8 +131,9 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
 			fputs(line, stdout);
 			fflush(stdout);
 		}
-		else
-			diff_tree_stdin(line);
+		else if (diff_tree_stdin(line)) {
+			result = 1;
+		}
 	}
-	return 0;
+	return opt->diffopt.diff_exit_code ? result: 0;
 }
diff --git a/builtin-diff.c b/builtin-diff.c
index 4efbb82..5e6265f 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -130,6 +130,7 @@ static int builtin_diff_tree(struct rev_info *revs,
 {
 	const unsigned char *(sha1[2]);
 	int swap = 0;
+	int result = 0;
 
 	if (argc > 1)
 		usage(builtin_diff_usage);
@@ -141,9 +142,9 @@ static int builtin_diff_tree(struct rev_info *revs,
 		swap = 1;
 	sha1[swap] = ent[0].item->sha1;
 	sha1[1-swap] = ent[1].item->sha1;
-	diff_tree_sha1(sha1[0], sha1[1], "", &revs->diffopt);
+	result = diff_tree_sha1(sha1[0], sha1[1], "", &revs->diffopt);
 	log_tree_diff_flush(revs);
-	return 0;
+	return result;
 }
 
 static int builtin_diff_combined(struct rev_info *revs,
diff --git a/diff-lib.c b/diff-lib.c
index 6abb981..f943b6f 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -170,8 +170,10 @@ static int handle_diff_files_args(struct rev_info *revs,
 		else if (!strcmp(argv[1], "--theirs"))
 			revs->max_count = 3;
 		else if (!strcmp(argv[1], "-n") ||
-				!strcmp(argv[1], "--no-index"))
+				!strcmp(argv[1], "--no-index")) {
 			revs->max_count = -2;
+			revs->diffopt.diff_exit_code = 1;
+		}
 		else if (!strcmp(argv[1], "-q"))
 			*silent = 1;
 		else
@@ -237,6 +239,7 @@ int setup_diff_no_index(struct rev_info *revs,
 			break;
 		} else if (i < argc - 3 && !strcmp(argv[i], "--no-index")) {
 			i = argc - 3;
+			revs->diffopt.diff_exit_code = 1;
 			break;
 		}
 	if (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) &&
@@ -309,6 +312,7 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
 
 int run_diff_files(struct rev_info *revs, int silent_on_removed)
 {
+	int result = 0;
 	int entries, i;
 	int diff_unmerged_stage = revs->max_count;
 
@@ -433,8 +437,9 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
 
 	}
 	diffcore_std(&revs->diffopt);
+	result = revs->diffopt.diff_exit_code && diff_queued_diff.nr ? 1: 0;
 	diff_flush(&revs->diffopt);
-	return 0;
+	return result;
 }
 
 /*
@@ -664,9 +669,10 @@ int run_diff_index(struct rev_info *revs, int cached)
 		return error("bad tree object %s", tree_name);
 	if (read_tree(tree, 1, revs->prune_data))
 		return error("unable to read tree object %s", tree_name);
-	ret = diff_cache(revs, active_cache, active_nr, revs->prune_data,
+	diff_cache(revs, active_cache, active_nr, revs->prune_data,
 			 cached, match_missing);
 	diffcore_std(&revs->diffopt);
+	ret = revs->diffopt.diff_exit_code && diff_queued_diff.nr ? 1: 0;
 	diff_flush(&revs->diffopt);
 	return ret;
 }
diff --git a/diff.c b/diff.c
index 954ca83..e2f91ed 100644
--- a/diff.c
+++ b/diff.c
@@ -2134,6 +2134,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
 		options->color_diff = options->color_diff_words = 1;
 	else if (!strcmp(arg, "--no-renames"))
 		options->detect_rename = 0;
+	else if (!strcmp(arg, "--exit-code"))
+		options->diff_exit_code = 1;
 	else
 		return 0;
 	return 1;
diff --git a/diff.h b/diff.h
index 4b435e8..cea61b5 100644
--- a/diff.h
+++ b/diff.h
@@ -56,7 +56,8 @@ struct diff_options {
 		 silent_on_remove:1,
 		 find_copies_harder:1,
 		 color_diff:1,
-		 color_diff_words:1;
+		 color_diff_words:1,
+		 diff_exit_code:1;
 	int context;
 	int break_opt;
 	int detect_rename;
diff --git a/t/t4017-diff-retval.sh b/t/t4017-diff-retval.sh
new file mode 100755
index 0000000..81a9393
--- /dev/null
+++ b/t/t4017-diff-retval.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+test_description='Return value of diffs'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	echo 1 >a &&
+	git add . &&
+	git commit -m first &&
+	echo 2 >b &&
+	git add . &&
+	git commit -a -m second
+'
+
+test_expect_failure 'git diff-tree HEAD^ HEAD' '
+	git diff-tree --exit-code HEAD^ HEAD
+'
+test_expect_failure 'echo HEAD | git diff-tree --stdin' '
+	echo $(git rev-parse HEAD) | git diff-tree --exit-code --stdin
+'
+test_expect_success 'git diff-tree HEAD HEAD' '
+	git diff-tree --exit-code HEAD HEAD
+'
+
+test_expect_success 'git diff-files' '
+	git diff-files --exit-code
+'
+
+test_expect_success 'git diff-index --cached HEAD' '
+	git diff-index --exit-code --cached HEAD
+'
+test_expect_failure 'git diff-index --cached HEAD^' '
+	git diff-index --exit-code --cached HEAD^
+'
+test_expect_failure 'git diff-index --cached HEAD^' '
+	echo 3 >c &&
+	git add . &&
+	git diff-index --exit-code --cached HEAD^
+'
+git commit -m 'third' >/dev/null
+test_expect_failure 'git diff-files' '
+	echo 3 >>c &&
+	git diff-files --exit-code
+'
+test_expect_failure 'git diff-index --cached HEAD' '
+	git update-index c &&
+	git diff-index --exit-code --cached HEAD
+'
+
+test_done
diff --git a/tree-diff.c b/tree-diff.c
index c827582..47c516f 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -160,6 +160,8 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree
 
 int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt)
 {
+	int result = 0;
+
 	while (t1->size | t2->size) {
 		if (opt->nr_paths && t1->size && !interesting(t1, base, opt)) {
 			update_tree_entry(t1);
@@ -170,29 +172,34 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, stru
 			continue;
 		}
 		if (!t1->size) {
+			result = 1;
 			show_entry(opt, "+", t2, base);
 			update_tree_entry(t2);
 			continue;
 		}
 		if (!t2->size) {
+			result = 1;
 			show_entry(opt, "-", t1, base);
 			update_tree_entry(t1);
 			continue;
 		}
 		switch (compare_tree_entry(t1, t2, base, opt)) {
 		case -1:
+			result = 1;
 			update_tree_entry(t1);
 			continue;
 		case 0:
 			update_tree_entry(t1);
-			/* Fallthrough */
+			update_tree_entry(t2);
+			continue;
 		case 1:
+			result = 1;
 			update_tree_entry(t2);
 			continue;
 		}
 		die("git-diff-tree: internal error");
 	}
-	return 0;
+	return opt->diff_exit_code ? result: 0;
 }
 
 int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const char *base, struct diff_options *opt)
-- 
1.5.0.3.545.g5d3ba


             reply	other threads:[~2007-03-14  0:17 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-03-14  0:17 Alex Riesen [this message]
2007-03-14  1:03 ` [PATCH] Allow git-diff exit with codes similar to diff(1) Johannes Schindelin
2007-03-14  1:20   ` Linus Torvalds
2007-03-14  1:23   ` Junio C Hamano
2007-03-14  1:13 ` Linus Torvalds
2007-03-14  1:18   ` Johannes Schindelin
2007-03-14  1:34     ` Linus Torvalds
2007-03-14  1:38       ` Johannes Schindelin
2007-03-14  8:37         ` Alex Riesen
2007-03-14 12:05           ` Johannes Schindelin
2007-03-14 12:26             ` Alex Riesen
2007-03-14 12:31               ` Johannes Schindelin
2007-03-15 12:49               ` Simon 'corecode' Schubert
2007-03-15 13:56                 ` Alex Riesen
2007-03-14  1:31   ` Junio C Hamano
2007-03-14  8:19     ` Alex Riesen
2007-03-14  8:58       ` Junio C Hamano
2007-03-14  9:06         ` Junio C Hamano
2007-03-14  9:07         ` Alex Riesen
2007-03-14  9:36           ` Junio C Hamano
2007-03-14  9:46             ` Alex Riesen
2007-03-14  4:56 ` Junio C Hamano
2007-03-14  8:28   ` Alex Riesen
2007-03-14  9:04     ` Junio C Hamano
2007-03-14 14:01       ` Alex Riesen
2007-03-14 16:14         ` Junio C Hamano
2007-03-14 16:33           ` Alex Riesen
2007-03-14 16:37             ` Junio C Hamano
2007-03-14 17:12               ` Alex Riesen
2007-03-14 17:20                 ` Junio C Hamano
2007-03-14 17:06             ` Junio C Hamano
2007-03-14 17:15               ` Alex Riesen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=81b0412b0703131717k7106ee1cg964628f0bda2c83e@mail.gmail.com \
    --to=raa.lkml@gmail.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=junkio@cox.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).