show_entry(opt, "+", t2, base, baselen);
return 1;
}
- if (!opt->find_copies_harder && !hashcmp(sha1, sha2) && mode1 == mode2)
+ if (!DIFF_OPT_TST(opt, FIND_COPIES_HARDER) && !hashcmp(sha1, sha2) && mode1 == mode2)
return 0;
/*
return 0;
}
- if (opt->recursive && S_ISDIR(mode1)) {
+ if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode1)) {
int retval;
char *newbase = malloc_base(base, baselen, path1, pathlen1);
- if (opt->tree_in_recursive)
+ if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE))
opt->change(opt, mode1, mode2,
sha1, sha2, base, path1);
retval = diff_tree_sha1(sha1, sha2, newbase, opt);
const char *path;
const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode);
- if (opt->recursive && S_ISDIR(mode)) {
+ if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode)) {
enum object_type type;
int pathlen = tree_entry_len(path, sha1);
char *newbase = malloc_base(base, baselen, path, pathlen);
int baselen = strlen(base);
for (;;) {
- if (opt->quiet && opt->has_changes)
+ if (DIFF_OPT_TST(opt, QUIET) && DIFF_OPT_TST(opt, HAS_CHANGES))
break;
if (opt->nr_paths) {
skip_uninteresting(t1, base, baselen, opt);
static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt)
{
struct diff_options diff_opts;
- const char *paths[2];
+ struct diff_queue_struct *q = &diff_queued_diff;
+ struct diff_filepair *choice;
+ const char *paths[1];
int i;
+ /* Remove the file creation entry from the diff queue, and remember it */
+ choice = q->queue[0];
+ q->nr = 0;
+
diff_setup(&diff_opts);
- diff_opts.recursive = 1;
+ DIFF_OPT_SET(&diff_opts, RECURSIVE);
diff_opts.detect_rename = DIFF_DETECT_RENAME;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_opts.single_follow = opt->paths[0];
+ diff_opts.break_opt = opt->break_opt;
paths[0] = NULL;
diff_tree_setup_paths(paths, &diff_opts);
if (diff_setup_done(&diff_opts) < 0)
die("unable to set up diff options to follow renames");
diff_tree(t1, t2, base, &diff_opts);
diffcore_std(&diff_opts);
+ diff_tree_release_paths(&diff_opts);
- /* NOTE! Ignore the first diff! That was the old one! */
- for (i = 1; i < diff_queued_diff.nr; i++) {
- struct diff_filepair *p = diff_queued_diff.queue[i];
+ /* Go through the new set of filepairing, and see if we find a more interesting one */
+ for (i = 0; i < q->nr; i++) {
+ struct diff_filepair *p = q->queue[i];
/*
* Found a source? Not only do we use that for the new
- * diff_queued_diff, we also use that as the path in
+ * diff_queued_diff, we will also use that as the path in
* the future!
*/
if ((p->status == 'R' || p->status == 'C') && !strcmp(p->two->path, opt->paths[0])) {
- diff_queued_diff.queue[0] = p;
+ /* Switch the file-pairs around */
+ q->queue[i] = choice;
+ choice = p;
+
+ /* Update the path we use from now on.. */
+ diff_tree_release_paths(opt);
opt->paths[0] = xstrdup(p->one->path);
diff_tree_setup_paths(opt->paths, opt);
break;
}
/*
- * Then, ignore any but the first entry! It might be the old one,
- * or it might be the rename/copy we found
+ * Then, discard all the non-relevane file pairs...
+ */
+ for (i = 0; i < q->nr; i++) {
+ struct diff_filepair *p = q->queue[i];
+ diff_free_filepair(p);
+ }
+
+ /*
+ * .. and re-instate the one we want (which might be either the
+ * original one, or the rename/copy we found)
*/
- diff_queued_diff.nr = 1;
+ q->queue[0] = choice;
+ q->nr = 1;
}
int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const char *base, struct diff_options *opt)
init_tree_desc(&t1, tree1, size1);
init_tree_desc(&t2, tree2, size2);
retval = diff_tree(&t1, &t2, base, opt);
- if (opt->follow_renames && diff_might_be_rename()) {
+ if (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);