]> git.ipfire.org Git - thirdparty/git.git/commitdiff
object-file-convert: convert commit objects when writing
authorbrian m. carlson <sandals@crustytoothpaste.net>
Mon, 2 Oct 2023 02:40:22 +0000 (21:40 -0500)
committerJunio C Hamano <gitster@pobox.com>
Mon, 2 Oct 2023 21:57:39 +0000 (14:57 -0700)
When writing a commit object in a repository with both SHA-1 and
SHA-256, we'll need to convert our commit objects so that we can write
the hash values for both into the repository.  To do so, let's add a
function to convert commit objects.

Read the commit object and map the tree value and any of the parent
values, and copy the rest of the commit through unmodified.  Note that
we don't need to modify the signature headers, because they are the
same under both algorithms.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file-convert.c

index 79e8e211ff9519567edea4686ea93cf1d47dc45c..0da081104ed4da269f4197e7f46e158cce8f28a8 100644 (file)
@@ -136,6 +136,48 @@ static int convert_tag_object(struct strbuf *out,
        return 0;
 }
 
+static int convert_commit_object(struct strbuf *out,
+                                const struct git_hash_algo *from,
+                                const struct git_hash_algo *to,
+                                const char *buffer, size_t size)
+{
+       const char *tail = buffer;
+       const char *bufptr = buffer;
+       const int tree_entry_len = from->hexsz + 5;
+       const int parent_entry_len = from->hexsz + 7;
+       struct object_id oid, mapped_oid;
+       const char *p;
+
+       tail += size;
+       if (tail <= bufptr + tree_entry_len + 1 || memcmp(bufptr, "tree ", 5) ||
+                       bufptr[tree_entry_len] != '\n')
+               return error("bogus commit object");
+       if (parse_oid_hex_algop(bufptr + 5, &oid, &p, from) < 0)
+               return error("bad tree pointer");
+
+       if (repo_oid_to_algop(the_repository, &oid, to, &mapped_oid))
+               return error("unable to map tree %s in commit object",
+                            oid_to_hex(&oid));
+       strbuf_addf(out, "tree %s\n", oid_to_hex(&mapped_oid));
+       bufptr = p + 1;
+
+       while (bufptr + parent_entry_len < tail && !memcmp(bufptr, "parent ", 7)) {
+               if (tail <= bufptr + parent_entry_len + 1 ||
+                   parse_oid_hex_algop(bufptr + 7, &oid, &p, from) ||
+                   *p != '\n')
+                       return error("bad parents in commit");
+
+               if (repo_oid_to_algop(the_repository, &oid, to, &mapped_oid))
+                       return error("unable to map parent %s in commit object",
+                                    oid_to_hex(&oid));
+
+               strbuf_addf(out, "parent %s\n", oid_to_hex(&mapped_oid));
+               bufptr = p + 1;
+       }
+       strbuf_add(out, bufptr, tail - bufptr);
+       return 0;
+}
+
 int convert_object_file(struct strbuf *outbuf,
                        const struct git_hash_algo *from,
                        const struct git_hash_algo *to,
@@ -150,13 +192,15 @@ int convert_object_file(struct strbuf *outbuf,
                BUG("Refusing noop object file conversion");
 
        switch (type) {
+       case OBJ_COMMIT:
+               ret = convert_commit_object(outbuf, from, to, buf, len);
+               break;
        case OBJ_TREE:
                ret = convert_tree_object(outbuf, from, to, buf, len);
                break;
        case OBJ_TAG:
                ret = convert_tag_object(outbuf, from, to, buf, len);
                break;
-       case OBJ_COMMIT:
        default:
                /* Not implemented yet, so fail. */
                ret = -1;