summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2010-08-20 19:53:09 (GMT)
committerJunio C Hamano <gitster@pobox.com>2010-08-20 19:53:09 (GMT)
commit55c6e6dc38188d27b4ec0315db93d6c40725cdd6 (patch)
treeede040677f6ad505638458f178d9527600ee7b4e
parent16bfbe6352e90b87de26effe5ce120ab74ebafc7 (diff)
parent65113121a50cd765033d51204213c817832c59cf (diff)
downloadgit-55c6e6dc38188d27b4ec0315db93d6c40725cdd6.zip
git-55c6e6dc38188d27b4ec0315db93d6c40725cdd6.tar.gz
git-55c6e6dc38188d27b4ec0315db93d6c40725cdd6.tar.bz2
Merge branch 'jc/maint-follow-rename-fix' into maint
* 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
-rw-r--r--diff.c27
-rw-r--r--diff.h3
-rw-r--r--diffcore.h2
-rwxr-xr-xt/t4202-log.sh14
-rw-r--r--tree-diff.c13
5 files changed, 41 insertions, 18 deletions
diff --git a/diff.c b/diff.c
index bf65892..9300492 100644
--- a/diff.c
+++ b/diff.c
@@ -4064,25 +4064,24 @@ void diffcore_fix_diff_index(struct diff_options *options)
void diffcore_std(struct diff_options *options)
{
- /* We never run this function more than one time, because the
- * rename/copy detection logic can only run once.
- */
- if (diff_queued_diff.run)
- return;
-
if (options->skip_stat_unmatch)
diffcore_skip_stat_unmatch(options);
- if (options->break_opt != -1)
- diffcore_break(options->break_opt);
- if (options->detect_rename)
- diffcore_rename(options);
- if (options->break_opt != -1)
- diffcore_merge_broken();
+ if (!options->found_follow) {
+ /* See try_to_follow_renames() in tree-diff.c */
+ if (options->break_opt != -1)
+ diffcore_break(options->break_opt);
+ if (options->detect_rename)
+ diffcore_rename(options);
+ if (options->break_opt != -1)
+ diffcore_merge_broken();
+ }
if (options->pickaxe)
diffcore_pickaxe(options->pickaxe, options->pickaxe_opts);
if (options->orderfile)
diffcore_order(options->orderfile);
- diff_resolve_rename_copy();
+ if (!options->found_follow)
+ /* See try_to_follow_renames() in tree-diff.c */
+ diff_resolve_rename_copy();
diffcore_apply_filter(options->filter);
if (diff_queued_diff.nr && !DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
@@ -4090,7 +4089,7 @@ void diffcore_std(struct diff_options *options)
else
DIFF_OPT_CLR(options, HAS_CHANGES);
- diff_queued_diff.run = 1;
+ options->found_follow = 0;
}
int diff_result_code(struct diff_options *opt, int status)
diff --git a/diff.h b/diff.h
index 063d10a..6fff024 100644
--- a/diff.h
+++ b/diff.h
@@ -126,6 +126,9 @@ struct diff_options {
/* this is set by diffcore for DIFF_FORMAT_PATCH */
int found_changes;
+ /* to support internal diff recursion by --follow hack*/
+ int found_follow;
+
FILE *file;
int close_file;
diff --git a/diffcore.h b/diffcore.h
index 05ebc11..8b3241a 100644
--- a/diffcore.h
+++ b/diffcore.h
@@ -91,13 +91,11 @@ struct diff_queue_struct {
struct diff_filepair **queue;
int alloc;
int nr;
- int run;
};
#define DIFF_QUEUE_CLEAR(q) \
do { \
(q)->queue = NULL; \
(q)->nr = (q)->alloc = 0; \
- (q)->run = 0; \
} while (0)
extern struct diff_queue_struct diff_queued_diff;
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 2230e60..ead204e 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -436,5 +436,17 @@ test_expect_success 'log.decorate configuration' '
'
-test_done
+test_expect_success 'show added path under "--follow -M"' '
+ # This tests for a regression introduced in v1.7.2-rc0~103^2~2
+ test_create_repo regression &&
+ (
+ cd regression &&
+ test_commit needs-another-commit &&
+ test_commit foo.bar &&
+ git log -M --follow -p foo.bar.t &&
+ git log -M --follow --stat foo.bar.t &&
+ git log -M --follow --name-only foo.bar.t
+ )
+'
+test_done
diff --git a/tree-diff.c b/tree-diff.c
index 1fb3e94..cd659c6 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -359,6 +359,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
diff_tree_release_paths(&diff_opts);
/* Go through the new set of filepairing, and see if we find a more interesting one */
+ opt->found_follow = 0;
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
@@ -376,6 +377,16 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
diff_tree_release_paths(opt);
opt->paths[0] = xstrdup(p->one->path);
diff_tree_setup_paths(opt->paths, opt);
+
+ /*
+ * The caller expects us to return a set of vanilla
+ * filepairs to let a later call to diffcore_std()
+ * it makes to sort the renames out (among other
+ * things), but we already have found renames
+ * ourselves; signal diffcore_std() not to muck with
+ * rename information.
+ */
+ opt->found_follow = 1;
break;
}
}
@@ -412,7 +423,7 @@ int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const cha
init_tree_desc(&t1, tree1, size1);
init_tree_desc(&t2, tree2, size2);
retval = diff_tree(&t1, &t2, base, opt);
- if (DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename()) {
+ if (!*base && DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename()) {
init_tree_desc(&t1, tree1, size1);
init_tree_desc(&t2, tree2, size2);
try_to_follow_renames(&t1, &t2, base, opt);