aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--diff.c25
-rwxr-xr-xt/t4013-diff-various.sh2
-rw-r--r--t/t4013/diff.diff_--dirstat-by-file_initial_rearrange3
3 files changed, 25 insertions, 5 deletions
diff --git a/diff.c b/diff.c
index 3fd9e0c70..4f5270b8d 100644
--- a/diff.c
+++ b/diff.c
@@ -1539,9 +1539,27 @@ static void show_dirstat(struct diff_options *options)
struct diff_filepair *p = q->queue[i];
const char *name;
unsigned long copied, added, damage;
+ int content_changed;
name = p->one->path ? p->one->path : p->two->path;
+ if (p->one->sha1_valid && p->two->sha1_valid)
+ content_changed = hashcmp(p->one->sha1, p->two->sha1);
+ else
+ content_changed = 1;
+
+ if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE)) {
+ /*
+ * In --dirstat-by-file mode, we don't really need to
+ * look at the actual file contents at all.
+ * The fact that the SHA1 changed is enough for us to
+ * add this file to the list of results
+ * (with each file contributing equal damage).
+ */
+ damage = content_changed ? 1 : 0;
+ goto found_damage;
+ }
+
if (DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
diff_populate_filespec(p->one, 0);
diff_populate_filespec(p->two, 0);
@@ -1564,14 +1582,11 @@ static void show_dirstat(struct diff_options *options)
/*
* Original minus copied is the removed material,
* added is the new material. They are both damages
- * made to the preimage. In --dirstat-by-file mode, count
- * damaged files, not damaged lines. This is done by
- * counting only a single damaged line per file.
+ * made to the preimage.
*/
damage = (p->one->size - copied) + added;
- if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE) && damage > 0)
- damage = 1;
+found_damage:
ALLOC_GROW(dir.files, dir.nr + 1, dir.alloc);
dir.files[dir.nr].name = name;
dir.files[dir.nr].changed = damage;
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 3b1b392a5..6428a905a 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -302,6 +302,8 @@ diff master master^ side
diff --dirstat master~1 master~2
# --dirstat doesn't notice changes that simply rearrange existing lines
diff --dirstat initial rearrange
+# ...but --dirstat-by-file does notice changes that only rearrange lines
+diff --dirstat-by-file initial rearrange
EOF
test_expect_success 'log -S requires an argument' '
diff --git a/t/t4013/diff.diff_--dirstat-by-file_initial_rearrange b/t/t4013/diff.diff_--dirstat-by-file_initial_rearrange
new file mode 100644
index 000000000..e48e33f67
--- /dev/null
+++ b/t/t4013/diff.diff_--dirstat-by-file_initial_rearrange
@@ -0,0 +1,3 @@
+$ git diff --dirstat-by-file initial rearrange
+ 100.0% dir/
+$