summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar brian m. carlson <sandals@crustytoothpaste.net>2019-01-15 00:39:43 +0000
committerLibravatar Junio C Hamano <gitster@pobox.com>2019-01-15 09:57:41 -0800
commitf55ac4311ad173529cbac7a619d422674a4252ad (patch)
treeb6b89dfa9b37e2f7466b7286294d14fc1140308c
parentmatch-trees: compute buffer offset correctly when splicing (diff)
downloadtgif-f55ac4311ad173529cbac7a619d422674a4252ad.tar.xz
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>
-rw-r--r--match-trees.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/match-trees.c b/match-trees.c
index feca48a5fd..c2b7329e09 100644
--- a/match-trees.c
+++ b/match-trees.c
@@ -179,7 +179,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
char *buf;
unsigned long sz;
struct tree_desc desc;
- struct object_id *rewrite_here;
+ unsigned char *rewrite_here;
const struct object_id *rewrite_with;
struct object_id subtree;
enum object_type type;
@@ -206,9 +206,19 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
if (!S_ISDIR(mode))
die("entry %s in tree %s is not a tree", name,
oid_to_hex(oid1));
- rewrite_here = (struct object_id *)(desc.entry.path +
- strlen(desc.entry.path) +
- 1);
+
+ /*
+ * We cast here for two reasons:
+ *
+ * - to flip the "char *" (for the path) to "unsigned
+ * char *" (for the hash stored after it)
+ *
+ * - to discard the "const"; this is OK because we
+ * know it points into our non-const "buf"
+ */
+ rewrite_here = (unsigned char *)(desc.entry.path +
+ strlen(desc.entry.path) +
+ 1);
break;
}
update_tree_entry(&desc);
@@ -217,14 +227,16 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
die("entry %.*s not found in tree %s", toplen, prefix,
oid_to_hex(oid1));
if (*subpath) {
- status = splice_tree(rewrite_here, subpath, oid2, &subtree);
+ struct object_id tree_oid;
+ hashcpy(tree_oid.hash, rewrite_here);
+ status = splice_tree(&tree_oid, subpath, oid2, &subtree);
if (status)
return status;
rewrite_with = &subtree;
} else {
rewrite_with = oid2;
}
- oidcpy(rewrite_here, rewrite_with);
+ hashcpy(rewrite_here, rewrite_with->hash);
status = write_object_file(buf, sz, tree_type, result);
free(buf);
return status;