use struct sha1_array in diff_tree_combined()

Maintaining an array of hashes is easier using sha1_array than open-coding it. This patch also fixes a leak of the SHA1 array in diff_tree_combined_merge(). Signed-off-by: René Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Dec 17, 2011 at 11:15 UTC 0041f09de6e62efc31c860487f04e8b08bce68c8
4 files changed +26 -37
builtin/diff.c
+6 -6
@@ -14,6 +14,7 @@
14 #include "log-tree.h"
15 #include "builtin.h"
16 #include "submodule.h"
17 +#include "sha1-array.h"
18
19 struct blobinfo {
20 unsigned char sha1[20];
@@ -169,7 +170,7 @@ static int builtin_diff_combined(struct rev_info *revs,
170 struct object_array_entry *ent,
171 int ents)
172 {
172 - const unsigned char (*parent)[20];
173 + struct sha1_array parents = SHA1_ARRAY_INIT;
174 int i;
175
176 if (argc > 1)
@@ -177,12 +178,11 @@ static int builtin_diff_combined(struct rev_info *revs,
178
179 if (!revs->dense_combined_merges && !revs->combine_merges)
180 revs->dense_combined_merges = revs->combine_merges = 1;
180 - parent = xmalloc(ents * sizeof(*parent));
181 - for (i = 0; i < ents; i++)
182 - hashcpy((unsigned char *)(parent + i), ent[i].item->sha1);
183 - diff_tree_combined(parent[0], parent + 1, ents - 1,
181 + for (i = 1; i < ents; i++)
182 + sha1_array_append(&parents, ent[i].item->sha1);
183 + diff_tree_combined(ent[0].item->sha1, &parents,
184 revs->dense_combined_merges, revs);
185 - free((void *)parent);
185 + sha1_array_clear(&parents);
186 return 0;
187 }
188
combine-diff.c
+13 -21
@@ -8,6 +8,7 @@
8 #include "log-tree.h"
9 #include "refs.h"
10 #include "userdiff.h"
11 +#include "sha1-array.h"
12
13 static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
14 {
@@ -1116,15 +1117,14 @@ static void handle_combined_callback(struct diff_options *opt,
1117 }
1118
1119 void diff_tree_combined(const unsigned char *sha1,
1119 - const unsigned char parent[][20],
1120 - int num_parent,
1120 + const struct sha1_array *parents,
1121 int dense,
1122 struct rev_info *rev)
1123 {
1124 struct diff_options *opt = &rev->diffopt;
1125 struct diff_options diffopts;
1126 struct combine_diff_path *p, *paths = NULL;
1127 - int i, num_paths, needsep, show_log_first;
1127 + int i, num_paths, needsep, show_log_first, num_parent = parents->nr;
1128
1129 diffopts = *opt;
1130 diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
@@ -1144,7 +1144,7 @@ void diff_tree_combined(const unsigned char *sha1,
1144 diffopts.output_format = stat_opt;
1145 else
1146 diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
1147 - diff_tree_sha1(parent[i], sha1, "", &diffopts);
1147 + diff_tree_sha1(parents->sha1[i], sha1, "", &diffopts);
1148 diffcore_std(&diffopts);
1149 paths = intersect_paths(paths, i, num_parent);
1150
@@ -1199,22 +1199,14 @@ void diff_tree_combined(const unsigned char *sha1,
1199 void diff_tree_combined_merge(const unsigned char *sha1,
1200 int dense, struct rev_info *rev)
1201 {
1202 - int num_parent;
1203 - const unsigned char (*parent)[20];
1202 struct commit *commit = lookup_commit(sha1);
1205 - struct commit_list *parents;
1206 -
1207 - /* count parents */
1208 - for (parents = commit->parents, num_parent = 0;
1209 - parents;
1210 - parents = parents->next, num_parent++)
1211 - ; /* nothing */
1212 -
1213 - parent = xmalloc(num_parent * sizeof(*parent));
1214 - for (parents = commit->parents, num_parent = 0;
1215 - parents;
1216 - parents = parents->next, num_parent++)
1217 - hashcpy((unsigned char *)(parent + num_parent),
1218 - parents->item->object.sha1);
1219 - diff_tree_combined(sha1, parent, num_parent, dense, rev);
1203 + struct commit_list *parent = commit->parents;
1204 + struct sha1_array parents = SHA1_ARRAY_INIT;
1205 +
1206 + while (parent) {
1207 + sha1_array_append(&parents, parent->item->object.sha1);
1208 + parent = parent->next;
1209 + }
1210 + diff_tree_combined(sha1, &parents, dense, rev);
1211 + sha1_array_clear(&parents);
1212 }
diff.h
+2 -1
@@ -12,6 +12,7 @@ struct diff_queue_struct;
12 struct strbuf;
13 struct diff_filespec;
14 struct userdiff_driver;
15 +struct sha1_array;
16
17 typedef void (*change_fn_t)(struct diff_options *options,
18 unsigned old_mode, unsigned new_mode,
@@ -195,7 +196,7 @@ struct combine_diff_path {
196 extern void show_combined_diff(struct combine_diff_path *elem, int num_parent,
197 int dense, struct rev_info *);
198
198 -extern void diff_tree_combined(const unsigned char *sha1, const unsigned char parent[][20], int num_parent, int dense, struct rev_info *rev);
199 +extern void diff_tree_combined(const unsigned char *sha1, const struct sha1_array *parents, int dense, struct rev_info *rev);
200
201 extern void diff_tree_combined_merge(const unsigned char *sha1, int, struct rev_info *);
202
submodule.c
+5 -9
@@ -373,15 +373,11 @@ static void collect_submodules_from_diff(struct diff_queue_struct *q,
373
374 static void commit_need_pushing(struct commit *commit, struct commit_list *parent, int *needs_pushing)
375 {
376 - const unsigned char (*parents)[20];
377 - unsigned int i, n;
376 + struct sha1_array parents = SHA1_ARRAY_INIT;
377 struct rev_info rev;
378
380 - n = commit_list_count(parent);
381 - parents = xmalloc(n * sizeof(*parents));
382 -
383 - for (i = 0; i < n; i++) {
384 - hashcpy((unsigned char *)(parents + i), parent->item->object.sha1);
379 + while (parent) {
380 + sha1_array_append(&parents, parent->item->object.sha1);
381 parent = parent->next;
382 }
383
@@ -389,9 +385,9 @@ static void commit_need_pushing(struct commit *commit, struct commit_list *paren
385 rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
386 rev.diffopt.format_callback = collect_submodules_from_diff;
387 rev.diffopt.format_callback_data = needs_pushing;
392 - diff_tree_combined(commit->object.sha1, parents, n, 1, &rev);
388 + diff_tree_combined(commit->object.sha1, &parents, 1, &rev);
389
394 - free((void *)parents);
390 + sha1_array_clear(&parents);
391 }
392
393 int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name)