* A tree "oid1" has a subdirectory at "prefix". Come up with a tree object by * replacing it with another tree "oid2". */
| 180 | * replacing it with another tree "oid2". |
| 181 | */ |
| 182 | static int splice_tree(struct repository *r, |
| 183 | const struct object_id *oid1, const char *prefix, |
| 184 | const struct object_id *oid2, struct object_id *result) |
| 185 | { |
| 186 | char *subpath; |
| 187 | int toplen; |
| 188 | char *buf; |
| 189 | size_t sz; |
| 190 | struct tree_desc desc; |
| 191 | unsigned char *rewrite_here; |
| 192 | const struct object_id *rewrite_with; |
| 193 | struct object_id subtree; |
| 194 | enum object_type type; |
| 195 | int status; |
| 196 | |
| 197 | subpath = strchrnul(prefix, '/'); |
| 198 | toplen = subpath - prefix; |
| 199 | if (*subpath) |
| 200 | subpath++; |
| 201 | |
| 202 | buf = odb_read_object(r->objects, oid1, &type, &sz); |
| 203 | if (!buf) |
| 204 | die("cannot read tree %s", oid_to_hex(oid1)); |
| 205 | init_tree_desc(&desc, oid1, buf, sz); |
| 206 | |
| 207 | rewrite_here = NULL; |
| 208 | while (desc.size) { |
| 209 | const char *name; |
| 210 | unsigned short mode; |
| 211 | |
| 212 | tree_entry_extract(&desc, &name, &mode); |
| 213 | if (strlen(name) == toplen && |
| 214 | !memcmp(name, prefix, toplen)) { |
| 215 | if (!S_ISDIR(mode)) |
| 216 | die("entry %s in tree %s is not a tree", name, |
| 217 | oid_to_hex(oid1)); |
| 218 | |
| 219 | /* |
| 220 | * We cast here for two reasons: |
| 221 | * |
| 222 | * - to flip the "char *" (for the path) to "unsigned |
| 223 | * char *" (for the hash stored after it) |
| 224 | * |
| 225 | * - to discard the "const"; this is OK because we |
| 226 | * know it points into our non-const "buf" |
| 227 | */ |
| 228 | rewrite_here = (unsigned char *)(desc.entry.path + |
| 229 | strlen(desc.entry.path) + |
| 230 | 1); |
| 231 | break; |
| 232 | } |
| 233 | update_tree_entry(&desc); |
| 234 | } |
| 235 | if (!rewrite_here) |
| 236 | die("entry %.*s not found in tree %s", toplen, prefix, |
| 237 | oid_to_hex(oid1)); |
| 238 | if (*subpath) { |
| 239 | struct object_id tree_oid; |
no test coverage detected