Skip to content

Commit 82c531b

Browse files
committed
Merge branch 'by/log-follow'
* by/log-follow: tests: rename duplicate t4205 Make git log --follow find copies among unmodified files. Make diffcore_std only can run once before a diff_flush Add a macro DIFF_QUEUE_CLEAR.
2 parents 82e7ee7 + 9feeaa2 commit 82c531b

File tree

8 files changed

+82
-18
lines changed

8 files changed

+82
-18
lines changed

Documentation/git-log.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ include::diff-options.txt[]
5757
commits, and doesn't limit diff for those commits.
5858

5959
--follow::
60-
Continue listing the history of a file beyond renames.
60+
Continue listing the history of a file beyond renames/copies.
6161

6262
--log-size::
6363
Before the log message print out its size in bytes. Intended

diff.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2600,6 +2600,7 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
26002600
void diff_setup(struct diff_options *options)
26012601
{
26022602
memset(options, 0, sizeof(*options));
2603+
memset(&diff_queued_diff, 0, sizeof(diff_queued_diff));
26032604

26042605
options->file = stdout;
26052606

@@ -3541,8 +3542,7 @@ int diff_flush_patch_id(struct diff_options *options, unsigned char *sha1)
35413542
diff_free_filepair(q->queue[i]);
35423543

35433544
free(q->queue);
3544-
q->queue = NULL;
3545-
q->nr = q->alloc = 0;
3545+
DIFF_QUEUE_CLEAR(q);
35463546

35473547
return result;
35483548
}
@@ -3670,8 +3670,7 @@ void diff_flush(struct diff_options *options)
36703670
diff_free_filepair(q->queue[i]);
36713671
free_queue:
36723672
free(q->queue);
3673-
q->queue = NULL;
3674-
q->nr = q->alloc = 0;
3673+
DIFF_QUEUE_CLEAR(q);
36753674
if (options->close_file)
36763675
fclose(options->file);
36773676

@@ -3693,8 +3692,7 @@ static void diffcore_apply_filter(const char *filter)
36933692
int i;
36943693
struct diff_queue_struct *q = &diff_queued_diff;
36953694
struct diff_queue_struct outq;
3696-
outq.queue = NULL;
3697-
outq.nr = outq.alloc = 0;
3695+
DIFF_QUEUE_CLEAR(&outq);
36983696

36993697
if (!filter)
37003698
return;
@@ -3762,8 +3760,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
37623760
int i;
37633761
struct diff_queue_struct *q = &diff_queued_diff;
37643762
struct diff_queue_struct outq;
3765-
outq.queue = NULL;
3766-
outq.nr = outq.alloc = 0;
3763+
DIFF_QUEUE_CLEAR(&outq);
37673764

37683765
for (i = 0; i < q->nr; i++) {
37693766
struct diff_filepair *p = q->queue[i];
@@ -3824,6 +3821,12 @@ void diffcore_fix_diff_index(struct diff_options *options)
38243821

38253822
void diffcore_std(struct diff_options *options)
38263823
{
3824+
/* We never run this function more than one time, because the
3825+
* rename/copy detection logic can only run once.
3826+
*/
3827+
if (diff_queued_diff.run)
3828+
return;
3829+
38273830
if (options->skip_stat_unmatch)
38283831
diffcore_skip_stat_unmatch(options);
38293832
if (options->break_opt != -1)
@@ -3843,6 +3846,8 @@ void diffcore_std(struct diff_options *options)
38433846
DIFF_OPT_SET(options, HAS_CHANGES);
38443847
else
38453848
DIFF_OPT_CLR(options, HAS_CHANGES);
3849+
3850+
diff_queued_diff.run = 1;
38463851
}
38473852

38483853
int diff_result_code(struct diff_options *opt, int status)

diffcore-break.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ void diffcore_break(int break_score)
162162
if (!merge_score)
163163
merge_score = DEFAULT_MERGE_SCORE;
164164

165-
outq.nr = outq.alloc = 0;
166-
outq.queue = NULL;
165+
DIFF_QUEUE_CLEAR(&outq);
167166

168167
for (i = 0; i < q->nr; i++) {
169168
struct diff_filepair *p = q->queue[i];
@@ -256,8 +255,7 @@ void diffcore_merge_broken(void)
256255
struct diff_queue_struct outq;
257256
int i, j;
258257

259-
outq.nr = outq.alloc = 0;
260-
outq.queue = NULL;
258+
DIFF_QUEUE_CLEAR(&outq);
261259

262260
for (i = 0; i < q->nr; i++) {
263261
struct diff_filepair *p = q->queue[i];

diffcore-pickaxe.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ void diffcore_pickaxe(const char *needle, int opts)
5555
int i, has_changes;
5656
regex_t regex, *regexp = NULL;
5757
struct diff_queue_struct outq;
58-
outq.queue = NULL;
59-
outq.nr = outq.alloc = 0;
58+
DIFF_QUEUE_CLEAR(&outq);
6059

6160
if (opts & DIFF_PICKAXE_REGEX) {
6261
int err;

diffcore-rename.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,8 +569,7 @@ void diffcore_rename(struct diff_options *options)
569569
/* At this point, we have found some renames and copies and they
570570
* are recorded in rename_dst. The original list is still in *q.
571571
*/
572-
outq.queue = NULL;
573-
outq.nr = outq.alloc = 0;
572+
DIFF_QUEUE_CLEAR(&outq);
574573
for (i = 0; i < q->nr; i++) {
575574
struct diff_filepair *p = q->queue[i];
576575
struct diff_filepair *pair_to_free = NULL;

diffcore.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,14 @@ struct diff_queue_struct {
9191
struct diff_filepair **queue;
9292
int alloc;
9393
int nr;
94+
int run;
9495
};
96+
#define DIFF_QUEUE_CLEAR(q) \
97+
do { \
98+
(q)->queue = NULL; \
99+
(q)->nr = (q)->alloc = 0; \
100+
(q)->run = 0; \
101+
} while(0);
95102

96103
extern struct diff_queue_struct diff_queued_diff;
97104
extern struct diff_filepair *diff_queue(struct diff_queue_struct *,

t/t4206-log-follow-harder-copies.sh

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2010 Bo Yang
4+
#
5+
6+
test_description='Test --follow should always find copies hard in git log.
7+
8+
'
9+
. ./test-lib.sh
10+
. "$TEST_DIRECTORY"/diff-lib.sh
11+
12+
echo >path0 'Line 1
13+
Line 2
14+
Line 3
15+
'
16+
17+
test_expect_success \
18+
'add a file path0 and commit.' \
19+
'git add path0 &&
20+
git commit -m "Add path0"'
21+
22+
echo >path0 'New line 1
23+
New line 2
24+
New line 3
25+
'
26+
test_expect_success \
27+
'Change path0.' \
28+
'git add path0 &&
29+
git commit -m "Change path0"'
30+
31+
cat <path0 >path1
32+
test_expect_success \
33+
'copy path0 to path1.' \
34+
'git add path1 &&
35+
git commit -m "Copy path1 from path0"'
36+
37+
test_expect_success \
38+
'find the copy path0 -> path1 harder' \
39+
'git log --follow --name-status --pretty="format:%s" path1 > current'
40+
41+
cat >expected <<\EOF
42+
Copy path1 from path0
43+
C100 path0 path1
44+
45+
Change path0
46+
M path0
47+
48+
Add path0
49+
A path0
50+
EOF
51+
52+
test_expect_success \
53+
'validate the output.' \
54+
'compare_diff_patch current expected'
55+
56+
test_done

tree-diff.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
346346

347347
diff_setup(&diff_opts);
348348
DIFF_OPT_SET(&diff_opts, RECURSIVE);
349-
diff_opts.detect_rename = DIFF_DETECT_RENAME;
349+
DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);
350350
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
351351
diff_opts.single_follow = opt->paths[0];
352352
diff_opts.break_opt = opt->break_opt;

0 commit comments

Comments
 (0)