Skip to content

Commit c43136d

Browse files
committed
Merge branch 'jk/combine-diff-cleanup'
Code clean-up for code paths around combined diff. * 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
2 parents caf1742 + 6979bf6 commit c43136d

File tree

4 files changed

+102
-184
lines changed

4 files changed

+102
-184
lines changed

combine-diff.c

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -47,31 +47,20 @@ static struct combine_diff_path *intersect_paths(
4747

4848
if (!n) {
4949
for (i = 0; i < q->nr; i++) {
50-
int len;
51-
const char *path;
5250
if (diff_unmodified_pair(q->queue[i]))
5351
continue;
54-
path = q->queue[i]->two->path;
55-
len = strlen(path);
56-
p = xmalloc(combine_diff_path_size(num_parent, len));
57-
p->path = (char *) &(p->parent[num_parent]);
58-
memcpy(p->path, path, len);
59-
p->path[len] = 0;
60-
p->next = NULL;
61-
memset(p->parent, 0,
62-
sizeof(p->parent[0]) * num_parent);
63-
64-
oidcpy(&p->oid, &q->queue[i]->two->oid);
65-
p->mode = q->queue[i]->two->mode;
52+
p = combine_diff_path_new(q->queue[i]->two->path,
53+
strlen(q->queue[i]->two->path),
54+
q->queue[i]->two->mode,
55+
&q->queue[i]->two->oid,
56+
num_parent);
6657
oidcpy(&p->parent[n].oid, &q->queue[i]->one->oid);
6758
p->parent[n].mode = q->queue[i]->one->mode;
6859
p->parent[n].status = q->queue[i]->status;
6960

7061
if (combined_all_paths &&
7162
filename_changed(p->parent[n].status)) {
72-
strbuf_init(&p->parent[n].path, 0);
73-
strbuf_addstr(&p->parent[n].path,
74-
q->queue[i]->one->path);
63+
p->parent[n].path = xstrdup(q->queue[i]->one->path);
7564
}
7665
*tail = p;
7766
tail = &p->next;
@@ -92,9 +81,7 @@ static struct combine_diff_path *intersect_paths(
9281
/* p->path not in q->queue[]; drop it */
9382
*tail = p->next;
9483
for (j = 0; j < num_parent; j++)
95-
if (combined_all_paths &&
96-
filename_changed(p->parent[j].status))
97-
strbuf_release(&p->parent[j].path);
84+
free(p->parent[j].path);
9885
free(p);
9986
continue;
10087
}
@@ -110,8 +97,7 @@ static struct combine_diff_path *intersect_paths(
11097
p->parent[n].status = q->queue[i]->status;
11198
if (combined_all_paths &&
11299
filename_changed(p->parent[n].status))
113-
strbuf_addstr(&p->parent[n].path,
114-
q->queue[i]->one->path);
100+
p->parent[n].path = xstrdup(q->queue[i]->one->path);
115101

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

997983
if (rev->combined_all_paths) {
998984
for (i = 0; i < num_parent; i++) {
999-
char *path = filename_changed(elem->parent[i].status)
1000-
? elem->parent[i].path.buf : elem->path;
985+
const char *path = elem->parent[i].path ?
986+
elem->parent[i].path :
987+
elem->path;
1001988
if (elem->parent[i].status == DIFF_STATUS_ADDED)
1002989
dump_quoted_path("--- ", "", "/dev/null",
1003990
line_prefix, c_meta, c_reset);
@@ -1278,12 +1265,10 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct re
12781265

12791266
for (i = 0; i < num_parent; i++)
12801267
if (rev->combined_all_paths) {
1281-
if (filename_changed(p->parent[i].status))
1282-
write_name_quoted(p->parent[i].path.buf, stdout,
1283-
inter_name_termination);
1284-
else
1285-
write_name_quoted(p->path, stdout,
1286-
inter_name_termination);
1268+
const char *path = p->parent[i].path ?
1269+
p->parent[i].path :
1270+
p->path;
1271+
write_name_quoted(path, stdout, inter_name_termination);
12871272
}
12881273
write_name_quoted(p->path, stdout, line_termination);
12891274
}
@@ -1443,22 +1428,19 @@ static struct combine_diff_path *find_paths_multitree(
14431428
{
14441429
int i, nparent = parents->nr;
14451430
const struct object_id **parents_oid;
1446-
struct combine_diff_path paths_head;
1431+
struct combine_diff_path *paths;
14471432
struct strbuf base;
14481433

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

1453-
/* fake list head, so worker can assume it is non-NULL */
1454-
paths_head.next = NULL;
1455-
14561438
strbuf_init(&base, PATH_MAX);
1457-
diff_tree_paths(&paths_head, oid, parents_oid, nparent, &base, opt);
1439+
paths = diff_tree_paths(oid, parents_oid, nparent, &base, opt);
14581440

14591441
strbuf_release(&base);
14601442
free(parents_oid);
1461-
return paths_head.next;
1443+
return paths;
14621444
}
14631445

14641446
static int match_objfind(struct combine_diff_path *path,
@@ -1645,9 +1627,7 @@ void diff_tree_combined(const struct object_id *oid,
16451627
struct combine_diff_path *tmp = paths;
16461628
paths = paths->next;
16471629
for (i = 0; i < num_parent; i++)
1648-
if (rev->combined_all_paths &&
1649-
filename_changed(tmp->parent[i].status))
1650-
strbuf_release(&tmp->parent[i].path);
1630+
free(tmp->parent[i].path);
16511631
free(tmp);
16521632
}
16531633

@@ -1667,3 +1647,25 @@ void diff_tree_combined_merge(const struct commit *commit,
16671647
diff_tree_combined(&commit->object.oid, &parents, rev);
16681648
oid_array_clear(&parents);
16691649
}
1650+
1651+
struct combine_diff_path *combine_diff_path_new(const char *path,
1652+
size_t path_len,
1653+
unsigned int mode,
1654+
const struct object_id *oid,
1655+
size_t num_parents)
1656+
{
1657+
struct combine_diff_path *p;
1658+
size_t parent_len = st_mult(sizeof(p->parent[0]), num_parents);
1659+
1660+
p = xmalloc(st_add4(sizeof(*p), path_len, 1, parent_len));
1661+
p->path = (char *)&(p->parent[num_parents]);
1662+
memcpy(p->path, path, path_len);
1663+
p->path[path_len] = 0;
1664+
p->next = NULL;
1665+
p->mode = mode;
1666+
oidcpy(&p->oid, oid);
1667+
1668+
memset(p->parent, 0, parent_len);
1669+
1670+
return p;
1671+
}

diff-lib.c

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -153,21 +153,8 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
153153
struct diff_filepair *pair;
154154
unsigned int wt_mode = 0;
155155
int num_compare_stages = 0;
156-
size_t path_len;
157156
struct stat st;
158157

159-
path_len = ce_namelen(ce);
160-
161-
dpath = xmalloc(combine_diff_path_size(5, path_len));
162-
dpath->path = (char *) &(dpath->parent[5]);
163-
164-
dpath->next = NULL;
165-
memcpy(dpath->path, ce->name, path_len);
166-
dpath->path[path_len] = '\0';
167-
oidclr(&dpath->oid, the_repository->hash_algo);
168-
memset(&(dpath->parent[0]), 0,
169-
sizeof(struct combine_diff_parent)*5);
170-
171158
changed = check_removed(ce, &st);
172159
if (!changed)
173160
wt_mode = ce_mode_from_stat(ce, st.st_mode);
@@ -178,7 +165,14 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
178165
}
179166
wt_mode = 0;
180167
}
181-
dpath->mode = wt_mode;
168+
169+
/*
170+
* Allocate space for two parents, which will come from
171+
* index stages #2 and #3, if present. Below we'll fill
172+
* these from (stage - 2).
173+
*/
174+
dpath = combine_diff_path_new(ce->name, ce_namelen(ce),
175+
wt_mode, null_oid(), 2);
182176

183177
while (i < entries) {
184178
struct cache_entry *nce = istate->cache[i];
@@ -405,16 +399,10 @@ static int show_modified(struct rev_info *revs,
405399
if (revs->combine_merges && !cached &&
406400
(!oideq(oid, &old_entry->oid) || !oideq(&old_entry->oid, &new_entry->oid))) {
407401
struct combine_diff_path *p;
408-
int pathlen = ce_namelen(new_entry);
409-
410-
p = xmalloc(combine_diff_path_size(2, pathlen));
411-
p->path = (char *) &p->parent[2];
412-
p->next = NULL;
413-
memcpy(p->path, new_entry->name, pathlen);
414-
p->path[pathlen] = 0;
415-
p->mode = mode;
416-
oidclr(&p->oid, the_repository->hash_algo);
417-
memset(p->parent, 0, 2 * sizeof(struct combine_diff_parent));
402+
403+
p = combine_diff_path_new(new_entry->name,
404+
ce_namelen(new_entry),
405+
mode, null_oid(), 2);
418406
p->parent[0].status = DIFF_STATUS_MODIFIED;
419407
p->parent[0].mode = new_entry->ce_mode;
420408
oidcpy(&p->parent[0].oid, &new_entry->oid);

diff.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ const char *diff_line_prefix(struct diff_options *);
462462
extern const char mime_boundary_leader[];
463463

464464
struct combine_diff_path *diff_tree_paths(
465-
struct combine_diff_path *p, const struct object_id *oid,
465+
const struct object_id *oid,
466466
const struct object_id **parents_oid, int nparent,
467467
struct strbuf *base, struct diff_options *opt);
468468
void diff_tree_oid(const struct object_id *old_oid,
@@ -480,12 +480,20 @@ struct combine_diff_path {
480480
char status;
481481
unsigned int mode;
482482
struct object_id oid;
483-
struct strbuf path;
483+
/*
484+
* This per-parent path is filled only when doing a combined
485+
* diff with revs.combined_all_paths set, and only if the path
486+
* differs from the post-image (e.g., a rename or copy).
487+
* Otherwise it is left NULL.
488+
*/
489+
char *path;
484490
} parent[FLEX_ARRAY];
485491
};
486-
#define combine_diff_path_size(n, l) \
487-
st_add4(sizeof(struct combine_diff_path), (l), 1, \
488-
st_mult(sizeof(struct combine_diff_parent), (n)))
492+
struct combine_diff_path *combine_diff_path_new(const char *path,
493+
size_t path_len,
494+
unsigned int mode,
495+
const struct object_id *oid,
496+
size_t num_parents);
489497

490498
void show_combined_diff(struct combine_diff_path *elem, int num_parent,
491499
struct rev_info *);

0 commit comments

Comments
 (0)