Skip to content

Commit

Permalink
Merge branch 'jk/combine-diff-cleanup' into seen
Browse files Browse the repository at this point in the history
* jk/combine-diff-cleanup:
  tree-diff: make list tail-passing more explicit
  tree-diff: simplify emit_path() list management
  tree-diff: use the name "tail" to refer to list tail
  tree-diff: drop list-tail argument to diff_tree_paths()
  combine-diff: drop public declaration of combine_diff_path_size()
  tree-diff: inline path_appendnew()
  tree-diff: pass whole path string to path_appendnew()
  tree-diff: drop path_appendnew() alloc optimization
  run_diff_files(): de-mystify the size of combine_diff_path struct
  diff: add a comment about combine_diff_path.parent.path
  combine-diff: use pointer for parent paths
  tree-diff: clear parent array in path_appendnew()
  combine-diff: add combine_diff_path_new()
  run_diff_files(): delay allocation of combine_diff_path
  • Loading branch information
gitster committed Jan 9, 2025
2 parents a48a7bd + 6979bf6 commit afa0870
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 184 deletions.
80 changes: 41 additions & 39 deletions combine-diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,31 +47,20 @@ static struct combine_diff_path *intersect_paths(

if (!n) {
for (i = 0; i < q->nr; i++) {
int len;
const char *path;
if (diff_unmodified_pair(q->queue[i]))
continue;
path = q->queue[i]->two->path;
len = strlen(path);
p = xmalloc(combine_diff_path_size(num_parent, len));
p->path = (char *) &(p->parent[num_parent]);
memcpy(p->path, path, len);
p->path[len] = 0;
p->next = NULL;
memset(p->parent, 0,
sizeof(p->parent[0]) * num_parent);

oidcpy(&p->oid, &q->queue[i]->two->oid);
p->mode = q->queue[i]->two->mode;
p = combine_diff_path_new(q->queue[i]->two->path,
strlen(q->queue[i]->two->path),
q->queue[i]->two->mode,
&q->queue[i]->two->oid,
num_parent);
oidcpy(&p->parent[n].oid, &q->queue[i]->one->oid);
p->parent[n].mode = q->queue[i]->one->mode;
p->parent[n].status = q->queue[i]->status;

if (combined_all_paths &&
filename_changed(p->parent[n].status)) {
strbuf_init(&p->parent[n].path, 0);
strbuf_addstr(&p->parent[n].path,
q->queue[i]->one->path);
p->parent[n].path = xstrdup(q->queue[i]->one->path);
}
*tail = p;
tail = &p->next;
Expand All @@ -92,9 +81,7 @@ static struct combine_diff_path *intersect_paths(
/* p->path not in q->queue[]; drop it */
*tail = p->next;
for (j = 0; j < num_parent; j++)
if (combined_all_paths &&
filename_changed(p->parent[j].status))
strbuf_release(&p->parent[j].path);
free(p->parent[j].path);
free(p);
continue;
}
Expand All @@ -110,8 +97,7 @@ static struct combine_diff_path *intersect_paths(
p->parent[n].status = q->queue[i]->status;
if (combined_all_paths &&
filename_changed(p->parent[n].status))
strbuf_addstr(&p->parent[n].path,
q->queue[i]->one->path);
p->parent[n].path = xstrdup(q->queue[i]->one->path);

tail = &p->next;
i++;
Expand Down Expand Up @@ -996,8 +982,9 @@ static void show_combined_header(struct combine_diff_path *elem,

if (rev->combined_all_paths) {
for (i = 0; i < num_parent; i++) {
char *path = filename_changed(elem->parent[i].status)
? elem->parent[i].path.buf : elem->path;
const char *path = elem->parent[i].path ?
elem->parent[i].path :
elem->path;
if (elem->parent[i].status == DIFF_STATUS_ADDED)
dump_quoted_path("--- ", "", "/dev/null",
line_prefix, c_meta, c_reset);
Expand Down Expand Up @@ -1278,12 +1265,10 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct re

for (i = 0; i < num_parent; i++)
if (rev->combined_all_paths) {
if (filename_changed(p->parent[i].status))
write_name_quoted(p->parent[i].path.buf, stdout,
inter_name_termination);
else
write_name_quoted(p->path, stdout,
inter_name_termination);
const char *path = p->parent[i].path ?
p->parent[i].path :
p->path;
write_name_quoted(path, stdout, inter_name_termination);
}
write_name_quoted(p->path, stdout, line_termination);
}
Expand Down Expand Up @@ -1443,22 +1428,19 @@ static struct combine_diff_path *find_paths_multitree(
{
int i, nparent = parents->nr;
const struct object_id **parents_oid;
struct combine_diff_path paths_head;
struct combine_diff_path *paths;
struct strbuf base;

ALLOC_ARRAY(parents_oid, nparent);
for (i = 0; i < nparent; i++)
parents_oid[i] = &parents->oid[i];

/* fake list head, so worker can assume it is non-NULL */
paths_head.next = NULL;

strbuf_init(&base, PATH_MAX);
diff_tree_paths(&paths_head, oid, parents_oid, nparent, &base, opt);
paths = diff_tree_paths(oid, parents_oid, nparent, &base, opt);

strbuf_release(&base);
free(parents_oid);
return paths_head.next;
return paths;
}

static int match_objfind(struct combine_diff_path *path,
Expand Down Expand Up @@ -1645,9 +1627,7 @@ void diff_tree_combined(const struct object_id *oid,
struct combine_diff_path *tmp = paths;
paths = paths->next;
for (i = 0; i < num_parent; i++)
if (rev->combined_all_paths &&
filename_changed(tmp->parent[i].status))
strbuf_release(&tmp->parent[i].path);
free(tmp->parent[i].path);
free(tmp);
}

Expand All @@ -1667,3 +1647,25 @@ void diff_tree_combined_merge(const struct commit *commit,
diff_tree_combined(&commit->object.oid, &parents, rev);
oid_array_clear(&parents);
}

struct combine_diff_path *combine_diff_path_new(const char *path,
size_t path_len,
unsigned int mode,
const struct object_id *oid,
size_t num_parents)
{
struct combine_diff_path *p;
size_t parent_len = st_mult(sizeof(p->parent[0]), num_parents);

p = xmalloc(st_add4(sizeof(*p), path_len, 1, parent_len));
p->path = (char *)&(p->parent[num_parents]);
memcpy(p->path, path, path_len);
p->path[path_len] = 0;
p->next = NULL;
p->mode = mode;
oidcpy(&p->oid, oid);

memset(p->parent, 0, parent_len);

return p;
}
36 changes: 12 additions & 24 deletions diff-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,21 +153,8 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
struct diff_filepair *pair;
unsigned int wt_mode = 0;
int num_compare_stages = 0;
size_t path_len;
struct stat st;

path_len = ce_namelen(ce);

dpath = xmalloc(combine_diff_path_size(5, path_len));
dpath->path = (char *) &(dpath->parent[5]);

dpath->next = NULL;
memcpy(dpath->path, ce->name, path_len);
dpath->path[path_len] = '\0';
oidclr(&dpath->oid, the_repository->hash_algo);
memset(&(dpath->parent[0]), 0,
sizeof(struct combine_diff_parent)*5);

changed = check_removed(ce, &st);
if (!changed)
wt_mode = ce_mode_from_stat(ce, st.st_mode);
Expand All @@ -178,7 +165,14 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
}
wt_mode = 0;
}
dpath->mode = wt_mode;

/*
* Allocate space for two parents, which will come from
* index stages #2 and #3, if present. Below we'll fill
* these from (stage - 2).
*/
dpath = combine_diff_path_new(ce->name, ce_namelen(ce),
wt_mode, null_oid(), 2);

while (i < entries) {
struct cache_entry *nce = istate->cache[i];
Expand Down Expand Up @@ -405,16 +399,10 @@ static int show_modified(struct rev_info *revs,
if (revs->combine_merges && !cached &&
(!oideq(oid, &old_entry->oid) || !oideq(&old_entry->oid, &new_entry->oid))) {
struct combine_diff_path *p;
int pathlen = ce_namelen(new_entry);

p = xmalloc(combine_diff_path_size(2, pathlen));
p->path = (char *) &p->parent[2];
p->next = NULL;
memcpy(p->path, new_entry->name, pathlen);
p->path[pathlen] = 0;
p->mode = mode;
oidclr(&p->oid, the_repository->hash_algo);
memset(p->parent, 0, 2 * sizeof(struct combine_diff_parent));

p = combine_diff_path_new(new_entry->name,
ce_namelen(new_entry),
mode, null_oid(), 2);
p->parent[0].status = DIFF_STATUS_MODIFIED;
p->parent[0].mode = new_entry->ce_mode;
oidcpy(&p->parent[0].oid, &new_entry->oid);
Expand Down
18 changes: 13 additions & 5 deletions diff.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ const char *diff_line_prefix(struct diff_options *);
extern const char mime_boundary_leader[];

struct combine_diff_path *diff_tree_paths(
struct combine_diff_path *p, const struct object_id *oid,
const struct object_id *oid,
const struct object_id **parents_oid, int nparent,
struct strbuf *base, struct diff_options *opt);
void diff_tree_oid(const struct object_id *old_oid,
Expand All @@ -480,12 +480,20 @@ struct combine_diff_path {
char status;
unsigned int mode;
struct object_id oid;
struct strbuf path;
/*
* This per-parent path is filled only when doing a combined
* diff with revs.combined_all_paths set, and only if the path
* differs from the post-image (e.g., a rename or copy).
* Otherwise it is left NULL.
*/
char *path;
} parent[FLEX_ARRAY];
};
#define combine_diff_path_size(n, l) \
st_add4(sizeof(struct combine_diff_path), (l), 1, \
st_mult(sizeof(struct combine_diff_parent), (n)))
struct combine_diff_path *combine_diff_path_new(const char *path,
size_t path_len,
unsigned int mode,
const struct object_id *oid,
size_t num_parents);

void show_combined_diff(struct combine_diff_path *elem, int num_parent,
struct rev_info *);
Expand Down
Loading

0 comments on commit afa0870

Please sign in to comment.