match-trees: use hashcpy to splice trees
When we splice trees together, we operate in place on the tree buffer. If we're using SHA-1 for the hash algorithm, we may not have a full GIT_MAX_RAWSZ (32) bytes to copy. Consequently, it doesn't logically make sense for us to use a struct object_id to represent this type, since it isn't a complete object. Represent this value as a unsigned char pointer instead and copy it when necessary. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
brian m. carlson committed
Jan 15, 2019 at 00:39 UTC
f55ac4311ad173529cbac7a619d422674a4252ad
1 file changed
+18
-6
match-trees.c
+18
-6
@@ -179,7 +179,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
179
char *buf;
180
unsigned long sz;
181
struct tree_desc desc;
182
- struct object_id *rewrite_here;
182
+ unsigned char *rewrite_here;
183
const struct object_id *rewrite_with;
184
struct object_id subtree;
185
enum object_type type;
@@ -206,9 +206,19 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
206
if (!S_ISDIR(mode))
207
die("entry %s in tree %s is not a tree", name,
208
oid_to_hex(oid1));
209
- rewrite_here = (struct object_id *)(desc.entry.path +
210
- strlen(desc.entry.path) +
211
- 1);
209
+
210
+ /*
211
+ * We cast here for two reasons:
212
+ *
213
+ * - to flip the "char *" (for the path) to "unsigned
214
+ * char *" (for the hash stored after it)
215
+ *
216
+ * - to discard the "const"; this is OK because we
217
+ * know it points into our non-const "buf"
218
+ */
219
+ rewrite_here = (unsigned char *)(desc.entry.path +
220
+ strlen(desc.entry.path) +
221
+ 1);
222
break;
223
}
224
update_tree_entry(&desc);
@@ -217,14 +227,16 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
227
die("entry %.*s not found in tree %s", toplen, prefix,
228
oid_to_hex(oid1));
229
if (*subpath) {
220
- status = splice_tree(rewrite_here, subpath, oid2, &subtree);
230
+ struct object_id tree_oid;
231
+ hashcpy(tree_oid.hash, rewrite_here);
232
+ status = splice_tree(&tree_oid, subpath, oid2, &subtree);
233
if (status)
234
return status;
235
rewrite_with = &subtree;
236
} else {
237
rewrite_with = oid2;
238
}
227
- oidcpy(rewrite_here, rewrite_with);
239
+ hashcpy(rewrite_here, rewrite_with->hash);
240
status = write_object_file(buf, sz, tree_type, result);
241
free(buf);
242
return status;