Merge branch 'eb/hash-transition'

Work to support a repository that work with both SHA-1 and SHA-256
hash algorithms has started.

* eb/hash-transition: (30 commits)
  t1016-compatObjectFormat: add tests to verify the conversion between objects
  t1006: test oid compatibility with cat-file
  t1006: rename sha1 to oid
  test-lib: compute the compatibility hash so tests may use it
  builtin/ls-tree: let the oid determine the output algorithm
  object-file: handle compat objects in check_object_signature
  tree-walk: init_tree_desc take an oid to get the hash algorithm
  builtin/cat-file: let the oid determine the output algorithm
  rev-parse: add an --output-object-format parameter
  repository: implement extensions.compatObjectFormat
  object-file: update object_info_extended to reencode objects
  object-file-convert: convert commits that embed signed tags
  object-file-convert: convert commit objects when writing
  object-file-convert: don't leak when converting tag objects
  object-file-convert: convert tag objects when writing
  object-file-convert: add a function to convert trees between algorithms
  object: factor out parse_mode out of fast-import and tree-walk into in object.h
  cache: add a function to read an OID of a specific algorithm
  tag: sign both hashes
  commit: export add_header_signature to support handling signatures on tags
  ...
This commit is contained in:
Junio C Hamano
2024-03-28 14:13:50 -07:00
62 changed files with 1880 additions and 385 deletions

View File

@ -27,6 +27,7 @@
#include "ref-filter.h"
#include "date.h"
#include "write-or-die.h"
#include "object-file-convert.h"
static const char * const git_tag_usage[] = {
N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
@ -151,9 +152,43 @@ static int verify_tag(const char *name, const char *ref UNUSED,
return 0;
}
static int do_sign(struct strbuf *buffer)
static int do_sign(struct strbuf *buffer, struct object_id **compat_oid,
struct object_id *compat_oid_buf)
{
return sign_buffer(buffer, buffer, get_signing_key()) ? -1 : 0;
const struct git_hash_algo *compat = the_repository->compat_hash_algo;
struct strbuf sig = STRBUF_INIT, compat_sig = STRBUF_INIT;
struct strbuf compat_buf = STRBUF_INIT;
const char *keyid = get_signing_key();
int ret = -1;
if (sign_buffer(buffer, &sig, keyid))
return -1;
if (compat) {
const struct git_hash_algo *algo = the_repository->hash_algo;
if (convert_object_file(&compat_buf, algo, compat,
buffer->buf, buffer->len, OBJ_TAG, 1))
goto out;
if (sign_buffer(&compat_buf, &compat_sig, keyid))
goto out;
add_header_signature(&compat_buf, &sig, algo);
strbuf_addbuf(&compat_buf, &compat_sig);
hash_object_file(compat, compat_buf.buf, compat_buf.len,
OBJ_TAG, compat_oid_buf);
*compat_oid = compat_oid_buf;
}
if (compat_sig.len)
add_header_signature(buffer, &compat_sig, compat);
strbuf_addbuf(buffer, &sig);
ret = 0;
out:
strbuf_release(&sig);
strbuf_release(&compat_sig);
strbuf_release(&compat_buf);
return ret;
}
static const char tag_template[] =
@ -226,9 +261,11 @@ static void write_tag_body(int fd, const struct object_id *oid)
static int build_tag_object(struct strbuf *buf, int sign, struct object_id *result)
{
if (sign && do_sign(buf) < 0)
struct object_id *compat_oid = NULL, compat_oid_buf;
if (sign && do_sign(buf, &compat_oid, &compat_oid_buf) < 0)
return error(_("unable to sign the tag"));
if (write_object_file(buf->buf, buf->len, OBJ_TAG, result) < 0)
if (write_object_file_flags(buf->buf, buf->len, OBJ_TAG, result,
compat_oid, 0) < 0)
return error(_("unable to write tag file"));
return 0;
}