summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 803527f)
raw | patch | inline | side by side (parent: 803527f)
author | Alex Riesen <raa.lkml@gmail.com> | |
Wed, 14 Mar 2007 00:17:04 +0000 (01:17 +0100) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Wed, 14 Mar 2007 23:21:19 +0000 (16:21 -0700) |
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>
Signed-off-by: Junio C Hamano <junkio@cox.net>
programs will return 1 for differences, return 0 for equality, and
something else for errors.
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Documentation/diff-options.txt | patch | blob | history | |
builtin-diff-files.c | patch | blob | history | |
builtin-diff-index.c | patch | blob | history | |
builtin-diff-tree.c | patch | blob | history | |
builtin-diff.c | patch | blob | history | |
diff-lib.c | patch | blob | history | |
diff.c | patch | blob | history | |
diff.h | patch | blob | history | |
t/t4017-diff-retval.sh | [new file with mode: 0755] | patch | blob |
index d8696b7b36ff81f47214da9d7c4ec53142b97653..77a3f78dd75514667b77ae4e1dbbb3731b05a33d 100644 (file)
-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-files.c b/builtin-diff-files.c
index aec83384298042fc4509605299f82e82745ae675..6ba5077a2be6619f110280622cf46a7f4cfb8b01 100644 (file)
--- a/builtin-diff-files.c
+++ b/builtin-diff-files.c
{
struct rev_info rev;
int nongit = 0;
+ int result;
prefix = setup_git_directory_gently(&nongit);
init_revisions(&rev, prefix);
argc = setup_revisions(argc, argv, &rev, NULL);
if (!rev.diffopt.output_format)
rev.diffopt.output_format = DIFF_FORMAT_RAW;
- return run_diff_files_cmd(&rev, argc, argv);
+ result = run_diff_files_cmd(&rev, argc, argv);
+ return rev.diffopt.exit_with_status ? rev.diffopt.has_changes: result;
}
diff --git a/builtin-diff-index.c b/builtin-diff-index.c
index 083599d5c4c174cfab7c148428630534e4cd8174..d90eba95a6be17bd0486e0311c2657b1f69ab7d9 100644 (file)
--- a/builtin-diff-index.c
+++ b/builtin-diff-index.c
struct rev_info rev;
int cached = 0;
int i;
+ int result;
init_revisions(&rev, prefix);
git_config(git_default_config); /* no "diff" UI options */
perror("read_cache");
return -1;
}
- return run_diff_index(&rev, cached);
+ result = run_diff_index(&rev, cached);
+ return rev.diffopt.exit_with_status ? rev.diffopt.has_changes: result;
}
diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c
index 24cb2d7f84064d7833fa04f33aeca6eafc8b931d..0b591c87169ff4b8c2173bedb26d6ed1a8a84b68 100644 (file)
--- a/builtin-diff-tree.c
+++ b/builtin-diff-tree.c
}
if (!read_stdin)
- return 0;
+ return opt->diffopt.exit_with_status ?
+ opt->diffopt.has_changes: 0;
if (opt->diffopt.detect_rename)
opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
else
diff_tree_stdin(line);
}
- return 0;
+ return opt->diffopt.exit_with_status ? opt->diffopt.has_changes: 0;
}
diff --git a/builtin-diff.c b/builtin-diff.c
index 4efbb8237bd49e8717a42833b2d9b2db064b45ac..21d13f0b30359295b8385754fccb4bb71f995dba 100644 (file)
--- a/builtin-diff.c
+++ b/builtin-diff.c
const char *path = NULL;
struct blobinfo blob[2];
int nongit = 0;
+ int result = 0;
/*
* We could get N tree-ish in the rev.pending_objects list.
if (!ents) {
switch (blobs) {
case 0:
- return run_diff_files_cmd(&rev, argc, argv);
+ result = run_diff_files_cmd(&rev, argc, argv);
break;
case 1:
if (paths != 1)
usage(builtin_diff_usage);
- return builtin_diff_b_f(&rev, argc, argv, blob, path);
+ result = builtin_diff_b_f(&rev, argc, argv, blob, path);
break;
case 2:
if (paths)
usage(builtin_diff_usage);
- return builtin_diff_blobs(&rev, argc, argv, blob);
+ result = builtin_diff_blobs(&rev, argc, argv, blob);
break;
default:
usage(builtin_diff_usage);
else if (blobs)
usage(builtin_diff_usage);
else if (ents == 1)
- return builtin_diff_index(&rev, argc, argv);
+ result = builtin_diff_index(&rev, argc, argv);
else if (ents == 2)
- return builtin_diff_tree(&rev, argc, argv, ent);
+ result = builtin_diff_tree(&rev, argc, argv, ent);
else if ((ents == 3) && (ent[0].item->flags & UNINTERESTING)) {
/* diff A...B where there is one sane merge base between
* A and B. We have ent[0] == merge-base, ent[1] == A,
* and ent[2] == B. Show diff between the base and B.
*/
ent[1] = ent[2];
- return builtin_diff_tree(&rev, argc, argv, ent);
+ result = builtin_diff_tree(&rev, argc, argv, ent);
}
else
- return builtin_diff_combined(&rev, argc, argv,
+ result = builtin_diff_combined(&rev, argc, argv,
ent, ents);
- usage(builtin_diff_usage);
+ if (rev.diffopt.exit_with_status)
+ result = rev.diffopt.has_changes;
+ return result;
}
diff --git a/diff-lib.c b/diff-lib.c
index 6abb981534bf032d50e28eb3a14033c1b6546762..f9a1a10cc0319270358d658cd5e83bd5633fbf49 100644 (file)
--- a/diff-lib.c
+++ b/diff-lib.c
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.exit_with_status = 1;
+ }
else if (!strcmp(argv[1], "-q"))
*silent = 1;
else
break;
} else if (i < argc - 3 && !strcmp(argv[i], "--no-index")) {
i = argc - 3;
+ revs->diffopt.exit_with_status = 1;
break;
}
if (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) &&
index 954ca83e0b0c95f55c0287d2deeb4cab76153fe0..cc818011b93a13c269344819f5a0045f2558d550 100644 (file)
--- a/diff.c
+++ b/diff.c
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->exit_with_status = 1;
else
return 0;
return 1;
diffcore_order(options->orderfile);
diff_resolve_rename_copy();
diffcore_apply_filter(options->filter);
+ if (options->exit_with_status)
+ options->has_changes = !!diff_queued_diff.nr;
}
if (options->orderfile)
diffcore_order(options->orderfile);
diffcore_apply_filter(options->filter);
+ if (options->exit_with_status)
+ options->has_changes = !!diff_queued_diff.nr;
}
void diff_addremove(struct diff_options *options,
index 4b435e8b1933222da02f9e4cf2c28d2fef44d292..d13fc89768087427379749479d172da31bff95b9 100644 (file)
--- a/diff.h
+++ b/diff.h
silent_on_remove:1,
find_copies_harder:1,
color_diff:1,
- color_diff_words:1;
+ color_diff_words:1,
+ exit_with_status:1;
int context;
int break_opt;
int detect_rename;
const char *msg_sep;
const char *stat_sep;
long xdl_opts;
+ /* 0 - no differences; only meaningful if exit_with_status set */
+ int has_changes;
int stat_width;
int stat_name_width;
diff --git a/t/t4017-diff-retval.sh b/t/t4017-diff-retval.sh
--- /dev/null
+++ b/t/t4017-diff-retval.sh
@@ -0,0 +1,79 @@
+#!/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_success 'git diff-tree HEAD^ HEAD' '
+ git diff-tree --exit-code HEAD^ HEAD
+ test $? = 1
+'
+test_expect_success 'git diff-tree HEAD^ HEAD -- a' '
+ git diff-tree --exit-code HEAD^ HEAD -- a
+ test $? = 0
+'
+test_expect_success 'git diff-tree HEAD^ HEAD -- b' '
+ git diff-tree --exit-code HEAD^ HEAD -- b
+ test $? = 1
+'
+test_expect_success 'echo HEAD | git diff-tree --stdin' '
+ echo $(git rev-parse HEAD) | git diff-tree --exit-code --stdin
+ test $? = 1
+'
+test_expect_success 'git diff-tree HEAD HEAD' '
+ git diff-tree --exit-code HEAD HEAD
+ test $? = 0
+'
+test_expect_success 'git diff-files' '
+ git diff-files --exit-code
+ test $? = 0
+'
+test_expect_success 'git diff-index --cached HEAD' '
+ git diff-index --exit-code --cached HEAD
+ test $? = 0
+'
+test_expect_success 'git diff-index --cached HEAD^' '
+ git diff-index --exit-code --cached HEAD^
+ test $? = 1
+'
+test_expect_success 'git diff-index --cached HEAD^' '
+ echo text >>b &&
+ echo 3 >c &&
+ git add . && {
+ git diff-index --exit-code --cached HEAD^
+ test $? = 1
+ }
+'
+test_expect_success 'git diff-tree -Stext HEAD^ HEAD -- b' '
+ git commit -m "text in b" && {
+ git diff-tree -p --exit-code -Stext HEAD^ HEAD -- b
+ test $? = 1
+ }
+'
+test_expect_success 'git diff-tree -Snot-found HEAD^ HEAD -- b' '
+ git diff-tree -p --exit-code -Snot-found HEAD^ HEAD -- b
+ test $? = 0
+'
+test_expect_success 'git diff-files' '
+ echo 3 >>c && {
+ git diff-files --exit-code
+ test $? = 1
+ }
+'
+test_expect_success 'git diff-index --cached HEAD' '
+ git update-index c && {
+ git diff-index --exit-code --cached HEAD
+ test $? = 1
+ }
+'
+
+test_done