Skip to content

Commit d98a509

Browse files
committed
Merge branch 'jh/dirstat'
* jh/dirstat: --dirstat: In case of renames, use target filename instead of source filename Teach --dirstat not to completely ignore rearranged lines within a file --dirstat-by-file: Make it faster and more correct --dirstat: Describe non-obvious differences relative to --stat or regular diff
2 parents 11c3e2b + 2ca8671 commit d98a509

8 files changed

+81
-12
lines changed

Documentation/diff-options.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ endif::git-format-patch[]
7272
a cut-off percent (3% by default) are not shown. The cut-off percent
7373
can be set with `--dirstat=<limit>`. Changes in a child directory are not
7474
counted for the parent directory, unless `--cumulative` is used.
75+
+
76+
Note that the `--dirstat` option computes the changes while ignoring
77+
the amount of pure code movements within a file. In other words,
78+
rearranging lines in a file is not counted as much as other changes.
7579

7680
--dirstat-by-file[=<limit>]::
7781
Same as `--dirstat`, but counts changed files instead of lines.

diff.c

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,8 +1538,36 @@ static void show_dirstat(struct diff_options *options)
15381538
struct diff_filepair *p = q->queue[i];
15391539
const char *name;
15401540
unsigned long copied, added, damage;
1541+
int content_changed;
15411542

1542-
name = p->one->path ? p->one->path : p->two->path;
1543+
name = p->two->path ? p->two->path : p->one->path;
1544+
1545+
if (p->one->sha1_valid && p->two->sha1_valid)
1546+
content_changed = hashcmp(p->one->sha1, p->two->sha1);
1547+
else
1548+
content_changed = 1;
1549+
1550+
if (!content_changed) {
1551+
/*
1552+
* The SHA1 has not changed, so pre-/post-content is
1553+
* identical. We can therefore skip looking at the
1554+
* file contents altogether.
1555+
*/
1556+
damage = 0;
1557+
goto found_damage;
1558+
}
1559+
1560+
if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE)) {
1561+
/*
1562+
* In --dirstat-by-file mode, we don't really need to
1563+
* look at the actual file contents at all.
1564+
* The fact that the SHA1 changed is enough for us to
1565+
* add this file to the list of results
1566+
* (with each file contributing equal damage).
1567+
*/
1568+
damage = 1;
1569+
goto found_damage;
1570+
}
15431571

15441572
if (DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
15451573
diff_populate_filespec(p->one, 0);
@@ -1563,14 +1591,18 @@ static void show_dirstat(struct diff_options *options)
15631591
/*
15641592
* Original minus copied is the removed material,
15651593
* added is the new material. They are both damages
1566-
* made to the preimage. In --dirstat-by-file mode, count
1567-
* damaged files, not damaged lines. This is done by
1568-
* counting only a single damaged line per file.
1594+
* made to the preimage.
1595+
* If the resulting damage is zero, we know that
1596+
* diffcore_count_changes() considers the two entries to
1597+
* be identical, but since content_changed is true, we
1598+
* know that there must have been _some_ kind of change,
1599+
* so we force all entries to have damage > 0.
15691600
*/
15701601
damage = (p->one->size - copied) + added;
1571-
if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE) && damage > 0)
1602+
if (!damage)
15721603
damage = 1;
15731604

1605+
found_damage:
15741606
ALLOC_GROW(dir.files, dir.nr + 1, dir.alloc);
15751607
dir.files[dir.nr].name = name;
15761608
dir.files[dir.nr].changed = damage;

t/t4013-diff-various.sh

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,31 @@ test_expect_success setup '
8080
8181
git config log.showroot false &&
8282
git commit --amend &&
83+
84+
GIT_AUTHOR_DATE="2006-06-26 00:06:00 +0000" &&
85+
GIT_COMMITTER_DATE="2006-06-26 00:06:00 +0000" &&
86+
export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&
87+
git checkout -b rearrange initial &&
88+
for i in B A; do echo $i; done >dir/sub &&
89+
git add dir/sub &&
90+
git commit -m "Rearranged lines in dir/sub" &&
91+
git checkout master &&
92+
8393
git show-branch
8494
'
8595

8696
: <<\EOF
8797
! [initial] Initial
8898
* [master] Merge branch 'side'
89-
! [side] Side
90-
---
91-
- [master] Merge branch 'side'
92-
*+ [side] Side
93-
* [master^] Second
94-
+*+ [initial] Initial
99+
! [rearrange] Rearranged lines in dir/sub
100+
! [side] Side
101+
----
102+
+ [rearrange] Rearranged lines in dir/sub
103+
- [master] Merge branch 'side'
104+
* + [side] Side
105+
* [master^] Third
106+
* [master~2] Second
107+
+*++ [initial] Initial
95108
EOF
96109

97110
V=`git version | sed -e 's/^git version //' -e 's/\./\\./g'`
@@ -287,6 +300,8 @@ diff --no-index --name-status -- dir2 dir
287300
diff --no-index dir dir3
288301
diff master master^ side
289302
diff --dirstat master~1 master~2
303+
diff --dirstat initial rearrange
304+
diff --dirstat-by-file initial rearrange
290305
EOF
291306

292307
test_expect_success 'log -S requires an argument' '
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
$ git diff --dirstat-by-file initial rearrange
2+
100.0% dir/
3+
$
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
$ git diff --dirstat initial rearrange
2+
100.0% dir/
3+
$

t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
$ git format-patch --stdout --cover-letter -n initial..master^
22
From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001
33
From: C O Mitter <[email protected]>
4-
Date: Mon, 26 Jun 2006 00:05:00 +0000
4+
Date: Mon, 26 Jun 2006 00:06:00 +0000
55
Subject: [DIFFERENT_PREFIX 0/2] *** SUBJECT HERE ***
66

77
*** BLURB HERE ***

t/t4013/diff.log_--decorate=full_--all

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
$ git log --decorate=full --all
2+
commit cd4e72fd96faed3f0ba949dc42967430374e2290 (refs/heads/rearrange)
3+
Author: A U Thor <[email protected]>
4+
Date: Mon Jun 26 00:06:00 2006 +0000
5+
6+
Rearranged lines in dir/sub
7+
28
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, refs/heads/master)
39
Merge: 9a6d494 c7a2ab9
410
Author: A U Thor <[email protected]>

t/t4013/diff.log_--decorate_--all

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
$ git log --decorate --all
2+
commit cd4e72fd96faed3f0ba949dc42967430374e2290 (rearrange)
3+
Author: A U Thor <[email protected]>
4+
Date: Mon Jun 26 00:06:00 2006 +0000
5+
6+
Rearranged lines in dir/sub
7+
28
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, master)
39
Merge: 9a6d494 c7a2ab9
410
Author: A U Thor <[email protected]>

0 commit comments

Comments
 (0)