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:
@ -23,6 +23,7 @@
|
||||
#include "midx.h"
|
||||
#include "commit-reach.h"
|
||||
#include "date.h"
|
||||
#include "object-file-convert.h"
|
||||
|
||||
static int get_oid_oneline(struct repository *r, const char *, struct object_id *, struct commit_list *);
|
||||
|
||||
@ -47,6 +48,7 @@ struct disambiguate_state {
|
||||
|
||||
static void update_candidates(struct disambiguate_state *ds, const struct object_id *current)
|
||||
{
|
||||
/* The hash algorithm of current has already been filtered */
|
||||
if (ds->always_call_fn) {
|
||||
ds->ambiguous = ds->fn(ds->repo, current, ds->cb_data) ? 1 : 0;
|
||||
return;
|
||||
@ -132,6 +134,8 @@ static void unique_in_midx(struct multi_pack_index *m,
|
||||
{
|
||||
uint32_t num, i, first = 0;
|
||||
const struct object_id *current = NULL;
|
||||
int len = ds->len > ds->repo->hash_algo->hexsz ?
|
||||
ds->repo->hash_algo->hexsz : ds->len;
|
||||
num = m->num_objects;
|
||||
|
||||
if (!num)
|
||||
@ -147,7 +151,7 @@ static void unique_in_midx(struct multi_pack_index *m,
|
||||
for (i = first; i < num && !ds->ambiguous; i++) {
|
||||
struct object_id oid;
|
||||
current = nth_midxed_object_oid(&oid, m, i);
|
||||
if (!match_hash(ds->len, ds->bin_pfx.hash, current->hash))
|
||||
if (!match_hash(len, ds->bin_pfx.hash, current->hash))
|
||||
break;
|
||||
update_candidates(ds, current);
|
||||
}
|
||||
@ -157,6 +161,8 @@ static void unique_in_pack(struct packed_git *p,
|
||||
struct disambiguate_state *ds)
|
||||
{
|
||||
uint32_t num, i, first = 0;
|
||||
int len = ds->len > ds->repo->hash_algo->hexsz ?
|
||||
ds->repo->hash_algo->hexsz : ds->len;
|
||||
|
||||
if (p->multi_pack_index)
|
||||
return;
|
||||
@ -175,7 +181,7 @@ static void unique_in_pack(struct packed_git *p,
|
||||
for (i = first; i < num && !ds->ambiguous; i++) {
|
||||
struct object_id oid;
|
||||
nth_packed_object_id(&oid, p, i);
|
||||
if (!match_hash(ds->len, ds->bin_pfx.hash, oid.hash))
|
||||
if (!match_hash(len, ds->bin_pfx.hash, oid.hash))
|
||||
break;
|
||||
update_candidates(ds, &oid);
|
||||
}
|
||||
@ -186,6 +192,10 @@ static void find_short_packed_object(struct disambiguate_state *ds)
|
||||
struct multi_pack_index *m;
|
||||
struct packed_git *p;
|
||||
|
||||
/* Skip, unless oids from the storage hash algorithm are wanted */
|
||||
if (ds->bin_pfx.algo && (&hash_algos[ds->bin_pfx.algo] != ds->repo->hash_algo))
|
||||
return;
|
||||
|
||||
for (m = get_multi_pack_index(ds->repo); m && !ds->ambiguous;
|
||||
m = m->next)
|
||||
unique_in_midx(m, ds);
|
||||
@ -324,11 +334,12 @@ int set_disambiguate_hint_config(const char *var, const char *value)
|
||||
|
||||
static int init_object_disambiguation(struct repository *r,
|
||||
const char *name, int len,
|
||||
const struct git_hash_algo *algo,
|
||||
struct disambiguate_state *ds)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (len < MINIMUM_ABBREV || len > the_hash_algo->hexsz)
|
||||
if (len < MINIMUM_ABBREV || len > GIT_MAX_HEXSZ)
|
||||
return -1;
|
||||
|
||||
memset(ds, 0, sizeof(*ds));
|
||||
@ -355,6 +366,7 @@ static int init_object_disambiguation(struct repository *r,
|
||||
ds->len = len;
|
||||
ds->hex_pfx[len] = '\0';
|
||||
ds->repo = r;
|
||||
ds->bin_pfx.algo = algo ? hash_algo_by_ptr(algo) : GIT_HASH_UNKNOWN;
|
||||
prepare_alt_odb(r);
|
||||
return 0;
|
||||
}
|
||||
@ -489,9 +501,10 @@ static int repo_collect_ambiguous(struct repository *r UNUSED,
|
||||
return collect_ambiguous(oid, data);
|
||||
}
|
||||
|
||||
static int sort_ambiguous(const void *a, const void *b, void *ctx)
|
||||
static int sort_ambiguous(const void *va, const void *vb, void *ctx)
|
||||
{
|
||||
struct repository *sort_ambiguous_repo = ctx;
|
||||
const struct object_id *a = va, *b = vb;
|
||||
int a_type = oid_object_info(sort_ambiguous_repo, a, NULL);
|
||||
int b_type = oid_object_info(sort_ambiguous_repo, b, NULL);
|
||||
int a_type_sort;
|
||||
@ -501,8 +514,12 @@ static int sort_ambiguous(const void *a, const void *b, void *ctx)
|
||||
* Sorts by hash within the same object type, just as
|
||||
* oid_array_for_each_unique() would do.
|
||||
*/
|
||||
if (a_type == b_type)
|
||||
return oidcmp(a, b);
|
||||
if (a_type == b_type) {
|
||||
if (a->algo == b->algo)
|
||||
return oidcmp(a, b);
|
||||
else
|
||||
return a->algo > b->algo ? 1 : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Between object types show tags, then commits, and finally
|
||||
@ -531,8 +548,12 @@ static enum get_oid_result get_short_oid(struct repository *r,
|
||||
int status;
|
||||
struct disambiguate_state ds;
|
||||
int quietly = !!(flags & GET_OID_QUIETLY);
|
||||
const struct git_hash_algo *algo = r->hash_algo;
|
||||
|
||||
if (init_object_disambiguation(r, name, len, &ds) < 0)
|
||||
if (flags & GET_OID_HASH_ANY)
|
||||
algo = NULL;
|
||||
|
||||
if (init_object_disambiguation(r, name, len, algo, &ds) < 0)
|
||||
return -1;
|
||||
|
||||
if (HAS_MULTI_BITS(flags & GET_OID_DISAMBIGUATORS))
|
||||
@ -586,7 +607,7 @@ static enum get_oid_result get_short_oid(struct repository *r,
|
||||
if (!ds.ambiguous)
|
||||
ds.fn = NULL;
|
||||
|
||||
repo_for_each_abbrev(r, ds.hex_pfx, collect_ambiguous, &collect);
|
||||
repo_for_each_abbrev(r, ds.hex_pfx, algo, collect_ambiguous, &collect);
|
||||
sort_ambiguous_oid_array(r, &collect);
|
||||
|
||||
if (oid_array_for_each(&collect, show_ambiguous_object, &out))
|
||||
@ -608,13 +629,14 @@ static enum get_oid_result get_short_oid(struct repository *r,
|
||||
}
|
||||
|
||||
int repo_for_each_abbrev(struct repository *r, const char *prefix,
|
||||
const struct git_hash_algo *algo,
|
||||
each_abbrev_fn fn, void *cb_data)
|
||||
{
|
||||
struct oid_array collect = OID_ARRAY_INIT;
|
||||
struct disambiguate_state ds;
|
||||
int ret;
|
||||
|
||||
if (init_object_disambiguation(r, prefix, strlen(prefix), &ds) < 0)
|
||||
if (init_object_disambiguation(r, prefix, strlen(prefix), algo, &ds) < 0)
|
||||
return -1;
|
||||
|
||||
ds.always_call_fn = 1;
|
||||
@ -785,10 +807,12 @@ void strbuf_add_unique_abbrev(struct strbuf *sb, const struct object_id *oid,
|
||||
int repo_find_unique_abbrev_r(struct repository *r, char *hex,
|
||||
const struct object_id *oid, int len)
|
||||
{
|
||||
const struct git_hash_algo *algo =
|
||||
oid->algo ? &hash_algos[oid->algo] : r->hash_algo;
|
||||
struct disambiguate_state ds;
|
||||
struct min_abbrev_data mad;
|
||||
struct object_id oid_ret;
|
||||
const unsigned hexsz = r->hash_algo->hexsz;
|
||||
const unsigned hexsz = algo->hexsz;
|
||||
|
||||
if (len < 0) {
|
||||
unsigned long count = repo_approximate_object_count(r);
|
||||
@ -824,7 +848,7 @@ int repo_find_unique_abbrev_r(struct repository *r, char *hex,
|
||||
|
||||
find_abbrev_len_packed(&mad);
|
||||
|
||||
if (init_object_disambiguation(r, hex, mad.cur_len, &ds) < 0)
|
||||
if (init_object_disambiguation(r, hex, mad.cur_len, algo, &ds) < 0)
|
||||
return -1;
|
||||
|
||||
ds.fn = repo_extend_abbrev_len;
|
||||
|
||||
Reference in New Issue
Block a user