Skip to content

Commit 44aad15

Browse files
author
Junio C Hamano
committed
diff --stat: do not drop rename information.
When a verbatim rename or copy is detected, we did not show anything on the "diff --stat" for the filepair. This makes it to show the rename information. Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent a4d0cce commit 44aad15

File tree

1 file changed

+68
-9
lines changed

1 file changed

+68
-9
lines changed

diff-lib.c

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,56 @@ static int fn_out(void *priv, mmbuffer_t *mb, int nbuf)
195195
return 0;
196196
}
197197

198+
static char *pprint_rename(const char *a, const char *b)
199+
{
200+
const char *old = a;
201+
const char *new = b;
202+
char *name = NULL;
203+
int pfx_length, sfx_length;
204+
int len_a = strlen(a);
205+
int len_b = strlen(b);
206+
207+
/* Find common prefix */
208+
pfx_length = 0;
209+
while (*old && *new && *old == *new) {
210+
if (*old == '/')
211+
pfx_length = old - a + 1;
212+
old++;
213+
new++;
214+
}
215+
216+
/* Find common suffix */
217+
old = a + len_a;
218+
new = b + len_b;
219+
sfx_length = 0;
220+
while (a <= old && b <= new && *old == *new) {
221+
if (*old == '/')
222+
sfx_length = len_a - (old - a);
223+
old--;
224+
new--;
225+
}
226+
227+
/*
228+
* pfx{mid-a => mid-b}sfx
229+
* {pfx-a => pfx-b}sfx
230+
* pfx{sfx-a => sfx-b}
231+
* name-a => name-b
232+
*/
233+
if (pfx_length + sfx_length) {
234+
name = xmalloc(len_a + len_b - pfx_length - sfx_length + 7);
235+
sprintf(name, "%.*s{%.*s => %.*s}%s",
236+
pfx_length, a,
237+
len_a - pfx_length - sfx_length, a + pfx_length,
238+
len_b - pfx_length - sfx_length, b + pfx_length,
239+
a + len_a - sfx_length);
240+
}
241+
else {
242+
name = xmalloc(len_a + len_b + 5);
243+
sprintf(name, "%s => %s", a, b);
244+
}
245+
return name;
246+
}
247+
198248
struct diffstat_t {
199249
struct xdiff_emit_state xm;
200250

@@ -204,12 +254,14 @@ struct diffstat_t {
204254
char *name;
205255
unsigned is_unmerged:1;
206256
unsigned is_binary:1;
257+
unsigned is_renamed:1;
207258
unsigned int added, deleted;
208259
} **files;
209260
};
210261

211262
static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat,
212-
const char *name)
263+
const char *name_a,
264+
const char *name_b)
213265
{
214266
struct diffstat_file *x;
215267
x = xcalloc(sizeof (*x), 1);
@@ -219,7 +271,12 @@ static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat,
219271
diffstat->alloc * sizeof(x));
220272
}
221273
diffstat->files[diffstat->nr++] = x;
222-
x->name = strdup(name);
274+
if (name_b) {
275+
x->name = pprint_rename(name_a, name_b);
276+
x->is_renamed = 1;
277+
}
278+
else
279+
x->name = strdup(name_a);
223280
return x;
224281
}
225282

@@ -305,7 +362,8 @@ static void show_stats(struct diffstat_t* data)
305362
printf(" %s%-*s | Unmerged\n", prefix, len, name);
306363
goto free_diffstat_file;
307364
}
308-
else if (added + deleted == 0) {
365+
else if (!data->files[i]->is_renamed &&
366+
(added + deleted == 0)) {
309367
total_files--;
310368
goto free_diffstat_file;
311369
}
@@ -425,13 +483,14 @@ static void builtin_diff(const char *name_a,
425483
}
426484

427485
static void builtin_diffstat(const char *name_a, const char *name_b,
428-
struct diff_filespec *one, struct diff_filespec *two,
429-
struct diffstat_t *diffstat)
486+
struct diff_filespec *one,
487+
struct diff_filespec *two,
488+
struct diffstat_t *diffstat)
430489
{
431490
mmfile_t mf1, mf2;
432491
struct diffstat_file *data;
433492

434-
data = diffstat_add(diffstat, name_a ? name_a : name_b);
493+
data = diffstat_add(diffstat, name_a, name_b);
435494

436495
if (!one || !two) {
437496
data->is_unmerged = 1;
@@ -992,7 +1051,7 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
9921051
}
9931052

9941053
static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
995-
struct diffstat_t *diffstat)
1054+
struct diffstat_t *diffstat)
9961055
{
9971056
const char *name;
9981057
const char *other;
@@ -1374,7 +1433,7 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o)
13741433
}
13751434

13761435
static void diff_flush_stat(struct diff_filepair *p, struct diff_options *o,
1377-
struct diffstat_t *diffstat)
1436+
struct diffstat_t *diffstat)
13781437
{
13791438
if (diff_unmodified_pair(p))
13801439
return;
@@ -1559,7 +1618,7 @@ void diff_flush(struct diff_options *options)
15591618
for (i = 0; i < q->nr; i++) {
15601619
struct diff_filepair *p = q->queue[i];
15611620
flush_one_pair(p, DIFF_FORMAT_DIFFSTAT, options,
1562-
diffstat);
1621+
diffstat);
15631622
}
15641623
show_stats(diffstat);
15651624
free(diffstat);

0 commit comments

Comments
 (0)