diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 228ccaf..12ad048 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -185,5 +185,9 @@
--no-ext-diff::
Disallow external diff drivers.
+--show-touched::
+ Display the "diff --git" message for files whose modification
+ timestamps have changed, even if the contents don't differ.
+
For more detailed explanation on these common options, see also
link:diffcore.html[diffcore documentation].
diff --git a/diff.c b/diff.c
index a5fc56b..e1112e5 100644
--- a/diff.c
+++ b/diff.c
@@ -1260,6 +1260,9 @@ static const char *diff_funcname_pattern(struct diff_filespec *one)
return NULL;
}
+/* The message that gets printed at the top of a file's diffs */
+#define DIFF_MESSAGE_FORMAT_STRING "%sdiff --git %s %s%s\n"
+
static void builtin_diff(const char *name_a,
const char *name_b,
struct diff_filespec *one,
@@ -1268,6 +1271,7 @@ static void builtin_diff(const char *name_a,
struct diff_options *o,
int complete_rewrite)
{
+ char *diff_message;
mmfile_t mf1, mf2;
const char *lbl[2];
char *a_one, *b_two;@@ -1278,25 +1282,50 @@ static void builtin_diff(const char *name_a,
b_two = quote_two("b/", name_b + (*name_b == '/'));
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
- printf("%sdiff --git %s %s%s\n", set, a_one, b_two, reset);
+
+ /*
+ * Generate the "diff --git" status message. By default we only
+ * show it if we have a difference to display, but the user can
+ * optionally choose to show it for all files that we examine for
+ * content differences (e.g. because their timestamps have changed.)
+ */
+ diff_message = xmalloc(strlen(set) + strlen(reset) +
+ strlen(a_one) + strlen(b_two) +
+ sizeof(DIFF_MESSAGE_FORMAT_STRING));
+ sprintf(diff_message, DIFF_MESSAGE_FORMAT_STRING,
+ set, a_one, b_two, reset);
+ if (o->show_touched) {
+ fputs(diff_message, stdout);
+ *diff_message = '\0';
+ }
+
if (lbl[0][0] == '/') {
/* /dev/null */
- printf("%snew file mode %06o%s\n", set, two->mode, reset);
+ printf("%s%snew file mode %06o%s\n",
+ diff_message, set, two->mode, reset);
+ *diff_message = '\0';
if (xfrm_msg && xfrm_msg[0])
printf("%s%s%s\n", set, xfrm_msg, reset);
}
else if (lbl[1][0] == '/') {
- printf("%sdeleted file mode %06o%s\n", set, one->mode, reset);
+ printf("%s%sdeleted file mode %06o%s\n",
+ diff_message, set, one->mode, reset);
+ *diff_message = '\0';
if (xfrm_msg && xfrm_msg[0])
printf("%s%s%s\n", set, xfrm_msg, reset);
}
else {
if (one->mode != two->mode) {
- printf("%sold mode %06o%s\n", set, one->mode, reset);
+ printf("%s%sold mode %06o%s\n",
+ diff_message, set, one->mode, reset);
printf("%snew mode %06o%s\n", set, two->mode, reset);
+ *diff_message = '\0';
+ }
+ if (xfrm_msg && xfrm_msg[0]) {
+ printf("%s%s%s%s\n",
+ diff_message, set, xfrm_msg, reset);
+ *diff_message = '\0';
}
- if (xfrm_msg && xfrm_msg[0])
- printf("%s%s%s\n", set, xfrm_msg, reset);
/*
* we do not run diff between different kind
* of objects.@@ -1304,6 +1333,8 @@ static void builtin_diff(const char *name_a,
if ((one->mode ^ two->mode) & S_IFMT)
goto free_ab_and_return;
if (complete_rewrite) {
+ fputs(diff_message, stdout);
+ *diff_message = '\0';
emit_rewrite_diff(name_a, name_b, one, two,
o->color_diff);
o->found_changes = 1;@@ -1372,6 +1403,7 @@ static void builtin_diff(const char *name_a,
diff_free_filespec_data(two);
free(a_one);
free(b_two);
+ free(diff_message);
return;
}
@@ -2381,6 +2413,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
options->allow_external = 1;
else if (!strcmp(arg, "--no-ext-diff"))
options->allow_external = 0;
+ else if (!strcmp(arg, "--show-touched"))
+ options->show_touched = 1;
else
return 0;
return 1;
diff --git a/diff.h b/diff.h
index 9fd6d44..e172ecf 100644
--- a/diff.h
+++ b/diff.h
@@ -61,7 +61,8 @@ struct diff_options {
has_changes:1,
quiet:1,
allow_external:1,
- exit_with_status:1;
+ exit_with_status:1,
+ show_touched:1;
int context;
int break_opt;
int detect_rename;diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh
index c6d1369..910c6cc 100755
--- a/t/t4011-diff-symlink.sh
+++ b/t/t4011-diff-symlink.sh
@@ -60,7 +60,7 @@ test_expect_success \
'diff identical, but newly created symlink' \
'sleep 3 &&
ln -s xyzzy frotz &&
- git diff-index -M -p $tree > current &&
+ git diff-index --show-touched -M -p $tree > current &&
compare_diff_patch current expected'
cat > expected << EOFdiff --git a/t/t4021-diff-untouched.sh b/t/t4021-diff-untouched.sh
new file mode 100755
index 0000000..a8153e0
--- /dev/null
+++ b/t/t4021-diff-untouched.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Johannes Schindelin
+#
+
+test_description='Test display and suppression of unmodified files.
+
+'
+. ./test-lib.sh
+. ../diff-lib.sh
+
+touch empty
+
+test_expect_success 'no output when no changes' '
+
+ echo foobar > file1 &&
+ chmod 644 file1 &&
+ git add file1 &&
+ git commit -m "initial commit" &&
+ git diff > current &&
+ compare_diff_patch current empty
+'
+
+test_expect_success 'no output when file touched' '
+
+ sleep 1 &&
+ touch file1 &&
+ git diff > current &&
+ compare_diff_patch current empty
+'
+
+cat > expected << EOF
+diff --git a/file1 b/file1
+EOF
+
+test_expect_success 'output when --show-touched is used' '
+
+ git diff --show-touched > current &&
+ compare_diff_patch current expected
+'
+
+test_expect_success 'no output when index updated with touched file' '
+
+ git add file1 &&
+ git diff --cached > current &&
+ compare_diff_patch current empty
+'
+
+cat > expected << EOF
+diff --git a/file1 b/file1
+old mode 100644
+new mode 100755
+EOF
+
+test_expect_success 'output when mode is changed' '
+
+ chmod 755 file1 &&
+ git diff > current &&
+ compare_diff_patch current expected
+'
+test_done
--
1.5.3.rc2.4.g726f9