Skip to content

Commit

Permalink
match-trees: use hashcpy to splice trees
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
bk2204 authored and gitster committed Jan 15, 2019
1 parent 36775ab commit f55ac43
Showing 1 changed file with 18 additions and 6 deletions.
24 changes: 18 additions & 6 deletions match-trees.c
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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;
Expand Down

0 comments on commit f55ac43

Please sign in to comment.