Skip to content

Commit bd3a97a

Browse files
committed
Merge branch 'jc/maint-follow-rename-fix'
* jc/maint-follow-rename-fix: log: test for regression introduced in v1.7.2-rc0~103^2~2 diff --follow: do call diffcore_std() as necessary diff --follow: do not waste cycles while recursing
2 parents 6b5005c + 6511312 commit bd3a97a

File tree

5 files changed

+41
-18
lines changed

5 files changed

+41
-18
lines changed

diff.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4073,33 +4073,32 @@ void diffcore_fix_diff_index(struct diff_options *options)
40734073

40744074
void diffcore_std(struct diff_options *options)
40754075
{
4076-
/* We never run this function more than one time, because the
4077-
* rename/copy detection logic can only run once.
4078-
*/
4079-
if (diff_queued_diff.run)
4080-
return;
4081-
40824076
if (options->skip_stat_unmatch)
40834077
diffcore_skip_stat_unmatch(options);
4084-
if (options->break_opt != -1)
4085-
diffcore_break(options->break_opt);
4086-
if (options->detect_rename)
4087-
diffcore_rename(options);
4088-
if (options->break_opt != -1)
4089-
diffcore_merge_broken();
4078+
if (!options->found_follow) {
4079+
/* See try_to_follow_renames() in tree-diff.c */
4080+
if (options->break_opt != -1)
4081+
diffcore_break(options->break_opt);
4082+
if (options->detect_rename)
4083+
diffcore_rename(options);
4084+
if (options->break_opt != -1)
4085+
diffcore_merge_broken();
4086+
}
40904087
if (options->pickaxe)
40914088
diffcore_pickaxe(options->pickaxe, options->pickaxe_opts);
40924089
if (options->orderfile)
40934090
diffcore_order(options->orderfile);
4094-
diff_resolve_rename_copy();
4091+
if (!options->found_follow)
4092+
/* See try_to_follow_renames() in tree-diff.c */
4093+
diff_resolve_rename_copy();
40954094
diffcore_apply_filter(options->filter);
40964095

40974096
if (diff_queued_diff.nr && !DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
40984097
DIFF_OPT_SET(options, HAS_CHANGES);
40994098
else
41004099
DIFF_OPT_CLR(options, HAS_CHANGES);
41014100

4102-
diff_queued_diff.run = 1;
4101+
options->found_follow = 0;
41034102
}
41044103

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

diff.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ struct diff_options {
127127
/* this is set by diffcore for DIFF_FORMAT_PATCH */
128128
int found_changes;
129129

130+
/* to support internal diff recursion by --follow hack*/
131+
int found_follow;
132+
130133
FILE *file;
131134
int close_file;
132135

diffcore.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,11 @@ struct diff_queue_struct {
9191
struct diff_filepair **queue;
9292
int alloc;
9393
int nr;
94-
int run;
9594
};
9695
#define DIFF_QUEUE_CLEAR(q) \
9796
do { \
9897
(q)->queue = NULL; \
9998
(q)->nr = (q)->alloc = 0; \
100-
(q)->run = 0; \
10199
} while (0)
102100

103101
extern struct diff_queue_struct diff_queued_diff;

t/t4202-log.sh

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,5 +436,17 @@ test_expect_success 'log.decorate configuration' '
436436
437437
'
438438

439-
test_done
439+
test_expect_success 'show added path under "--follow -M"' '
440+
# This tests for a regression introduced in v1.7.2-rc0~103^2~2
441+
test_create_repo regression &&
442+
(
443+
cd regression &&
444+
test_commit needs-another-commit &&
445+
test_commit foo.bar &&
446+
git log -M --follow -p foo.bar.t &&
447+
git log -M --follow --stat foo.bar.t &&
448+
git log -M --follow --name-only foo.bar.t
449+
)
450+
'
440451

452+
test_done

tree-diff.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
359359
diff_tree_release_paths(&diff_opts);
360360

361361
/* Go through the new set of filepairing, and see if we find a more interesting one */
362+
opt->found_follow = 0;
362363
for (i = 0; i < q->nr; i++) {
363364
struct diff_filepair *p = q->queue[i];
364365

@@ -376,6 +377,16 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
376377
diff_tree_release_paths(opt);
377378
opt->paths[0] = xstrdup(p->one->path);
378379
diff_tree_setup_paths(opt->paths, opt);
380+
381+
/*
382+
* The caller expects us to return a set of vanilla
383+
* filepairs to let a later call to diffcore_std()
384+
* it makes to sort the renames out (among other
385+
* things), but we already have found renames
386+
* ourselves; signal diffcore_std() not to muck with
387+
* rename information.
388+
*/
389+
opt->found_follow = 1;
379390
break;
380391
}
381392
}
@@ -412,7 +423,7 @@ int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const cha
412423
init_tree_desc(&t1, tree1, size1);
413424
init_tree_desc(&t2, tree2, size2);
414425
retval = diff_tree(&t1, &t2, base, opt);
415-
if (DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename()) {
426+
if (!*base && DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename()) {
416427
init_tree_desc(&t1, tree1, size1);
417428
init_tree_desc(&t2, tree2, size2);
418429
try_to_follow_renames(&t1, &t2, base, opt);

0 commit comments

Comments
 (0)