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.
This commit is contained in:
commit
82c531b3b6
@ -57,7 +57,7 @@ include::diff-options.txt[]
|
|||||||
commits, and doesn't limit diff for those commits.
|
commits, and doesn't limit diff for those commits.
|
||||||
|
|
||||||
--follow::
|
--follow::
|
||||||
Continue listing the history of a file beyond renames.
|
Continue listing the history of a file beyond renames/copies.
|
||||||
|
|
||||||
--log-size::
|
--log-size::
|
||||||
Before the log message print out its size in bytes. Intended
|
Before the log message print out its size in bytes. Intended
|
||||||
|
21
diff.c
21
diff.c
@ -2600,6 +2600,7 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
|
|||||||
void diff_setup(struct diff_options *options)
|
void diff_setup(struct diff_options *options)
|
||||||
{
|
{
|
||||||
memset(options, 0, sizeof(*options));
|
memset(options, 0, sizeof(*options));
|
||||||
|
memset(&diff_queued_diff, 0, sizeof(diff_queued_diff));
|
||||||
|
|
||||||
options->file = stdout;
|
options->file = stdout;
|
||||||
|
|
||||||
@ -3541,8 +3542,7 @@ int diff_flush_patch_id(struct diff_options *options, unsigned char *sha1)
|
|||||||
diff_free_filepair(q->queue[i]);
|
diff_free_filepair(q->queue[i]);
|
||||||
|
|
||||||
free(q->queue);
|
free(q->queue);
|
||||||
q->queue = NULL;
|
DIFF_QUEUE_CLEAR(q);
|
||||||
q->nr = q->alloc = 0;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -3670,8 +3670,7 @@ void diff_flush(struct diff_options *options)
|
|||||||
diff_free_filepair(q->queue[i]);
|
diff_free_filepair(q->queue[i]);
|
||||||
free_queue:
|
free_queue:
|
||||||
free(q->queue);
|
free(q->queue);
|
||||||
q->queue = NULL;
|
DIFF_QUEUE_CLEAR(q);
|
||||||
q->nr = q->alloc = 0;
|
|
||||||
if (options->close_file)
|
if (options->close_file)
|
||||||
fclose(options->file);
|
fclose(options->file);
|
||||||
|
|
||||||
@ -3693,8 +3692,7 @@ static void diffcore_apply_filter(const char *filter)
|
|||||||
int i;
|
int i;
|
||||||
struct diff_queue_struct *q = &diff_queued_diff;
|
struct diff_queue_struct *q = &diff_queued_diff;
|
||||||
struct diff_queue_struct outq;
|
struct diff_queue_struct outq;
|
||||||
outq.queue = NULL;
|
DIFF_QUEUE_CLEAR(&outq);
|
||||||
outq.nr = outq.alloc = 0;
|
|
||||||
|
|
||||||
if (!filter)
|
if (!filter)
|
||||||
return;
|
return;
|
||||||
@ -3762,8 +3760,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
|
|||||||
int i;
|
int i;
|
||||||
struct diff_queue_struct *q = &diff_queued_diff;
|
struct diff_queue_struct *q = &diff_queued_diff;
|
||||||
struct diff_queue_struct outq;
|
struct diff_queue_struct outq;
|
||||||
outq.queue = NULL;
|
DIFF_QUEUE_CLEAR(&outq);
|
||||||
outq.nr = outq.alloc = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < q->nr; i++) {
|
for (i = 0; i < q->nr; i++) {
|
||||||
struct diff_filepair *p = q->queue[i];
|
struct diff_filepair *p = q->queue[i];
|
||||||
@ -3824,6 +3821,12 @@ void diffcore_fix_diff_index(struct diff_options *options)
|
|||||||
|
|
||||||
void diffcore_std(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)
|
if (options->skip_stat_unmatch)
|
||||||
diffcore_skip_stat_unmatch(options);
|
diffcore_skip_stat_unmatch(options);
|
||||||
if (options->break_opt != -1)
|
if (options->break_opt != -1)
|
||||||
@ -3843,6 +3846,8 @@ void diffcore_std(struct diff_options *options)
|
|||||||
DIFF_OPT_SET(options, HAS_CHANGES);
|
DIFF_OPT_SET(options, HAS_CHANGES);
|
||||||
else
|
else
|
||||||
DIFF_OPT_CLR(options, HAS_CHANGES);
|
DIFF_OPT_CLR(options, HAS_CHANGES);
|
||||||
|
|
||||||
|
diff_queued_diff.run = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int diff_result_code(struct diff_options *opt, int status)
|
int diff_result_code(struct diff_options *opt, int status)
|
||||||
|
@ -162,8 +162,7 @@ void diffcore_break(int break_score)
|
|||||||
if (!merge_score)
|
if (!merge_score)
|
||||||
merge_score = DEFAULT_MERGE_SCORE;
|
merge_score = DEFAULT_MERGE_SCORE;
|
||||||
|
|
||||||
outq.nr = outq.alloc = 0;
|
DIFF_QUEUE_CLEAR(&outq);
|
||||||
outq.queue = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < q->nr; i++) {
|
for (i = 0; i < q->nr; i++) {
|
||||||
struct diff_filepair *p = q->queue[i];
|
struct diff_filepair *p = q->queue[i];
|
||||||
@ -256,8 +255,7 @@ void diffcore_merge_broken(void)
|
|||||||
struct diff_queue_struct outq;
|
struct diff_queue_struct outq;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
outq.nr = outq.alloc = 0;
|
DIFF_QUEUE_CLEAR(&outq);
|
||||||
outq.queue = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < q->nr; i++) {
|
for (i = 0; i < q->nr; i++) {
|
||||||
struct diff_filepair *p = q->queue[i];
|
struct diff_filepair *p = q->queue[i];
|
||||||
|
@ -55,8 +55,7 @@ void diffcore_pickaxe(const char *needle, int opts)
|
|||||||
int i, has_changes;
|
int i, has_changes;
|
||||||
regex_t regex, *regexp = NULL;
|
regex_t regex, *regexp = NULL;
|
||||||
struct diff_queue_struct outq;
|
struct diff_queue_struct outq;
|
||||||
outq.queue = NULL;
|
DIFF_QUEUE_CLEAR(&outq);
|
||||||
outq.nr = outq.alloc = 0;
|
|
||||||
|
|
||||||
if (opts & DIFF_PICKAXE_REGEX) {
|
if (opts & DIFF_PICKAXE_REGEX) {
|
||||||
int err;
|
int err;
|
||||||
|
@ -569,8 +569,7 @@ void diffcore_rename(struct diff_options *options)
|
|||||||
/* At this point, we have found some renames and copies and they
|
/* At this point, we have found some renames and copies and they
|
||||||
* are recorded in rename_dst. The original list is still in *q.
|
* are recorded in rename_dst. The original list is still in *q.
|
||||||
*/
|
*/
|
||||||
outq.queue = NULL;
|
DIFF_QUEUE_CLEAR(&outq);
|
||||||
outq.nr = outq.alloc = 0;
|
|
||||||
for (i = 0; i < q->nr; i++) {
|
for (i = 0; i < q->nr; i++) {
|
||||||
struct diff_filepair *p = q->queue[i];
|
struct diff_filepair *p = q->queue[i];
|
||||||
struct diff_filepair *pair_to_free = NULL;
|
struct diff_filepair *pair_to_free = NULL;
|
||||||
|
@ -91,7 +91,14 @@ struct diff_queue_struct {
|
|||||||
struct diff_filepair **queue;
|
struct diff_filepair **queue;
|
||||||
int alloc;
|
int alloc;
|
||||||
int nr;
|
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;
|
extern struct diff_queue_struct diff_queued_diff;
|
||||||
extern struct diff_filepair *diff_queue(struct diff_queue_struct *,
|
extern struct diff_filepair *diff_queue(struct diff_queue_struct *,
|
||||||
|
56
t/t4206-log-follow-harder-copies.sh
Executable file
56
t/t4206-log-follow-harder-copies.sh
Executable file
@ -0,0 +1,56 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2010 Bo Yang
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='Test --follow should always find copies hard in git log.
|
||||||
|
|
||||||
|
'
|
||||||
|
. ./test-lib.sh
|
||||||
|
. "$TEST_DIRECTORY"/diff-lib.sh
|
||||||
|
|
||||||
|
echo >path0 'Line 1
|
||||||
|
Line 2
|
||||||
|
Line 3
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'add a file path0 and commit.' \
|
||||||
|
'git add path0 &&
|
||||||
|
git commit -m "Add path0"'
|
||||||
|
|
||||||
|
echo >path0 'New line 1
|
||||||
|
New line 2
|
||||||
|
New line 3
|
||||||
|
'
|
||||||
|
test_expect_success \
|
||||||
|
'Change path0.' \
|
||||||
|
'git add path0 &&
|
||||||
|
git commit -m "Change path0"'
|
||||||
|
|
||||||
|
cat <path0 >path1
|
||||||
|
test_expect_success \
|
||||||
|
'copy path0 to path1.' \
|
||||||
|
'git add path1 &&
|
||||||
|
git commit -m "Copy path1 from path0"'
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'find the copy path0 -> path1 harder' \
|
||||||
|
'git log --follow --name-status --pretty="format:%s" path1 > current'
|
||||||
|
|
||||||
|
cat >expected <<\EOF
|
||||||
|
Copy path1 from path0
|
||||||
|
C100 path0 path1
|
||||||
|
|
||||||
|
Change path0
|
||||||
|
M path0
|
||||||
|
|
||||||
|
Add path0
|
||||||
|
A path0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'validate the output.' \
|
||||||
|
'compare_diff_patch current expected'
|
||||||
|
|
||||||
|
test_done
|
@ -346,7 +346,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
|
|||||||
|
|
||||||
diff_setup(&diff_opts);
|
diff_setup(&diff_opts);
|
||||||
DIFF_OPT_SET(&diff_opts, RECURSIVE);
|
DIFF_OPT_SET(&diff_opts, RECURSIVE);
|
||||||
diff_opts.detect_rename = DIFF_DETECT_RENAME;
|
DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);
|
||||||
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
|
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
|
||||||
diff_opts.single_follow = opt->paths[0];
|
diff_opts.single_follow = opt->paths[0];
|
||||||
diff_opts.break_opt = opt->break_opt;
|
diff_opts.break_opt = opt->break_opt;
|
||||||
|
Loading…
Reference in New Issue
Block a user