aboutsummaryrefslogtreecommitdiffstats
path: root/tree-diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'tree-diff.c')
-rw-r--r--tree-diff.c65
1 files changed, 33 insertions, 32 deletions
diff --git a/tree-diff.c b/tree-diff.c
index fe2e466ac1..69031d7cba 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -21,7 +21,9 @@
ALLOC_ARRAY((x), nr); \
} while(0)
#define FAST_ARRAY_FREE(x, nr) do { \
- if ((nr) > 2) \
+ if ((nr) <= 2) \
+ xalloca_free((x)); \
+ else \
free((x)); \
} while(0)
@@ -29,9 +31,9 @@ static struct combine_diff_path *ll_diff_tree_paths(
struct combine_diff_path *p, const struct object_id *oid,
const struct object_id **parents_oid, int nparent,
struct strbuf *base, struct diff_options *opt);
-static int ll_diff_tree_oid(const struct object_id *old_oid,
- const struct object_id *new_oid,
- struct strbuf *base, struct diff_options *opt);
+static void ll_diff_tree_oid(const struct object_id *old_oid,
+ const struct object_id *new_oid,
+ struct strbuf *base, struct diff_options *opt);
/*
* Compare two tree entries, taking into account only path/S_ISDIR(mode),
@@ -161,7 +163,7 @@ static struct combine_diff_path *path_appendnew(struct combine_diff_path *last,
memcpy(p->path + base->len, path, pathlen);
p->path[len] = 0;
p->mode = mode;
- oidcpy(&p->oid, oid ? oid : &null_oid);
+ oidcpy(&p->oid, oid ? oid : null_oid());
return p;
}
@@ -181,7 +183,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p,
struct tree_desc *t, struct tree_desc *tp,
int imin)
{
- unsigned mode;
+ unsigned short mode;
const char *path;
const struct object_id *oid;
int pathlen;
@@ -239,11 +241,11 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p,
DIFF_STATUS_ADDED;
if (tpi_valid) {
- oid_i = tp[i].entry.oid;
+ oid_i = &tp[i].entry.oid;
mode_i = tp[i].entry.mode;
}
else {
- oid_i = &null_oid;
+ oid_i = null_oid();
mode_i = 0;
}
@@ -280,7 +282,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p,
/* same rule as in emitthis */
int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ);
- parents_oid[i] = tpi_valid ? tp[i].entry.oid : NULL;
+ parents_oid[i] = tpi_valid ? &tp[i].entry.oid : NULL;
}
strbuf_add(base, path, pathlen);
@@ -299,7 +301,8 @@ static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
enum interesting match;
while (t->size) {
- match = tree_entry_interesting(&t->entry, base, 0, &opt->pathspec);
+ match = tree_entry_interesting(opt->repo->index, &t->entry,
+ base, 0, &opt->pathspec);
if (match) {
if (match == all_entries_not_interesting)
t->size = 0;
@@ -421,8 +424,8 @@ static struct combine_diff_path *ll_diff_tree_paths(
* diff_tree_oid(parent, commit) )
*/
for (i = 0; i < nparent; ++i)
- tptree[i] = fill_tree_descriptor(&tp[i], parents_oid[i]);
- ttree = fill_tree_descriptor(&t, oid);
+ tptree[i] = fill_tree_descriptor(opt->repo, &tp[i], parents_oid[i]);
+ ttree = fill_tree_descriptor(opt->repo, &t, oid);
/* Enable recursion indefinitely */
opt->pathspec.recursive = opt->flags.recursive;
@@ -433,6 +436,9 @@ static struct combine_diff_path *ll_diff_tree_paths(
if (diff_can_quit_early(opt))
break;
+ if (opt->max_changes && diff_queued_diff.nr > opt->max_changes)
+ break;
+
if (opt->pathspec.nr) {
skip_uninteresting(&t, base, opt);
for (i = 0; i < nparent; i++)
@@ -491,7 +497,7 @@ static struct combine_diff_path *ll_diff_tree_paths(
continue;
/* diff(t,pi) != ΓΈ */
- if (oidcmp(t.entry.oid, tp[i].entry.oid) ||
+ if (!oideq(&t.entry.oid, &tp[i].entry.oid) ||
(t.entry.mode != tp[i].entry.mode))
continue;
@@ -557,9 +563,7 @@ struct combine_diff_path *diff_tree_paths(
* free pre-allocated last element, if any
* (see path_appendnew() for details about why)
*/
- if (p->next) {
- FREE_AND_NULL(p->next);
- }
+ FREE_AND_NULL(p->next);
return p;
}
@@ -599,15 +603,14 @@ static void try_to_follow_renames(const struct object_id *old_oid,
* about dry-run mode and returns wildcard info.
*/
if (opt->pathspec.has_wildcard)
- die("BUG:%s:%d: wildcards are not supported",
- __FILE__, __LINE__);
+ BUG("wildcards are not supported");
#endif
/* Remove the file creation entry from the diff queue, and remember it */
choice = q->queue[0];
q->nr = 0;
- diff_setup(&diff_opts);
+ repo_diff_setup(opt->repo, &diff_opts);
diff_opts.flags.recursive = 1;
diff_opts.flags.find_copies_harder = 1;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
@@ -674,9 +677,9 @@ static void try_to_follow_renames(const struct object_id *old_oid,
q->nr = 1;
}
-static int ll_diff_tree_oid(const struct object_id *old_oid,
- const struct object_id *new_oid,
- struct strbuf *base, struct diff_options *opt)
+static void ll_diff_tree_oid(const struct object_id *old_oid,
+ const struct object_id *new_oid,
+ struct strbuf *base, struct diff_options *opt)
{
struct combine_diff_path phead, *p;
pathchange_fn_t pathchange_old = opt->pathchange;
@@ -692,29 +695,27 @@ static int ll_diff_tree_oid(const struct object_id *old_oid,
}
opt->pathchange = pathchange_old;
- return 0;
}
-int diff_tree_oid(const struct object_id *old_oid,
- const struct object_id *new_oid,
- const char *base_str, struct diff_options *opt)
+void diff_tree_oid(const struct object_id *old_oid,
+ const struct object_id *new_oid,
+ const char *base_str, struct diff_options *opt)
{
struct strbuf base;
- int retval;
strbuf_init(&base, PATH_MAX);
strbuf_addstr(&base, base_str);
- retval = ll_diff_tree_oid(old_oid, new_oid, &base, opt);
+ ll_diff_tree_oid(old_oid, new_oid, &base, opt);
if (!*base_str && opt->flags.follow_renames && diff_might_be_rename())
try_to_follow_renames(old_oid, new_oid, &base, opt);
strbuf_release(&base);
-
- return retval;
}
-int diff_root_tree_oid(const struct object_id *new_oid, const char *base, struct diff_options *opt)
+void diff_root_tree_oid(const struct object_id *new_oid,
+ const char *base,
+ struct diff_options *opt)
{
- return diff_tree_oid(NULL, new_oid, base, opt);
+ diff_tree_oid(NULL, new_oid, base, opt);
}