diff options
author | Junio C Hamano <gitster@pobox.com> | 2018-05-30 07:04:10 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2018-05-30 07:04:10 +0200 |
commit | 42c8ce1c49f862c98b35e4d89c88aa3d489d6608 (patch) | |
tree | dce3eb119c51e3d539f5a703411787d3a333b175 | |
parent | Merge branch 'sb/blame-color' (diff) | |
parent | merge-one-file: compute empty blob object ID (diff) | |
download | git-42c8ce1c49f862c98b35e4d89c88aa3d489d6608.tar.xz git-42c8ce1c49f862c98b35e4d89c88aa3d489d6608.zip |
Merge branch 'bc/object-id'
Conversion from uchar[20] to struct object_id continues.
* bc/object-id: (42 commits)
merge-one-file: compute empty blob object ID
add--interactive: compute the empty tree value
Update shell scripts to compute empty tree object ID
sha1_file: only expose empty object constants through git_hash_algo
dir: use the_hash_algo for empty blob object ID
sequencer: use the_hash_algo for empty tree object ID
cache-tree: use is_empty_tree_oid
sha1_file: convert cached object code to struct object_id
builtin/reset: convert use of EMPTY_TREE_SHA1_BIN
builtin/receive-pack: convert one use of EMPTY_TREE_SHA1_HEX
wt-status: convert two uses of EMPTY_TREE_SHA1_HEX
submodule: convert several uses of EMPTY_TREE_SHA1_HEX
sequencer: convert one use of EMPTY_TREE_SHA1_HEX
merge: convert empty tree constant to the_hash_algo
builtin/merge: switch tree functions to use object_id
builtin/am: convert uses of EMPTY_TREE_SHA1_BIN to the_hash_algo
sha1-file: add functions for hex empty tree and blob OIDs
builtin/receive-pack: avoid hard-coded constants for push certs
diff: specify abbreviation size in terms of the_hash_algo
upload-pack: replace use of several hard-coded constants
...
46 files changed, 348 insertions, 306 deletions
diff --git a/builtin/am.c b/builtin/am.c index 3dc2ef4259..aa989e7390 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1542,7 +1542,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa char *their_tree_name; if (get_oid("HEAD", &our_tree) < 0) - hashcpy(our_tree.hash, EMPTY_TREE_SHA1_BIN); + oidcpy(&our_tree, the_hash_algo->empty_tree); if (build_fake_ancestor(state, index_path)) return error("could not build fake ancestor"); @@ -2042,7 +2042,7 @@ static void am_skip(struct am_state *state) am_rerere_clear(); if (get_oid("HEAD", &head)) - hashcpy(head.hash, EMPTY_TREE_SHA1_BIN); + oidcpy(&head, the_hash_algo->empty_tree); if (clean_index(&head, &head)) die(_("failed to clean index")); @@ -2105,11 +2105,11 @@ static void am_abort(struct am_state *state) curr_branch = resolve_refdup("HEAD", 0, &curr_head, NULL); has_curr_head = curr_branch && !is_null_oid(&curr_head); if (!has_curr_head) - hashcpy(curr_head.hash, EMPTY_TREE_SHA1_BIN); + oidcpy(&curr_head, the_hash_algo->empty_tree); has_orig_head = !get_oid("ORIG_HEAD", &orig_head); if (!has_orig_head) - hashcpy(orig_head.hash, EMPTY_TREE_SHA1_BIN); + oidcpy(&orig_head, the_hash_algo->empty_tree); clean_index(&curr_head, &orig_head); diff --git a/builtin/count-objects.c b/builtin/count-objects.c index b054713e1a..d51e2ce1ec 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -66,7 +66,7 @@ static int count_loose(const struct object_id *oid, const char *path, void *data else { loose_size += on_disk_bytes(st); loose++; - if (verbose && has_sha1_pack(oid->hash)) + if (verbose && has_object_pack(oid)) packed_loose++; } return 0; diff --git a/builtin/fsck.c b/builtin/fsck.c index 916109ac1c..3ad4f160f9 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -228,7 +228,7 @@ static void check_reachable_object(struct object *obj) if (!(obj->flags & HAS_OBJ)) { if (is_promisor_object(&obj->oid)) return; - if (has_sha1_pack(obj->oid.hash)) + if (has_object_pack(&obj->oid)) return; /* it is in pack - forget about it */ printf("missing %s %s\n", printable_type(obj), describe_object(obj)); diff --git a/builtin/index-pack.c b/builtin/index-pack.c index b3a5abcf2b..4ab31ed388 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1549,12 +1549,13 @@ static void read_v2_anomalous_offsets(struct packed_git *p, { const uint32_t *idx1, *idx2; uint32_t i; + const uint32_t hashwords = the_hash_algo->rawsz / sizeof(uint32_t); /* The address of the 4-byte offset table */ idx1 = (((const uint32_t *)p->index_data) + 2 /* 8-byte header */ + 256 /* fan out */ - + 5 * p->num_objects /* 20-byte SHA-1 table */ + + hashwords * p->num_objects /* object ID table */ + p->num_objects /* CRC32 table */ ); diff --git a/builtin/merge.c b/builtin/merge.c index de62b2c5c6..fba0a7fc79 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -280,7 +280,7 @@ out: return rc; } -static void read_empty(unsigned const char *sha1, int verbose) +static void read_empty(const struct object_id *oid, int verbose) { int i = 0; const char *args[7]; @@ -290,15 +290,15 @@ static void read_empty(unsigned const char *sha1, int verbose) args[i++] = "-v"; args[i++] = "-m"; args[i++] = "-u"; - args[i++] = EMPTY_TREE_SHA1_HEX; - args[i++] = sha1_to_hex(sha1); + args[i++] = empty_tree_oid_hex(); + args[i++] = oid_to_hex(oid); args[i] = NULL; if (run_command_v_opt(args, RUN_GIT_CMD)) die(_("read-tree failed")); } -static void reset_hard(unsigned const char *sha1, int verbose) +static void reset_hard(const struct object_id *oid, int verbose) { int i = 0; const char *args[6]; @@ -308,7 +308,7 @@ static void reset_hard(unsigned const char *sha1, int verbose) args[i++] = "-v"; args[i++] = "--reset"; args[i++] = "-u"; - args[i++] = sha1_to_hex(sha1); + args[i++] = oid_to_hex(oid); args[i] = NULL; if (run_command_v_opt(args, RUN_GIT_CMD)) @@ -324,7 +324,7 @@ static void restore_state(const struct object_id *head, if (is_null_oid(stash)) return; - reset_hard(head->hash, 1); + reset_hard(head, 1); args[2] = oid_to_hex(stash); @@ -1297,7 +1297,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) if (remoteheads->next) die(_("Can merge only exactly one commit into empty head")); remote_head_oid = &remoteheads->item->object.oid; - read_empty(remote_head_oid->hash, 0); + read_empty(remote_head_oid, 0); update_ref("initial pull", "HEAD", remote_head_oid, NULL, 0, UPDATE_REFS_DIE_ON_ERR); goto done; diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 53a0fb6ef2..e78f3f5220 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -279,6 +279,7 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent enum object_type type; void *buf; struct git_istream *st = NULL; + const unsigned hashsz = the_hash_algo->rawsz; if (!usable_delta) { if (oe_type(entry) == OBJ_BLOB && @@ -335,7 +336,7 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent dheader[pos] = ofs & 127; while (ofs >>= 7) dheader[--pos] = 128 | (--ofs & 127); - if (limit && hdrlen + sizeof(dheader) - pos + datalen + 20 >= limit) { + if (limit && hdrlen + sizeof(dheader) - pos + datalen + hashsz >= limit) { if (st) close_istream(st); free(buf); @@ -347,19 +348,19 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent } else if (type == OBJ_REF_DELTA) { /* * Deltas with a base reference contain - * an additional 20 bytes for the base sha1. + * additional bytes for the base object ID. */ - if (limit && hdrlen + 20 + datalen + 20 >= limit) { + if (limit && hdrlen + hashsz + datalen + hashsz >= limit) { if (st) close_istream(st); free(buf); return 0; } hashwrite(f, header, hdrlen); - hashwrite(f, DELTA(entry)->idx.oid.hash, 20); - hdrlen += 20; + hashwrite(f, DELTA(entry)->idx.oid.hash, hashsz); + hdrlen += hashsz; } else { - if (limit && hdrlen + datalen + 20 >= limit) { + if (limit && hdrlen + datalen + hashsz >= limit) { if (st) close_istream(st); free(buf); @@ -391,6 +392,7 @@ static off_t write_reuse_object(struct hashfile *f, struct object_entry *entry, unsigned char header[MAX_PACK_OBJECT_HEADER], dheader[MAX_PACK_OBJECT_HEADER]; unsigned hdrlen; + const unsigned hashsz = the_hash_algo->rawsz; unsigned long entry_size = SIZE(entry); if (DELTA(entry)) @@ -427,7 +429,7 @@ static off_t write_reuse_object(struct hashfile *f, struct object_entry *entry, dheader[pos] = ofs & 127; while (ofs >>= 7) dheader[--pos] = 128 | (--ofs & 127); - if (limit && hdrlen + sizeof(dheader) - pos + datalen + 20 >= limit) { + if (limit && hdrlen + sizeof(dheader) - pos + datalen + hashsz >= limit) { unuse_pack(&w_curs); return 0; } @@ -436,16 +438,16 @@ static off_t write_reuse_object(struct hashfile *f, struct object_entry *entry, hdrlen += sizeof(dheader) - pos; reused_delta++; } else if (type == OBJ_REF_DELTA) { - if (limit && hdrlen + 20 + datalen + 20 >= limit) { + if (limit && hdrlen + hashsz + datalen + hashsz >= limit) { unuse_pack(&w_curs); return 0; } hashwrite(f, header, hdrlen); - hashwrite(f, DELTA(entry)->idx.oid.hash, 20); - hdrlen += 20; + hashwrite(f, DELTA(entry)->idx.oid.hash, hashsz); + hdrlen += hashsz; reused_delta++; } else { - if (limit && hdrlen + datalen + 20 >= limit) { + if (limit && hdrlen + datalen + hashsz >= limit) { unuse_pack(&w_curs); return 0; } @@ -769,7 +771,7 @@ static off_t write_reused_pack(struct hashfile *f) die_errno("unable to seek in reused packfile"); if (reuse_packfile_offset < 0) - reuse_packfile_offset = reuse_packfile->pack_size - 20; + reuse_packfile_offset = reuse_packfile->pack_size - the_hash_algo->rawsz; total = to_write = reuse_packfile_offset - sizeof(struct pack_header); @@ -1033,7 +1035,7 @@ static int want_object_in_pack(const struct object_id *oid, int want; struct list_head *pos; - if (!exclude && local && has_loose_object_nonlocal(oid->hash)) + if (!exclude && local && has_loose_object_nonlocal(oid)) return 0; /* @@ -1467,7 +1469,7 @@ static void check_object(struct object_entry *entry) if (reuse_delta && !entry->preferred_base) base_ref = use_pack(p, &w_curs, entry->in_pack_offset + used, NULL); - entry->in_pack_header_size = used + 20; + entry->in_pack_header_size = used + the_hash_algo->rawsz; break; case OBJ_OFS_DELTA: buf = use_pack(p, &w_curs, @@ -1949,7 +1951,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, /* Now some size filtering heuristics. */ trg_size = SIZE(trg_entry); if (!DELTA(trg_entry)) { - max_size = trg_size/2 - 20; + max_size = trg_size/2 - the_hash_algo->rawsz; ref_depth = 1; } else { max_size = DELTA_SIZE(trg_entry); diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index 354478a127..0494dceff7 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -20,7 +20,7 @@ static int load_all_packs, verbose, alt_odb; struct llist_item { struct llist_item *next; - const unsigned char *sha1; + const struct object_id *oid; }; static struct llist { struct llist_item *front; @@ -90,14 +90,14 @@ static struct llist * llist_copy(struct llist *list) return ret; new_item = ret->front = llist_item_get(); - new_item->sha1 = list->front->sha1; + new_item->oid = list->front->oid; old_item = list->front->next; while (old_item) { prev = new_item; new_item = llist_item_get(); prev->next = new_item; - new_item->sha1 = old_item->sha1; + new_item->oid = old_item->oid; old_item = old_item->next; } new_item->next = NULL; @@ -108,10 +108,10 @@ static struct llist * llist_copy(struct llist *list) static inline struct llist_item *llist_insert(struct llist *list, struct llist_item *after, - const unsigned char *sha1) + const struct object_id *oid) { struct llist_item *new_item = llist_item_get(); - new_item->sha1 = sha1; + new_item->oid = oid; new_item->next = NULL; if (after != NULL) { @@ -131,21 +131,21 @@ static inline struct llist_item *llist_insert(struct llist *list, } static inline struct llist_item *llist_insert_back(struct llist *list, - const unsigned char *sha1) + const struct object_id *oid) { - return llist_insert(list, list->back, sha1); + return llist_insert(list, list->back, oid); } static inline struct llist_item *llist_insert_sorted_unique(struct llist *list, - const unsigned char *sha1, struct llist_item *hint) + const struct object_id *oid, struct llist_item *hint) { struct llist_item *prev = NULL, *l; l = (hint == NULL) ? list->front : hint; while (l) { - int cmp = hashcmp(l->sha1, sha1); + int cmp = oidcmp(l->oid, oid); if (cmp > 0) { /* we insert before this entry */ - return llist_insert(list, prev, sha1); + return llist_insert(list, prev, oid); } if (!cmp) { /* already exists */ return l; @@ -154,11 +154,11 @@ static inline struct llist_item *llist_insert_sorted_unique(struct llist *list, l = l->next; } /* insert at the end */ - return llist_insert_back(list, sha1); + return llist_insert_back(list, oid); } /* returns a pointer to an item in front of sha1 */ -static inline struct llist_item * llist_sorted_remove(struct llist *list, const unsigned char *sha1, struct llist_item *hint) +static inline struct llist_item * llist_sorted_remove(struct llist *list, const struct object_id *oid, struct llist_item *hint) { struct llist_item *prev, *l; @@ -166,7 +166,7 @@ redo_from_start: l = (hint == NULL) ? list->front : hint; prev = NULL; while (l) { - int cmp = hashcmp(l->sha1, sha1); + int cmp = oidcmp(l->oid, oid); if (cmp > 0) /* not in list, since sorted */ return prev; if (!cmp) { /* found */ @@ -201,7 +201,7 @@ static void llist_sorted_difference_inplace(struct llist *A, b = B->front; while (b) { - hint = llist_sorted_remove(A, b->sha1, hint); + hint = llist_sorted_remove(A, b->oid, hint); b = b->next; } } @@ -252,13 +252,14 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2) unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step; const unsigned char *p1_base, *p2_base; struct llist_item *p1_hint = NULL, *p2_hint = NULL; + const unsigned int hashsz = the_hash_algo->rawsz; p1_base = p1->pack->index_data; p2_base = p2->pack->index_data; p1_base += 256 * 4 + ((p1->pack->index_version < 2) ? 4 : 8); p2_base += 256 * 4 + ((p2->pack->index_version < 2) ? 4 : 8); - p1_step = (p1->pack->index_version < 2) ? 24 : 20; - p2_step = (p2->pack->index_version < 2) ? 24 : 20; + p1_step = hashsz + ((p1->pack->index_version < 2) ? 4 : 0); + p2_step = hashsz + ((p2->pack->index_version < 2) ? 4 : 0); while (p1_off < p1->pack->num_objects * p1_step && p2_off < p2->pack->num_objects * p2_step) @@ -267,9 +268,11 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2) /* cmp ~ p1 - p2 */ if (cmp == 0) { p1_hint = llist_sorted_remove(p1->unique_objects, - p1_base + p1_off, p1_hint); + (const struct object_id *)(p1_base + p1_off), + p1_hint); p2_hint = llist_sorted_remove(p2->unique_objects, - p1_base + p1_off, p2_hint); + (const struct object_id *)(p1_base + p1_off), + p2_hint); p1_off += p1_step; p2_off += p2_step; continue; @@ -359,13 +362,14 @@ static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2) size_t ret = 0; unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step; const unsigned char *p1_base, *p2_base; + const unsigned int hashsz = the_hash_algo->rawsz; p1_base = p1->index_data; p2_base = p2->index_data; p1_base += 256 * 4 + ((p1->index_version < 2) ? 4 : 8); p2_base += 256 * 4 + ((p2->index_version < 2) ? 4 : 8); - p1_step = (p1->index_version < 2) ? 24 : 20; - p2_step = (p2->index_version < 2) ? 24 : 20; + p1_step = hashsz + ((p1->index_version < 2) ? 4 : 0); + p2_step = hashsz + ((p2->index_version < 2) ? 4 : 0); while (p1_off < p1->num_objects * p1_step && p2_off < p2->num_objects * p2_step) @@ -499,7 +503,7 @@ static void load_all_objects(void) l = pl->all_objects->front; while (l) { hint = llist_insert_sorted_unique(all_objects, - l->sha1, hint); + l->oid, hint); l = l->next; } pl = pl->next; @@ -558,9 +562,9 @@ static struct pack_list * add_pack(struct packed_git *p) base = p->index_data; base += 256 * 4 + ((p->index_version < 2) ? 4 : 8); - step = (p->index_version < 2) ? 24 : 20; + step = the_hash_algo->rawsz + ((p->index_version < 2) ? 4 : 0); while (off < p->num_objects * step) { - llist_insert_back(l.all_objects, base + off); + llist_insert_back(l.all_objects, (const struct object_id *)(base + off)); off += step; } /* this list will be pruned in cmp_two_packs later */ @@ -601,8 +605,8 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix) int i; struct pack_list *min, *red, *pl; struct llist *ignore; - unsigned char *sha1; - char buf[42]; /* 40 byte sha1 + \n + \0 */ + struct object_id *oid; + char buf[GIT_MAX_HEXSZ + 2]; /* hex hash + \n + \0 */ if (argc == 2 && !strcmp(argv[1], "-h")) usage(pack_redundant_usage); @@ -650,10 +654,10 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix) llist_init(&ignore); if (!isatty(0)) { while (fgets(buf, sizeof(buf), stdin)) { - sha1 = xmalloc(20); - if (get_sha1_hex(buf, sha1)) - die("Bad sha1 on stdin: %s", buf); - llist_insert_sorted_unique(ignore, sha1, NULL); + oid = xmalloc(sizeof(*oid)); + if (get_oid_hex(buf, oid)) + die("Bad object ID on stdin: %s", buf); + llist_insert_sorted_unique(ignore, oid, NULL); } } llist_sorted_difference_inplace(all_objects, ignore); diff --git a/builtin/prune-packed.c b/builtin/prune-packed.c index 419238171d..4ff525e50f 100644 --- a/builtin/prune-packed.c +++ b/builtin/prune-packed.c @@ -25,7 +25,7 @@ static int prune_object(const struct object_id *oid, const char *path, { int *opts = data; - if (!has_sha1_pack(oid->hash)) + if (!has_object_pack(oid)) return 0; if (*opts & PRUNE_PACKED_DRY_RUN) diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index d5f15cd4f6..68d36e0a56 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -454,21 +454,21 @@ static void hmac_sha1(unsigned char *out, /* RFC 2104 2. (6) & (7) */ git_SHA1_Init(&ctx); git_SHA1_Update(&ctx, k_opad, sizeof(k_opad)); - git_SHA1_Update(&ctx, out, 20); + git_SHA1_Update(&ctx, out, GIT_SHA1_RAWSZ); git_SHA1_Final(out, &ctx); } static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp) { struct strbuf buf = STRBUF_INIT; - unsigned char sha1[20]; + unsigned char sha1[GIT_SHA1_RAWSZ]; strbuf_addf(&buf, "%s:%"PRItime, path, stamp); hmac_sha1(sha1, buf.buf, buf.len, cert_nonce_seed, strlen(cert_nonce_seed));; strbuf_release(&buf); /* RFC 2104 5. HMAC-SHA1-80 */ - strbuf_addf(&buf, "%"PRItime"-%.*s", stamp, 20, sha1_to_hex(sha1)); + strbuf_addf(&buf, "%"PRItime"-%.*s", stamp, GIT_SHA1_HEXSZ, sha1_to_hex(sha1)); return strbuf_detach(&buf, NULL); } @@ -968,7 +968,7 @@ static const char *push_to_deploy(unsigned char *sha1, return "Working directory has unstaged changes"; /* diff-index with either HEAD or an empty tree */ - diff_index[4] = head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX; + diff_index[4] = head_has_history() ? "HEAD" : empty_tree_oid_hex(); child_process_init(&child); child.argv = diff_index; diff --git a/builtin/reset.c b/builtin/reset.c index 7f1c3f02a3..a862c70fab 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -314,7 +314,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) unborn = !strcmp(rev, "HEAD") && get_oid("HEAD", &oid); if (unborn) { /* reset on unborn branch: treat as reset to empty tree */ - hashcpy(oid.hash, EMPTY_TREE_SHA1_BIN); + oidcpy(&oid, the_hash_algo->empty_tree); } else if (!pathspec.nr) { struct commit *commit; if (get_oid_committish(rev, &oid)) diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 36b2087782..55c0b90441 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -887,8 +887,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) if (read_cache() < 0) die(_("Could not read the index")); if (the_index.split_index) { - const unsigned char *sha1 = the_index.split_index->base_sha1; - const char *path = git_path("sharedindex.%s", sha1_to_hex(sha1)); + const struct object_id *oid = &the_index.split_index->base_oid; + const char *path = git_path("sharedindex.%s", oid_to_hex(oid)); strbuf_reset(&buf); puts(relative_path(path, prefix, &buf)); } diff --git a/cache-tree.c b/cache-tree.c index 6a555f4d43..25663825b5 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -385,7 +385,7 @@ static int update_one(struct cache_tree *it, /* * "sub" can be an empty tree if all subentries are i-t-a. */ - if (contains_ita && !oidcmp(oid, &empty_tree_oid)) + if (contains_ita && is_empty_tree_oid(oid)) continue; strbuf_grow(&buffer, entlen + 100); @@ -523,7 +523,7 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p) if (0 <= it->entry_count) { if (size < rawsz) goto free_return; - memcpy(it->oid.hash, (const unsigned char*)buf, rawsz); + oidread(&it->oid, (const unsigned char *)buf); buf += rawsz; size -= rawsz; } @@ -324,7 +324,7 @@ struct index_state { drop_cache_tree : 1; struct hashmap name_hash; struct hashmap dir_hash; - unsigned char sha1[20]; + struct object_id oid; struct untracked_cache *untracked; uint64_t fsmonitor_last_update; struct ewah_bitmap *fsmonitor_dirty; @@ -1017,21 +1017,10 @@ static inline void oidclr(struct object_id *oid) memset(oid->hash, 0, GIT_MAX_RAWSZ); } - -#define EMPTY_TREE_SHA1_HEX \ - "4b825dc642cb6eb9a060e54bf8d69288fbee4904" -#define EMPTY_TREE_SHA1_BIN_LITERAL \ - "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \ - "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04" -extern const struct object_id empty_tree_oid; -#define EMPTY_TREE_SHA1_BIN (empty_tree_oid.hash) - -#define EMPTY_BLOB_SHA1_HEX \ - "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391" -#define EMPTY_BLOB_SHA1_BIN_LITERAL \ - "\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \ - "\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91" -extern const struct object_id empty_blob_oid; +static inline void oidread(struct object_id *oid, const unsigned char *hash) +{ + memcpy(oid->hash, hash, the_hash_algo->rawsz); +} static inline int is_empty_blob_sha1(const unsigned char *sha1) { @@ -1053,6 +1042,9 @@ static inline int is_empty_tree_oid(const struct object_id *oid) return !oidcmp(oid, the_hash_algo->empty_tree); } +const char *empty_tree_oid_hex(void); +const char *empty_blob_oid_hex(void); + /* set default permissions by passing mode arguments to open(2) */ int git_mkstemps_mode(char *pattern, int suffix_len, int mode); int git_mkstemp_mode(char *pattern, int mode); @@ -1268,7 +1260,7 @@ extern int has_object_file_with_flags(const struct object_id *oid, int flags); * with the specified name. This function does not respect replace * references. */ -extern int has_loose_object_nonlocal(const unsigned char *sha1); +extern int has_loose_object_nonlocal(const struct object_id *oid); extern void assert_oid_type(const struct object_id *oid, enum object_type expect); @@ -1299,7 +1291,6 @@ static inline int hex2chr(const char *s) #define FALLBACK_DEFAULT_ABBREV 7 struct object_context { - unsigned char tree[20]; unsigned mode; /* * symlink_path is only used by get_tree_entry_follow_symlinks, @@ -1566,7 +1557,6 @@ struct pack_window { struct pack_entry { off_t offset; - unsigned char sha1[20]; struct packed_git *p; }; @@ -358,7 +358,7 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s if (tail <= bufptr + tree_entry_len + 1 || memcmp(bufptr, "tree ", 5) || bufptr[tree_entry_len] != '\n') return error("bogus commit object %s", oid_to_hex(&item->object.oid)); - if (get_sha1_hex(bufptr + 5, parent.hash) < 0) + if (get_oid_hex(bufptr + 5, &parent) < 0) return error("bad tree pointer in commit %s", oid_to_hex(&item->object.oid)); item->maybe_tree = lookup_tree(&parent); @@ -370,7 +370,7 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s struct commit *new_parent; if (tail <= bufptr + parent_entry_len + 1 || - get_sha1_hex(bufptr + 7, parent.hash) || + get_oid_hex(bufptr + 7, &parent) || bufptr[parent_entry_len] != '\n') return error("bad parents in commit %s", oid_to_hex(&item->object.oid)); bufptr += parent_entry_len + 1; @@ -3472,7 +3472,7 @@ static int reuse_worktree_file(const char *name, const struct object_id *oid, in * objects however would tend to be slower as they need * to be individually opened and inflated. */ - if (!FAST_WORKING_DIRECTORY && !want_file && has_sha1_pack(oid->hash)) + if (!FAST_WORKING_DIRECTORY && !want_file && has_object_pack(oid)) return 0; /* @@ -3898,13 +3898,14 @@ static void fill_metainfo(struct strbuf *msg, *must_show_header = 0; } if (one && two && oidcmp(&one->oid, &two->oid)) { - int abbrev = o->flags.full_index ? 40 : DEFAULT_ABBREV; + const unsigned hexsz = the_hash_algo->hexsz; + int abbrev = o->flags.full_index ? hexsz : DEFAULT_ABBREV; if (o->flags.binary) { mmfile_t mf; if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) || (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two))) - abbrev = 40; + abbrev = hexsz; } strbuf_addf(msg, "%s%sindex %s..%s", line_prefix, set, diff_abbrev_oid(&one->oid, abbrev), @@ -4139,6 +4140,11 @@ void diff_setup_done(struct diff_options *options) DIFF_FORMAT_NAME_STATUS | DIFF_FORMAT_CHECKDIFF | DIFF_FORMAT_NO_OUTPUT; + /* + * This must be signed because we're comparing against a potentially + * negative value. + */ + const int hexsz = the_hash_algo->hexsz; if (options->set_default) options->set_default(options); @@ -4219,8 +4225,8 @@ void diff_setup_done(struct diff_options *options) */ read_cache(); } - if (40 < options->abbrev) - options->abbrev = 40; /* full */ + if (hexsz < options->abbrev) + options->abbrev = hexsz; /* full */ /* * It does not make sense to show the first hit we happened @@ -4798,8 +4804,8 @@ int diff_opt_parse(struct diff_options *options, options->abbrev = strtoul(arg, NULL, 10); if (options->abbrev < MINIMUM_ABBREV) options->abbrev = MINIMUM_ABBREV; - else if (40 < options->abbrev) - options->abbrev = 40; + else if (the_hash_algo->hexsz < options->abbrev) + options->abbrev = the_hash_algo->hexsz; } else if ((argcount = parse_long_opt("src-prefix", av, &optarg))) { options->a_prefix = optarg; @@ -829,7 +829,7 @@ static int add_excludes(const char *fname, const char *base, int baselen, if (size == 0) { if (oid_stat) { fill_stat_data(&oid_stat->stat, &st); - oidcpy(&oid_stat->oid, &empty_blob_oid); + oidcpy(&oid_stat->oid, the_hash_algo->empty_blob); oid_stat->valid = 1; } close(fd); @@ -1241,11 +1241,11 @@ static void prep_exclude(struct dir_struct *dir, (!untracked || !untracked->valid || /* * .. and .gitignore does not exist before - * (i.e. null exclude_sha1). Then we can skip + * (i.e. null exclude_oid). Then we can skip * loading .gitignore, which would result in * ENOENT anyway. */ - !is_null_sha1(untracked->exclude_sha1))) { + !is_null_oid(&untracked->exclude_oid))) { /* * dir->basebuf gets reused by the traversal, but we * need fname to remain unchanged to ensure the src @@ -1276,9 +1276,9 @@ static void prep_exclude(struct dir_struct *dir, * order, though, if you do that. */ if (untracked && - hashcmp(oid_stat.oid.hash, untracked->exclude_sha1)) { + oidcmp(&oid_stat.oid, &untracked->exclude_oid)) { invalidate_gitignore(dir->untracked, untracked); - hashcpy(untracked->exclude_sha1, oid_stat.oid.hash); + oidcpy(&untracked->exclude_oid, &oid_stat.oid); } dir->exclude_stack = stk; current = stk->baselen; @@ -2623,9 +2623,10 @@ static void write_one_dir(struct untracked_cache_dir *untracked, stat_data_to_disk(&stat_data, &untracked->stat_data); strbuf_add(&wd->sb_stat, &stat_data, sizeof(stat_data)); } - if (!is_null_sha1(untracked->exclude_sha1)) { + if (!is_null_oid(&untracked->exclude_oid)) { ewah_set(wd->sha1_valid, i); - strbuf_add(&wd->sb_sha1, untracked->exclude_sha1, 20); + strbuf_add(&wd->sb_sha1, untracked->exclude_oid.hash, + the_hash_algo->rawsz); } intlen = encode_varint(untracked->untracked_nr, intbuf); @@ -2826,16 +2827,16 @@ static void read_stat(size_t pos, void *cb) ud->valid = 1; } -static void read_sha1(size_t pos, void *cb) +static void read_oid(size_t pos, void *cb) { struct read_data *rd = cb; struct untracked_cache_dir *ud = rd->ucd[pos]; - if (rd->data + 20 > rd->end) { + if (rd->data + the_hash_algo->rawsz > rd->end) { rd->data = rd->end + 1; return; } - hashcpy(ud->exclude_sha1, rd->data); - rd->data += 20; + hashcpy(ud->exclude_oid.hash, rd->data); + rd->data += the_hash_algo->rawsz; } static void load_oid_stat(struct oid_stat *oid_stat, const unsigned char *data, @@ -2918,7 +2919,7 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long ewah_each_bit(rd.check_only, set_check_only, &rd); rd.data = next + len; ewah_each_bit(rd.valid, read_stat, &rd); - ewah_each_bit(rd.sha1_valid, read_sha1, &rd); + ewah_each_bit(rd.sha1_valid, read_oid, &rd); next = rd.data; done: @@ -3,6 +3,7 @@ /* See Documentation/technical/api-directory-listing.txt */ +#include "cache.h" #include "strbuf.h" struct dir_entry { @@ -118,8 +119,8 @@ struct untracked_cache_dir { /* all data except 'dirs' in this struct are good */ unsigned int valid : 1; unsigned int recurse : 1; - /* null SHA-1 means this directory does not have .gitignore */ - unsigned char exclude_sha1[20]; + /* null object ID means this directory does not have .gitignore */ + struct object_id exclude_oid; char name[FLEX_ARRAY]; }; @@ -734,30 +734,31 @@ static int fsck_ident(const char **ident, struct object *obj, struct fsck_option static int fsck_commit_buffer(struct commit *commit, const char *buffer, unsigned long size, struct fsck_options *options) { - unsigned char tree_sha1[20], sha1[20]; + struct object_id tree_oid, oid; struct commit_graft *graft; unsigned parent_count, parent_line_count = 0, author_count; int err; const char *buffer_begin = buffer; + const char *p; if (verify_headers(buffer, size, &commit->object, options)) return -1; if (!skip_prefix(buffer, "tree ", &buffer)) return report(options, &commit->object, FSCK_MSG_MISSING_TREE, "invalid format - expected 'tree' line"); - if (get_sha1_hex(buffer, tree_sha1) || buffer[40] != '\n') { + if (parse_oid_hex(buffer, &tree_oid, &p) || *p != '\n') { err = report(options, &commit->object, FSCK_MSG_BAD_TREE_SHA1, "invalid 'tree' line format - bad sha1"); if (err) return err; } - buffer += 41; + buffer = p + 1; while (skip_prefix(buffer, "parent ", &buffer)) { - if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') { + if (parse_oid_hex(buffer, &oid, &p) || *p != '\n') { err = report(options, &commit->object, FSCK_MSG_BAD_PARENT_SHA1, "invalid 'parent' line format - bad sha1"); if (err) return err; } - buffer += 41; + buffer = p + 1; parent_line_count++; } graft = lookup_commit_graft(&commit->object.oid); @@ -796,7 +797,7 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer, if (err) return err; if (!get_commit_tree(commit)) { - err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", sha1_to_hex(tree_sha1)); + err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", oid_to_hex(&tree_oid)); if (err) return err; } @@ -822,11 +823,12 @@ static int fsck_commit(struct commit *commit, const char *data, static int fsck_tag_buffer(struct tag *tag, const char *data, unsigned long size, struct fsck_options *options) { - unsigned char sha1[20]; + struct object_id oid; int ret = 0; const char *buffer; char *to_free = NULL, *eol; struct strbuf sb = STRBUF_INIT; + const char *p; if (data) buffer = data; @@ -857,12 +859,12 @@ static int fsck_tag_buffer(struct tag *tag, const char *data, ret = report(options, &tag->object, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line"); goto done; } - if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') { + if (parse_oid_hex(buffer, &oid, &p) || *p != '\n') { ret = report(options, &tag->object, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1"); if (ret) goto done; } - buffer += 41; + buffer = p + 1; if (!skip_prefix(buffer, "type ", &buffer)) { ret = report(options, &tag->object, FSCK_MSG_MISSING_TYPE_ENTRY, "invalid format - expected 'type' line"); diff --git a/git-add--interactive.perl b/git-add--interactive.perl index c1f52e457f..36f38ced90 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -205,8 +205,15 @@ my $status_head = sprintf($status_fmt, __('staged'), __('unstaged'), __('path')) } } -sub get_empty_tree { - return '4b825dc642cb6eb9a060e54bf8d69288fbee4904'; +{ + my $empty_tree; + sub get_empty_tree { + return $empty_tree if defined $empty_tree; + + $empty_tree = run_cmd_pipe(qw(git hash-object -t tree /dev/null)); + chomp $empty_tree; + return $empty_tree; + } } sub get_diff_reference { diff --git a/git-filter-branch.sh b/git-filter-branch.sh index 64f21547c1..ccceaf19a7 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -11,6 +11,8 @@ # The following functions will also be available in the commit filter: functions=$(cat << \EOF +EMPTY_TREE=$(git hash-object -t tree /dev/null) + warn () { echo "$*" >&2 } @@ -46,7 +48,7 @@ git_commit_non_empty_tree() { if test $# = 3 && test "$1" = $(git rev-parse "$3^{tree}"); then map "$3" - elif test $# = 1 && test "$1" = 4b825dc642cb6eb9a060e54bf8d69288fbee4904; then + elif test $# = 1 && test "$1" = $EMPTY_TREE; then : else git commit-tree "$@" diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh index 9879c59395..f6d9852d2f 100755 --- a/git-merge-one-file.sh +++ b/git-merge-one-file.sh @@ -120,7 +120,7 @@ case "${1:-.}${2:-.}${3:-.}" in case "$1" in '') echo "Added $4 in both, but differently." - orig=$(git unpack-file e69de29bb2d1d6434b8b29ae775ad8c2e48c5391) + orig=$(git unpack-file $(git hash-object /dev/null)) ;; *) echo "Auto-merging $4" diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 2f4941d0fc..0c92ac00fa 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -81,6 +81,8 @@ rewritten_pending="$state_dir"/rewritten-pending # and leaves CR at the end instead. cr=$(printf "\015") +empty_tree=$(git hash-object -t tree /dev/null) + strategy_args=${strategy:+--strategy=$strategy} test -n "$strategy_opts" && eval ' @@ -244,7 +246,7 @@ is_empty_commit() { die "$(eval_gettext "\$sha1: not a commit that can be picked")" } ptree=$(git rev-parse -q --verify "$1"^^{tree} 2>/dev/null) || - ptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904 + ptree=$empty_tree test "$tree" = "$ptree" } @@ -2038,7 +2038,8 @@ int http_get_info_packs(const char *base_url, struct packed_git **packs_head) int ret = 0, i = 0; char *url, *data; struct strbuf buf = STRBUF_INIT; - unsigned char sha1[20]; + unsigned char hash[GIT_MAX_RAWSZ]; + const unsigned hexsz = the_hash_algo->hexsz; end_url_with_slash(&buf, base_url); strbuf_addstr(&buf, "objects/info/packs"); @@ -2054,13 +2055,13 @@ int http_get_info_packs(const char *base_url, struct packed_git **packs_head) switch (data[i]) { case 'P': i++; - if (i + 52 <= buf.len && + if (i + hexsz + 12 <= buf.len && starts_with(data + i, " pack-") && - starts_with(data + i + 46, ".pack\n")) { - get_sha1_hex(data + i + 6, sha1); - fetch_and_setup_pack_index(packs_head, sha1, + starts_with(data + i + hexsz + 6, ".pack\n")) { + get_sha1_hex(data + i + 6, hash); + fetch_and_setup_pack_index(packs_head, hash, base_url); - i += 51; + i += hexsz + 11; break; } default: @@ -11,10 +11,7 @@ static const char *merge_argument(struct commit *commit) { - if (commit) - return oid_to_hex(&commit->object.oid); - else - return EMPTY_TREE_SHA1_HEX; + return oid_to_hex(commit ? &commit->object.oid : the_hash_algo->empty_tree); } int index_has_changes(struct strbuf *sb) diff --git a/packfile.c b/packfile.c index d625481b7a..1a714fbde9 100644 --- a/packfile.c +++ b/packfile.c @@ -84,6 +84,7 @@ static int check_packed_git_idx(const char *path, struct packed_git *p) uint32_t version, nr, i, *index; int fd = git_open(path); struct stat st; + const unsigned int hashsz = the_hash_algo->rawsz; if (fd < 0) return -1; @@ -92,7 +93,7 @@ static int check_packed_git_idx(const char *path, struct packed_git *p) return -1; } idx_size = xsize_t(st.st_size); - if (idx_size < 4 * 256 + 20 + 20) { + if (idx_size < 4 * 256 + hashsz + hashsz) { close(fd); return error("index file %s is too small", path); } @@ -129,11 +130,11 @@ static int check_packed_git_idx(const char *path, struct packed_git *p) /* * Total size: * - 256 index entries 4 bytes each - * - 24-byte entries * nr (20-byte sha1 + 4-byte offset) - * - 20-byte SHA1 of the packfile - * - 20-byte SHA1 file checksum + * - 24-byte entries * nr (object ID + 4-byte offset) + * - hash of the packfile + * - file checksum */ - if (idx_size != 4*256 + nr * 24 + 20 + 20) { + if (idx_size != 4*256 + nr * (hashsz + 4) + hashsz + hashsz) { munmap(idx_map, idx_size); return error("wrong index v1 file size in %s", path); } @@ -142,16 +143,16 @@ static int check_packed_git_idx(const char *path, struct packed_git *p) * Minimum size: * - 8 bytes of header * - 256 index entries 4 bytes each - * - 20-byte sha1 entry * nr + * - object ID entry * nr * - 4-byte crc entry * nr * - 4-byte offset entry * nr - * - 20-byte SHA1 of the packfile - * - 20-byte SHA1 file checksum + * - hash of the packfile + * - file checksum * And after the 4-byte offset table might be a * variable sized table containing 8-byte entries * for offsets larger than 2^31. */ - unsigned long min_size = 8 + 4*256 + nr*(20 + 4 + 4) + 20 + 20; + unsigned long min_size = 8 + 4*256 + nr*(hashsz + 4 + 4) + hashsz + hashsz; unsigned long max_size = min_size; if (nr) max_size += (nr - 1)*8; @@ -444,10 +445,11 @@ static int open_packed_git_1(struct packed_git *p) { struct stat st; struct pack_header hdr; - unsigned char sha1[20]; - unsigned char *idx_sha1; + unsigned char hash[GIT_MAX_RAWSZ]; + unsigned char *idx_hash; long fd_flag; ssize_t read_result; + const unsigned hashsz = the_hash_algo->rawsz; if (!p->index_data && open_pack_index(p)) return error("packfile %s index unavailable", p->pack_name); @@ -507,15 +509,15 @@ static int open_packed_git_1(struct packed_git *p) " while index indicates %"PRIu32" objects", p->pack_name, ntohl(hdr.hdr_entries), p->num_objects); - if (lseek(p->pack_fd, p->pack_size - sizeof(sha1), SEEK_SET) == -1) + if (lseek(p->pack_fd, p->pack_size - hashsz, SEEK_SET) == -1) return error("end of packfile %s is unavailable", p->pack_name); - read_result = read_in_full(p->pack_fd, sha1, sizeof(sha1)); + read_result = read_in_full(p->pack_fd, hash, hashsz); if (read_result < 0) return error_errno("error reading from %s", p->pack_name); - if (read_result != sizeof(sha1)) + if (read_result != hashsz) return error("packfile %s signature is unavailable", p->pack_name); - idx_sha1 = ((unsigned char *)p->index_data) + p->index_size - 40; - if (hashcmp(sha1, idx_sha1)) + idx_hash = ((unsigned char *)p->index_data) + p->index_size - hashsz * 2; + if (hashcmp(hash, idx_hash)) return error("packfile %s does not match index", p->pack_name); return 0; } @@ -530,7 +532,7 @@ static int open_packed_git(struct packed_git *p) static int in_window(struct pack_window *win, off_t offset) { - /* We must promise at least 20 bytes (one hash) after the + /* We must promise at least one full hash after the * offset is available from this window, otherwise the offset * is not actually in this window and a different window (which * has that one hash excess) must be used. This is to support @@ -538,7 +540,7 @@ static int in_window(struct pack_window *win, off_t offset) */ off_t win_off = win->offset; return win_off <= offset - && (offset + 20) <= (win_off + win->len); + && (offset + the_hash_algo->rawsz) <= (win_off + win->len); } unsigned char *use_pack(struct packed_git *p, @@ -555,7 +557,7 @@ unsigned char *use_pack(struct packed_git *p, */ if (!p->pack_size && p->pack_fd == -1 && open_packed_git(p)) die("packfile %s cannot be accessed", p->pack_name); - if (offset > (p->pack_size - 20)) + if (offset > (p->pack_size - the_hash_algo->rawsz)) die("offset beyond end of packfile (truncated pack?)"); if (offset < 0) die(_("offset before end of packfile (broken .idx?)")); @@ -675,7 +677,8 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local) p->pack_size = st.st_size; p->pack_local = local; p->mtime = st.st_mtime; - if (path_len < 40 || get_sha1_hex(path + path_len - 40, p->sha1)) + if (path_len < the_hash_algo->hexsz || + get_sha1_hex(path + path_len - the_hash_algo->hexsz, p->sha1)) hashclr(p->sha1); return p; } @@ -1028,7 +1031,8 @@ const struct packed_git *has_packed_and_bad(const unsigned char *sha1) for (p = the_repository->objects->packed_git; p; p = p->next) for (i = 0; i < p->num_bad_objects; i++) - if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i)) + if (!hashcmp(sha1, + p->bad_object_sha1 + the_hash_algo->rawsz * i)) return p; return NULL; } @@ -1066,7 +1070,7 @@ static off_t get_delta_base(struct packed_git *p, } else if (type == OBJ_REF_DELTA) { /* The base entry _must_ be in the same pack */ base_offset = find_pack_entry_one(base_info, p); - *curpos += 20; + *curpos += the_hash_algo->rawsz; } else die("I am totally screwed"); return base_offset; @@ -1677,6 +1681,7 @@ int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32 { const unsigned char *index_fanout = p->index_data; const unsigned char *index_lookup; + const unsigned int hashsz = the_hash_algo->rawsz; int index_lookup_width; if (!index_fanout) @@ -1684,10 +1689,10 @@ int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32 index_lookup = index_fanout + 4 * 256; if (p->index_version == 1) { - index_lookup_width = 24; + index_lookup_width = hashsz + 4; index_lookup += 4; } else { - index_lookup_width = 20; + index_lookup_width = hashsz; index_fanout += 8; index_lookup += 8; } @@ -1700,6 +1705,7 @@ const unsigned char *nth_packed_object_sha1(struct packed_git *p, uint32_t n) { const unsigned char *index = p->index_data; + const unsigned int hashsz = the_hash_algo->rawsz; if (!index) { if (open_pack_index(p)) return NULL; @@ -1709,10 +1715,10 @@ const unsigned char *nth_packed_object_sha1(struct packed_git *p, return NULL; index += 4 * 256; if (p->index_version == 1) { - return index + 24 * n + 4; + return index + (hashsz + 4) * n + 4; } else { index += 8; - return index + 20 * n; + return index + hashsz * n; } } @@ -1744,12 +1750,13 @@ void check_pack_index_ptr(const struct packed_git *p, const void *vptr) off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n) { const unsigned char *index = p->index_data; + const unsigned int hashsz = the_hash_algo->rawsz; index += 4 * 256; if (p->index_version == 1) { - return ntohl(*((uint32_t *)(index + 24 * n))); + return ntohl(*((uint32_t *)(index + (hashsz + 4) * n))); } else { uint32_t off; - index += 8 + p->num_objects * (20 + 4); + index += 8 + p->num_objects * (hashsz + 4); off = ntohl(*((uint32_t *)(index + 4 * n))); if (!(off & 0x80000000)) return off; @@ -1811,7 +1818,7 @@ struct packed_git *find_sha1_pack(const unsigned char *sha1, } -static int fill_pack_entry(const unsigned char *sha1, +static int fill_pack_entry(const struct object_id *oid, struct pack_entry *e, struct packed_git *p) { @@ -1820,11 +1827,12 @@ static int fill_pack_entry(const unsigned char *sha1, if (p->num_bad_objects) { unsigned i; for (i = 0; i < p->num_bad_objects; i++) - if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i)) + if (!hashcmp(oid->hash, + p->bad_object_sha1 + the_hash_algo->rawsz * i)) return 0; } - offset = find_pack_entry_one(sha1, p); + offset = find_pack_entry_one(oid->hash, p); if (!offset) return 0; @@ -1839,11 +1847,10 @@ static int fill_pack_entry(const unsigned char *sha1, return 0; e->offset = offset; e->p = p; - hashcpy(e->sha1, sha1); return 1; } -int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e) +int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e) { struct list_head *pos; @@ -1853,7 +1860,7 @@ int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack list_for_each(pos, &r->objects->packed_git_mru) { struct packed_git *p = list_entry(pos, struct packed_git, mru); - if (fill_pack_entry(sha1, e, p)) { + if (fill_pack_entry(oid, e, p)) { list_move(&p->mru, &r->objects->packed_git_mru); return 1; } @@ -1861,10 +1868,10 @@ int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack return 0; } -int has_sha1_pack(const unsigned char *sha1) +int has_object_pack(const struct object_id *oid) { struct pack_entry e; - return find_pack_entry(the_repository, sha1, &e); + return find_pack_entry(the_repository, oid, &e); } int has_pack_index(const unsigned char *sha1) diff --git a/packfile.h b/packfile.h index bfd0b5399d..e0a38aba93 100644 --- a/packfile.h +++ b/packfile.h @@ -137,9 +137,9 @@ extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1); * Iff a pack file in the given repository contains the object named by sha1, * return true and store its location to e. */ -extern int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e); +extern int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e); -extern int has_sha1_pack(const unsigned char *sha1); +extern int has_object_pack(const struct object_id *oid); extern int has_pack_index(const unsigned char *sha1); diff --git a/read-cache.c b/read-cache.c index cebd24849d..372588260e 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1831,7 +1831,7 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist) if (verify_hdr(hdr, mmap_size) < 0) goto unmap; - hashcpy(istate->sha1, (const unsigned char *)hdr + mmap_size - the_hash_algo->rawsz); + hashcpy(istate->oid.hash, (const unsigned char *)hdr + mmap_size - the_hash_algo->rawsz); istate->version = ntohl(hdr->hdr_version); istate->cache_nr = ntohl(hdr->hdr_entries); istate->cache_alloc = alloc_nr(istate->cache_nr); @@ -1903,7 +1903,7 @@ int read_index_from(struct index_state *istate, const char *path, uint64_t start = getnanotime(); struct split_index *split_index; int ret; - char *base_sha1_hex; + char *base_oid_hex; char *base_path; /* istate->initialized covers both .git/index and .git/sharedindex.xxx */ @@ -1914,7 +1914,7 @@ int read_index_from(struct index_state *istate, const char *path, trace_performance_since(start, "read cache %s", path); split_index = istate->split_index; - if (!split_index || is_null_sha1(split_index->base_sha1)) { + if (!split_index || is_null_oid(&split_index->base_oid)) { post_read_index_from(istate); return ret; } @@ -1924,13 +1924,13 @@ int read_index_from(struct index_state *istate, const char *path, else split_index->base = xcalloc(1, sizeof(*split_index->base)); - base_sha1_hex = sha1_to_hex(split_index->base_sha1); - base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_sha1_hex); + base_oid_hex = oid_to_hex(&split_index->base_oid); + base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_oid_hex); ret = do_read_index(split_index->base, base_path, 1); - if (hashcmp(split_index->base_sha1, split_index->base->sha1)) + if (oidcmp(&split_index->base_oid, &split_index->base->oid)) die("broken index, expect %s in %s, got %s", - base_sha1_hex, base_path, - sha1_to_hex(split_index->base->sha1)); + base_oid_hex, base_path, + oid_to_hex(&split_index->base->oid)); freshen_shared_index(base_path, 0); merge_base_index(istate); @@ -2219,7 +2219,7 @@ static int verify_index_from(const struct index_state *istate, const char *path) if (n != the_hash_algo->rawsz) goto out; - if (hashcmp(istate->sha1, hash)) + if (hashcmp(istate->oid.hash, hash)) goto out; close(fd); @@ -2398,7 +2398,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile, return -1; } - if (ce_flush(&c, newfd, istate->sha1)) + if (ce_flush(&c, newfd, istate->oid.hash)) return -1; if (close_tempfile_gently(tempfile)) { error(_("could not close '%s'"), tempfile->filename.buf); @@ -2522,10 +2522,10 @@ static int write_shared_index(struct index_state *istate, return ret; } ret = rename_tempfile(temp, - git_path("sharedindex.%s", sha1_to_hex(si->base->sha1))); + git_path("sharedindex.%s", oid_to_hex(&si->base->oid))); if (!ret) { - hashcpy(si->base_sha1, si->base->sha1); - clean_shared_index_files(sha1_to_hex(si->base->sha1)); + oidcpy(&si->base_oid, &si->base->oid); + clean_shared_index_files(oid_to_hex(&si->base->oid)); } return ret; @@ -2579,13 +2579,13 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock, if (!si || alternate_index_output || (istate->cache_changed & ~EXTMASK)) { if (si) - hashclr(si->base_sha1); + oidclr(&si->base_oid); ret = do_write_locked_index(istate, lock, flags); goto out; } if (git_env_bool("GIT_TEST_SPLIT_INDEX", 0)) { - int v = si->base_sha1[0]; + int v = si->base_oid.hash[0]; if ((v & 15) < 6) istate->cache_changed |= SPLIT_INDEX_ORDERED; } @@ -2600,7 +2600,7 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock, temp = mks_tempfile(git_path("sharedindex_XXXXXX")); if (!temp) { - hashclr(si->base_sha1); + oidclr(&si->base_oid); ret = do_write_locked_index(istate, lock, flags); goto out; } @@ -2620,7 +2620,7 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock, /* Freshen the shared index only if the split-index was written */ if (!ret && !new_shared_index) { const char *shared_index = git_path("sharedindex.%s", - sha1_to_hex(si->base_sha1)); + oid_to_hex(&si->base_oid)); freshen_shared_index(shared_index, 1); } diff --git a/resolve-undo.c b/resolve-undo.c index aed95b4b35..fc5b3b83d9 100644 --- a/resolve-undo.c +++ b/resolve-undo.c @@ -90,7 +90,7 @@ struct string_list *resolve_undo_read(const char *data, unsigned long size) continue; if (size < rawsz) goto error; - memcpy(ui->oid[i].hash, (const unsigned char *)data, rawsz); + oidread(&ui->oid[i], (const unsigned char *)data); size -= rawsz; data += rawsz; } diff --git a/revision.c b/revision.c index 5112c9af9b..40fd91ff2b 100644 --- a/revision.c +++ b/revision.c @@ -1762,6 +1762,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg const char *arg = argv[0]; const char *optarg; int argcount; + const unsigned hexsz = the_hash_algo->hexsz; /* pseudo revision arguments */ if (!strcmp(arg, "--all") || !strcmp(arg, "--branches") || @@ -2049,8 +2050,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->abbrev = strtoul(optarg, NULL, 10); if (revs->abbrev < MINIMUM_ABBREV) revs->abbrev = MINIMUM_ABBREV; - else if (revs->abbrev > 40) - revs->abbrev = 40; + else if (revs->abbrev > hexsz) + revs->abbrev = hexsz; } else if (!strcmp(arg, "--abbrev-commit")) { revs->abbrev_commit = 1; revs->abbrev_commit_given = 1; @@ -3097,7 +3098,7 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi { if (commit->object.flags & SHOWN) return commit_ignore; - if (revs->unpacked && has_sha1_pack(commit->object.oid.hash)) + if (revs->unpacked && has_object_pack(&commit->object.oid)) return commit_ignore; if (commit->object.flags & UNINTERESTING) return commit_ignore; diff --git a/sequencer.c b/sequencer.c index abb6c5dc26..72b4d8ecae 100644 --- a/sequencer.c +++ b/sequencer.c @@ -1247,7 +1247,7 @@ static int try_to_commit(struct strbuf *msg, const char *author, if (!(flags & ALLOW_EMPTY) && !oidcmp(current_head ? get_commit_tree_oid(current_head) : - &empty_tree_oid, &tree)) { + the_hash_algo->empty_tree, &tree)) { res = 1; /* run 'git commit' to display error message */ goto out; } @@ -1639,7 +1639,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit, unborn = 1; } else if (unborn) oidcpy(&head, the_hash_algo->empty_tree); - if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD", + if (index_differs_from(unborn ? empty_tree_oid_hex() : "HEAD", NULL, 0)) return error_dirty_index(opts); } diff --git a/server-info.c b/server-info.c index 83460ec0d6..7ce6dcd67b 100644 --- a/server-info.c +++ b/server-info.c @@ -92,8 +92,6 @@ static struct pack_info { int old_num; int new_num; int nr_alloc; - int nr_heads; - unsigned char (*head)[20]; } **info; static int num_pack; static const char *objdir; @@ -225,12 +223,9 @@ static void init_pack_info(const char *infofile, int force) else stale = 1; - for (i = 0; i < num_pack; i++) { - if (stale) { + for (i = 0; i < num_pack; i++) + if (stale) info[i]->old_num = -1; - info[i]->nr_heads = 0; - } - } /* renumber them */ QSORT(info, num_pack, compare_info); diff --git a/sha1-file.c b/sha1-file.c index e47098eff2..555e780f4b 100644 --- a/sha1-file.c +++ b/sha1-file.c @@ -36,12 +36,21 @@ /* The maximum size for an object header. */ #define MAX_HEADER_LEN 32 + +#define EMPTY_TREE_SHA1_BIN_LITERAL \ + "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \ + "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04" + +#define EMPTY_BLOB_SHA1_BIN_LITERAL \ + "\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \ + "\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91" + const unsigned char null_sha1[GIT_MAX_RAWSZ]; const struct object_id null_oid; -const struct object_id empty_tree_oid = { +static const struct object_id empty_tree_oid = { EMPTY_TREE_SHA1_BIN_LITERAL }; -const struct object_id empty_blob_oid = { +static const struct object_id empty_blob_oid = { EMPTY_BLOB_SHA1_BIN_LITERAL }; @@ -101,6 +110,18 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { }, }; +const char *empty_tree_oid_hex(void) +{ + static char buf[GIT_MAX_HEXSZ + 1]; + return oid_to_hex_r(buf, the_hash_algo->empty_tree); +} + +const char *empty_blob_oid_hex(void) +{ + static char buf[GIT_MAX_HEXSZ + 1]; + return oid_to_hex_r(buf, the_hash_algo->empty_blob); +} + /* * This is meant to hold a *small* number of objects that you would * want read_sha1_file() to be able to return, but yet you do not want @@ -108,7 +129,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { * application). */ static struct cached_object { - unsigned char sha1[20]; + struct object_id oid; enum object_type type; void *buf; unsigned long size; @@ -116,22 +137,22 @@ static struct cached_object { static int cached_object_nr, cached_object_alloc; static struct cached_object empty_tree = { - EMPTY_TREE_SHA1_BIN_LITERAL, + { EMPTY_TREE_SHA1_BIN_LITERAL }, OBJ_TREE, "", 0 }; -static struct cached_object *find_cached_object(const unsigned char *sha1) +static struct cached_object *find_cached_object(const struct object_id *oid) { int i; struct cached_object *co = cached_objects; for (i = 0; i < cached_object_nr; i++, co++) { - if (!hashcmp(co->sha1, sha1)) + if (!oidcmp(&co->oid, oid)) return co; } - if (!hashcmp(sha1, empty_tree.sha1)) + if (!oidcmp(oid, the_hash_algo->empty_tree)) return &empty_tree; return NULL; } @@ -710,42 +731,42 @@ int check_and_freshen_file(const char *fn, int freshen) return 1; } -static int check_and_freshen_local(const unsigned char *sha1, int freshen) +static int check_and_freshen_local(const struct object_id *oid, int freshen) { static struct strbuf buf = STRBUF_INIT; strbuf_reset(&buf); - sha1_file_name(the_repository, &buf, sha1); + sha1_file_name(the_repository, &buf, oid->hash); return check_and_freshen_file(buf.buf, freshen); } -static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen) +static int check_and_freshen_nonlocal(const struct object_id *oid, int freshen) { struct alternate_object_database *alt; prepare_alt_odb(the_repository); for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) { - const char *path = alt_sha1_path(alt, sha1); + const char *path = alt_sha1_path(alt, oid->hash); if (check_and_freshen_file(path, freshen)) return 1; } return 0; } -static int check_and_freshen(const unsigned char *sha1, int freshen) +static int check_and_freshen(const struct object_id *oid, int freshen) { - return check_and_freshen_local(sha1, freshen) || - check_and_freshen_nonlocal(sha1, freshen); + return check_and_freshen_local(oid, freshen) || + check_and_freshen_nonlocal(oid, freshen); } -int has_loose_object_nonlocal(const unsigned char *sha1) +int has_loose_object_nonlocal(const struct object_id *oid) { - return check_and_freshen_nonlocal(sha1, 0); + return check_and_freshen_nonlocal(oid, 0); } -static int has_loose_object(const unsigned char *sha1) +static int has_loose_object(const struct object_id *oid) { - return check_and_freshen(sha1, 0); + return check_and_freshen(oid, 0); } static void mmap_limit_check(size_t length) @@ -1250,7 +1271,7 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid, oi = &blank_oi; if (!(flags & OBJECT_INFO_SKIP_CACHED)) { - struct cached_object *co = find_cached_object(real->hash); + struct cached_object *co = find_cached_object(real); if (co) { if (oi->typep) *(oi->typep) = co->type; @@ -1270,7 +1291,7 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid, } while (1) { - if (find_pack_entry(r, real->hash, &e)) + if (find_pack_entry(r, real, &e)) break; if (flags & OBJECT_INFO_IGNORE_LOOSE) @@ -1283,7 +1304,7 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid, /* Not a loose object; someone else may have just packed it. */ if (!(flags & OBJECT_INFO_QUICK)) { reprepare_packed_git(r); - if (find_pack_entry(r, real->hash, &e)) + if (find_pack_entry(r, real, &e)) break; } @@ -1363,7 +1384,7 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type, struct cached_object *co; hash_object_file(buf, len, type_name(type), oid); - if (has_sha1_file(oid->hash) || find_cached_object(oid->hash)) + if (has_sha1_file(oid->hash) || find_cached_object(oid)) return 0; ALLOC_GROW(cached_objects, cached_object_nr + 1, cached_object_alloc); co = &cached_objects[cached_object_nr++]; @@ -1371,7 +1392,7 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type, co->type = type; co->buf = xmalloc(len); memcpy(co->buf, buf, len); - hashcpy(co->sha1, oid->hash); + oidcpy(&co->oid, oid); return 0; } @@ -1667,15 +1688,15 @@ static int write_loose_object(const struct object_id *oid, char *hdr, return finalize_object_file(tmp_file.buf, filename.buf); } -static int freshen_loose_object(const unsigned char *sha1) +static int freshen_loose_object(const struct object_id *oid) { - return check_and_freshen(sha1, 1); + return check_and_freshen(oid, 1); } -static int freshen_packed_object(const unsigned char *sha1) +static int freshen_packed_object(const struct object_id *oid) { struct pack_entry e; - if (!find_pack_entry(the_repository, sha1, &e)) + if (!find_pack_entry(the_repository, oid, &e)) return 0; if (e.p->freshened) return 1; @@ -1695,7 +1716,7 @@ int write_object_file(const void *buf, unsigned long len, const char *type, * it out into .git/objects/??/?{38} file. */ write_object_file_prepare(buf, len, type, oid, hdr, &hdrlen); - if (freshen_packed_object(oid->hash) || freshen_loose_object(oid->hash)) + if (freshen_packed_object(oid) || freshen_loose_object(oid)) return 0; return write_loose_object(oid, hdr, hdrlen, buf, len, 0); } @@ -1714,7 +1735,7 @@ int hash_object_file_literally(const void *buf, unsigned long len, if (!(flags & HASH_WRITE_OBJECT)) goto cleanup; - if (freshen_packed_object(oid->hash) || freshen_loose_object(oid->hash)) + if (freshen_packed_object(oid) || freshen_loose_object(oid)) goto cleanup; status = write_loose_object(oid, header, hdrlen, buf, len, 0); @@ -1732,7 +1753,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime) int hdrlen; int ret; - if (has_loose_object(oid->hash)) + if (has_loose_object(oid)) return 0; buf = read_object(oid->hash, &type, &len); if (!buf) diff --git a/sha1-name.c b/sha1-name.c index 60b8a935cc..cc0028ed19 100644 --- a/sha1-name.c +++ b/sha1-name.c @@ -1685,8 +1685,8 @@ static int get_oid_with_context_1(const char *name, if (new_filename) filename = new_filename; if (flags & GET_OID_FOLLOW_SYMLINKS) { - ret = get_tree_entry_follow_symlinks(tree_oid.hash, - filename, oid->hash, &oc->symlink_path, + ret = get_tree_entry_follow_symlinks(&tree_oid, + filename, oid, &oc->symlink_path, &oc->mode); } else { ret = get_tree_entry(&tree_oid, filename, oid, @@ -1698,7 +1698,6 @@ static int get_oid_with_context_1(const char *name, name, len); } } - hashcpy(oc->tree, tree_oid.hash); if (flags & GET_OID_RECORD_PATH) oc->path = xstrdup(filename); diff --git a/split-index.c b/split-index.c index 3eb8ff1b43..660c75f31f 100644 --- a/split-index.c +++ b/split-index.c @@ -18,12 +18,12 @@ int read_link_extension(struct index_state *istate, struct split_index *si; int ret; - if (sz < 20) + if (sz < the_hash_algo->rawsz) return error("corrupt link extension (too short)"); si = init_split_index(istate); - hashcpy(si->base_sha1, data); - data += 20; - sz -= 20; + hashcpy(si->base_oid.hash, data); + data += the_hash_algo->rawsz; + sz -= the_hash_algo->rawsz; if (!sz) return 0; si->delete_bitmap = ewah_new(); @@ -45,7 +45,7 @@ int write_link_extension(struct strbuf *sb, struct index_state *istate) { struct split_index *si = istate->split_index; - strbuf_add(sb, si->base_sha1, 20); + strbuf_add(sb, si->base_oid.hash, the_hash_algo->rawsz); if (!si->delete_bitmap && !si->replace_bitmap) return 0; ewah_serialize_strbuf(si->delete_bitmap, sb); diff --git a/split-index.h b/split-index.h index 43d66826eb..7a435ca2c9 100644 --- a/split-index.h +++ b/split-index.h @@ -1,12 +1,14 @@ #ifndef SPLIT_INDEX_H #define SPLIT_INDEX_H +#include "cache.h" + struct index_state; struct strbuf; struct ewah_bitmap; struct split_index { - unsigned char base_sha1[20]; + struct object_id base_oid; struct index_state *base; struct ewah_bitmap *delete_bitmap; struct ewah_bitmap *replace_bitmap; diff --git a/submodule-config.c b/submodule-config.c index 90d29348d3..388ef1f892 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -44,7 +44,7 @@ static int config_path_cmp(const void *unused_cmp_data, const struct submodule_entry *b = entry_or_key; return strcmp(a->config->path, b->config->path) || - hashcmp(a->config->gitmodules_sha1, b->config->gitmodules_sha1); + oidcmp(&a->config->gitmodules_oid, &b->config->gitmodules_oid); } static int config_name_cmp(const void *unused_cmp_data, @@ -56,7 +56,7 @@ static int config_name_cmp(const void *unused_cmp_data, const struct submodule_entry *b = entry_or_key; return strcmp(a->config->name, b->config->name) || - hashcmp(a->config->gitmodules_sha1, b->config->gitmodules_sha1); + oidcmp(&a->config->gitmodules_oid, &b->config->gitmodules_oid); } static struct submodule_cache *submodule_cache_alloc(void) @@ -109,17 +109,17 @@ void submodule_cache_free(struct submodule_cache *cache) free(cache); } -static unsigned int hash_sha1_string(const unsigned char *sha1, - const char *string) +static unsigned int hash_oid_string(const struct object_id *oid, + const char *string) { - return memhash(sha1, 20) + strhash(string); + return memhash(oid->hash, the_hash_algo->rawsz) + strhash(string); } static void cache_put_path(struct submodule_cache *cache, struct submodule *submodule) { - unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1, - submodule->path); + unsigned int hash = hash_oid_string(&submodule->gitmodules_oid, + submodule->path); struct submodule_entry *e = xmalloc(sizeof(*e)); hashmap_entry_init(e, hash); e->config = submodule; @@ -129,8 +129,8 @@ static void cache_put_path(struct submodule_cache *cache, static void cache_remove_path(struct submodule_cache *cache, struct submodule *submodule) { - unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1, - submodule->path); + unsigned int hash = hash_oid_string(&submodule->gitmodules_oid, + submodule->path); struct submodule_entry e; struct submodule_entry *removed; hashmap_entry_init(&e, hash); @@ -142,8 +142,8 @@ static void cache_remove_path(struct submodule_cache *cache, static void cache_add(struct submodule_cache *cache, struct submodule *submodule) { - unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1, - submodule->name); + unsigned int hash = hash_oid_string(&submodule->gitmodules_oid, + submodule->name); struct submodule_entry *e = xmalloc(sizeof(*e)); hashmap_entry_init(e, hash); e->config = submodule; @@ -151,14 +151,14 @@ static void cache_add(struct submodule_cache *cache, } static const struct submodule *cache_lookup_path(struct submodule_cache *cache, - const unsigned char *gitmodules_sha1, const char *path) + const struct object_id *gitmodules_oid, const char *path) { struct submodule_entry *entry; - unsigned int hash = hash_sha1_string(gitmodules_sha1, path); + unsigned int hash = hash_oid_string(gitmodules_oid, path); struct submodule_entry key; struct submodule key_config; - hashcpy(key_config.gitmodules_sha1, gitmodules_sha1); + oidcpy(&key_config.gitmodules_oid, gitmodules_oid); key_config.path = path; hashmap_entry_init(&key, hash); @@ -171,14 +171,14 @@ static const struct submodule *cache_lookup_path(struct submodule_cache *cache, } static struct submodule *cache_lookup_name(struct submodule_cache *cache, - const unsigned char *gitmodules_sha1, const char *name) + const struct object_id *gitmodules_oid, const char *name) { struct submodule_entry *entry; - unsigned int hash = hash_sha1_string(gitmodules_sha1, name); + unsigned int hash = hash_oid_string(gitmodules_oid, name); struct submodule_entry key; struct submodule key_config; - hashcpy(key_config.gitmodules_sha1, gitmodules_sha1); + oidcpy(&key_config.gitmodules_oid, gitmodules_oid); key_config.name = name; hashmap_entry_init(&key, hash); @@ -238,12 +238,12 @@ static int name_and_item_from_var(const char *var, struct strbuf *name, } static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache, - const unsigned char *gitmodules_sha1, const char *name) + const struct object_id *gitmodules_oid, const char *name) { struct submodule *submodule; struct strbuf name_buf = STRBUF_INIT; - submodule = cache_lookup_name(cache, gitmodules_sha1, name); + submodule = cache_lookup_name(cache, gitmodules_oid, name); if (submodule) return submodule; @@ -261,7 +261,7 @@ static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache, submodule->branch = NULL; submodule->recommend_shallow = -1; - hashcpy(submodule->gitmodules_sha1, gitmodules_sha1); + oidcpy(&submodule->gitmodules_oid, gitmodules_oid); cache_add(cache, submodule); @@ -372,12 +372,12 @@ int parse_push_recurse_submodules_arg(const char *opt, const char *arg) return parse_push_recurse(opt, arg, 1); } -static void warn_multiple_config(const unsigned char *treeish_name, +static void warn_multiple_config(const struct object_id *treeish_name, const char *name, const char *option) { const char *commit_string = "WORKTREE"; if (treeish_name) - commit_string = sha1_to_hex(treeish_name); + commit_string = oid_to_hex(treeish_name); warning("%s:.gitmodules, multiple configurations found for " "'submodule.%s.%s'. Skipping second one!", commit_string, name, option); @@ -385,8 +385,8 @@ static void warn_multiple_config(const unsigned char *treeish_name, struct parse_config_parameter { struct submodule_cache *cache; - const unsigned char *treeish_name; - const unsigned char *gitmodules_sha1; + const struct object_id *treeish_name; + const struct object_id *gitmodules_oid; int overwrite; }; @@ -402,7 +402,7 @@ static int parse_config(const char *var, const char *value, void *data) return 0; submodule = lookup_or_create_by_name(me->cache, - me->gitmodules_sha1, + me->gitmodules_oid, name.buf); if (!strcmp(item.buf, "path")) { @@ -420,7 +420,7 @@ static int parse_config(const char *var, const char *value, void *data) } } else if (!strcmp(item.buf, "fetchrecursesubmodules")) { /* when parsing worktree configurations we can die early */ - int die_on_error = is_null_sha1(me->gitmodules_sha1); + int die_on_error = is_null_oid(me->gitmodules_oid); if (!me->overwrite && submodule->fetch_recurse != RECURSE_SUBMODULES_NONE) warn_multiple_config(me->treeish_name, submodule->name, @@ -542,10 +542,10 @@ static const struct submodule *config_from(struct submodule_cache *cache, switch (lookup_type) { case lookup_name: - submodule = cache_lookup_name(cache, oid.hash, key); + submodule = cache_lookup_name(cache, &oid, key); break; case lookup_path: - submodule = cache_lookup_path(cache, oid.hash, key); + submodule = cache_lookup_path(cache, &oid, key); break; } if (submodule) @@ -557,8 +557,8 @@ static const struct submodule *config_from(struct submodule_cache *cache, /* fill the submodule config into the cache */ parameter.cache = cache; - parameter.treeish_name = treeish_name->hash; - parameter.gitmodules_sha1 = oid.hash; + parameter.treeish_name = treeish_name; + parameter.gitmodules_oid = &oid; parameter.overwrite = 0; git_config_from_mem(parse_config, CONFIG_ORIGIN_SUBMODULE_BLOB, rev.buf, config, config_size, ¶meter); @@ -567,9 +567,9 @@ static const struct submodule *config_from(struct submodule_cache *cache, switch (lookup_type) { case lookup_name: - return cache_lookup_name(cache, oid.hash, key); + return cache_lookup_name(cache, &oid, key); case lookup_path: - return cache_lookup_path(cache, oid.hash, key); + return cache_lookup_path(cache, &oid, key); default: return NULL; } @@ -598,7 +598,7 @@ static int gitmodules_cb(const char *var, const char *value, void *data) parameter.cache = repo->submodule_cache; parameter.treeish_name = NULL; - parameter.gitmodules_sha1 = null_sha1; + parameter.gitmodules_oid = &null_oid; parameter.overwrite = 1; return parse_config(var, value, ¶meter); diff --git a/submodule-config.h b/submodule-config.h index 21273f56a3..ca1f94e2d2 100644 --- a/submodule-config.h +++ b/submodule-config.h @@ -1,6 +1,7 @@ #ifndef SUBMODULE_CONFIG_CACHE_H #define SUBMODULE_CONFIG_CACHE_H +#include "cache.h" #include "hashmap.h" #include "submodule.h" #include "strbuf.h" @@ -17,13 +18,13 @@ struct submodule { const char *ignore; const char *branch; struct submodule_update_strategy update_strategy; - /* the sha1 blob id of the responsible .gitmodules file */ - unsigned char gitmodules_sha1[20]; + /* the object id of the responsible .gitmodules file */ + struct object_id gitmodules_oid; int recommend_shallow; }; #define SUBMODULE_INIT { NULL, NULL, NULL, RECURSE_SUBMODULES_NONE, \ - NULL, NULL, SUBMODULE_UPDATE_STRATEGY_INIT, {0}, -1 }; + NULL, NULL, SUBMODULE_UPDATE_STRATEGY_INIT, { { 0 } }, -1 }; struct submodule_cache; struct repository; diff --git a/submodule.c b/submodule.c index eb08cf0782..1f88623893 100644 --- a/submodule.c +++ b/submodule.c @@ -1569,7 +1569,7 @@ static void submodule_reset_index(const char *path) get_super_prefix_or_empty(), path); argv_array_pushl(&cp.args, "read-tree", "-u", "--reset", NULL); - argv_array_push(&cp.args, EMPTY_TREE_SHA1_HEX); + argv_array_push(&cp.args, empty_tree_oid_hex()); if (run_command(&cp)) die("could not reset submodule index"); @@ -1661,9 +1661,9 @@ int submodule_move_head(const char *path, argv_array_push(&cp.args, "-m"); if (!(flags & SUBMODULE_MOVE_HEAD_FORCE)) - argv_array_push(&cp.args, old_head ? old_head : EMPTY_TREE_SHA1_HEX); + argv_array_push(&cp.args, old_head ? old_head : empty_tree_oid_hex()); - argv_array_push(&cp.args, new_head ? new_head : EMPTY_TREE_SHA1_HEX); + argv_array_push(&cp.args, new_head ? new_head : empty_tree_oid_hex()); if (run_command(&cp)) { ret = -1; diff --git a/t/helper/test-dump-split-index.c b/t/helper/test-dump-split-index.c index 4e2fdb5e30..63c689d6ee 100644 --- a/t/helper/test-dump-split-index.c +++ b/t/helper/test-dump-split-index.c @@ -14,13 +14,13 @@ int cmd__dump_split_index(int ac, const char **av) int i; do_read_index(&the_index, av[1], 1); - printf("own %s\n", sha1_to_hex(the_index.sha1)); + printf("own %s\n", oid_to_hex(&the_index.oid)); si = the_index.split_index; if (!si) { printf("not a split index\n"); return 0; } - printf("base %s\n", sha1_to_hex(si->base_sha1)); + printf("base %s\n", oid_to_hex(&si->base_oid)); for (i = 0; i < the_index.cache_nr; i++) { struct cache_entry *ce = the_index.cache[i]; printf("%06o %s %d\t%s\n", ce->ce_mode, diff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c index d7c55c2355..bd92fb305a 100644 --- a/t/helper/test-dump-untracked-cache.c +++ b/t/helper/test-dump-untracked-cache.c @@ -23,7 +23,7 @@ static void dump(struct untracked_cache_dir *ucd, struct strbuf *base) len = base->len; strbuf_addf(base, "%s/", ucd->name); printf("%s %s", base->buf, - sha1_to_hex(ucd->exclude_sha1)); + oid_to_hex(&ucd->exclude_oid)); if (ucd->recurse) fputs(" recurse", stdout); if (ucd->check_only) diff --git a/templates/hooks--pre-commit.sample b/templates/hooks--pre-commit.sample index 68d62d5446..6a75641638 100755 --- a/templates/hooks--pre-commit.sample +++ b/templates/hooks--pre-commit.sample @@ -12,7 +12,7 @@ then against=HEAD else # Initial commit: diff against an empty tree object - against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 + against=$(git hash-object -t tree /dev/null) fi # If you want to allow non-ASCII filenames set this variable to true. diff --git a/tree-walk.c b/tree-walk.c index e11b3063af..8f5090862b 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -105,7 +105,7 @@ static void entry_extract(struct tree_desc *t, struct name_entry *a) static int update_tree_entry_internal(struct tree_desc *desc, struct strbuf *err) { const void *buf = desc->buffer; - const unsigned char *end = desc->entry.oid->hash + 20; + const unsigned char *end = desc->entry.oid->hash + the_hash_algo->rawsz; unsigned long size = desc->size; unsigned long len = end - (const unsigned char *)buf; @@ -488,7 +488,7 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info) struct dir_state { void *tree; unsigned long size; - unsigned char sha1[20]; + struct object_id oid; }; static int find_tree_entry(struct tree_desc *t, const char *name, struct object_id *result, unsigned *mode) @@ -576,7 +576,7 @@ int get_tree_entry(const struct object_id *tree_oid, const char *name, struct ob * See the code for enum follow_symlink_result for a description of * the return values. */ -enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_sha1, const char *name, unsigned char *result, struct strbuf *result_path, unsigned *mode) +enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode) { int retval = MISSING_OBJECT; struct dir_state *parents = NULL; @@ -589,7 +589,7 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s init_tree_desc(&t, NULL, 0UL); strbuf_addstr(&namebuf, name); - hashcpy(current_tree_oid.hash, tree_sha1); + oidcpy(¤t_tree_oid, tree_oid); while (1) { int find_result; @@ -609,11 +609,11 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s ALLOC_GROW(parents, parents_nr + 1, parents_alloc); parents[parents_nr].tree = tree; parents[parents_nr].size = size; - hashcpy(parents[parents_nr].sha1, root.hash); + oidcpy(&parents[parents_nr].oid, &root); parents_nr++; if (namebuf.buf[0] == '\0') { - hashcpy(result, root.hash); + oidcpy(result, &root); retval = FOUND; goto done; } @@ -663,7 +663,7 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s /* We could end up here via a symlink to dir/.. */ if (namebuf.buf[0] == '\0') { - hashcpy(result, parents[parents_nr - 1].sha1); + oidcpy(result, &parents[parents_nr - 1].oid); retval = FOUND; goto done; } @@ -677,7 +677,7 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s if (S_ISDIR(*mode)) { if (!remainder) { - hashcpy(result, current_tree_oid.hash); + oidcpy(result, ¤t_tree_oid); retval = FOUND; goto done; } @@ -687,7 +687,7 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s 1 + first_slash - namebuf.buf); } else if (S_ISREG(*mode)) { if (!remainder) { - hashcpy(result, current_tree_oid.hash); + oidcpy(result, ¤t_tree_oid); retval = FOUND; } else { retval = NOT_DIR; diff --git a/tree-walk.h b/tree-walk.h index 4617deeb0e..805f58f00f 100644 --- a/tree-walk.h +++ b/tree-walk.h @@ -64,7 +64,7 @@ enum follow_symlinks_result { */ }; -enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_sha1, const char *name, unsigned char *result, struct strbuf *result_path, unsigned *mode); +enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode); struct traverse_info { const char *traverse_path; diff --git a/unpack-trees.c b/unpack-trees.c index 7051fcf7d8..d17f726e75 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1298,7 +1298,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options } else { o->result.split_index = init_split_index(&o->result); } - hashcpy(o->result.sha1, o->src_index->sha1); + oidcpy(&o->result.oid, &o->src_index->oid); o->merge_size = len; mark_all_ce_unused(o->src_index); diff --git a/upload-pack.c b/upload-pack.c index 87b4d32a6e..bacc92bbb6 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -444,7 +444,7 @@ static int get_common_commits(void) break; default: got_common = 1; - memcpy(last_hex, oid_to_hex(&oid), 41); + oid_to_hex_r(last_hex, &oid); if (multi_ack == 2) packet_write_fmt(1, "ACK %s common\n", last_hex); else if (multi_ack) @@ -486,7 +486,7 @@ static int do_reachable_revlist(struct child_process *cmd, "rev-list", "--stdin", NULL, }; struct object *o; - char namebuf[42]; /* ^ + SHA-1 + LF */ + char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */ int i; cmd->argv = argv; @@ -555,15 +555,17 @@ static int get_reachable_list(struct object_array *src, struct child_process cmd = CHILD_PROCESS_INIT; int i; struct object *o; - char namebuf[42]; /* ^ + SHA-1 + LF */ + char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */ + const unsigned hexsz = the_hash_algo->hexsz; if (do_reachable_revlist(&cmd, src, reachable) < 0) return -1; - while ((i = read_in_full(cmd.out, namebuf, 41)) == 41) { + while ((i = read_in_full(cmd.out, namebuf, hexsz + 1)) == hexsz + 1) { struct object_id sha1; + const char *p; - if (namebuf[40] != '\n' || get_oid_hex(namebuf, &sha1)) + if (parse_oid_hex(namebuf, &sha1, &p) || *p != '\n') break; o = lookup_object(sha1.hash); @@ -895,11 +897,9 @@ static void receive_needs(void) } if (!skip_prefix(line, "want ", &arg) || - get_oid_hex(arg, &oid_buf)) + parse_oid_hex(arg, &oid_buf, &features)) die("git upload-pack: protocol error, " - "expected to get sha, not '%s'", line); - - features = arg + 40; + "expected to get object ID, not '%s'", line); if (parse_feature_request(features, "deepen-relative")) deepen_relative = 1; diff --git a/wt-status.c b/wt-status.c index 11f64deefc..d1c05145a4 100644 --- a/wt-status.c +++ b/wt-status.c @@ -609,7 +609,7 @@ static void wt_status_collect_changes_index(struct wt_status *s) init_revisions(&rev, NULL); memset(&opt, 0, sizeof(opt)); - opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference; + opt.def = s->is_initial ? empty_tree_oid_hex() : s->reference; setup_revisions(0, NULL, &rev, &opt); rev.diffopt.flags.override_submodule_config = 1; @@ -987,7 +987,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s) rev.diffopt.ita_invisible_in_index = 1; memset(&opt, 0, sizeof(opt)); - opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference; + opt.def = s->is_initial ? empty_tree_oid_hex() : s->reference; setup_revisions(0, NULL, &rev, &opt); rev.diffopt.output_format |= DIFF_FORMAT_PATCH; |