From f0be0db13dbd2d96d2240374e0e9cb106bf6a614 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 7 Jan 2019 03:34:40 -0500 Subject: http: use struct object_id instead of bare sha1 The dumb-http walker code still passes around and stores object ids as "unsigned char *sha1". Let's modernize it. There's probably still more work to be done to handle dumb-http fetches with a new, larger hash. But that can wait; this is enough that we can now convert some of the low-level object routines that we call into from here (and in fact, some of the "oid.hash" references added here will be further improved in the next patch). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- http-walker.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'http-walker.c') diff --git a/http-walker.c b/http-walker.c index 0a392c85b6..856716c63d 100644 --- a/http-walker.c +++ b/http-walker.c @@ -58,7 +58,7 @@ static void start_object_request(struct walker *walker, struct active_request_slot *slot; struct http_object_request *req; - req = new_http_object_request(obj_req->repo->base, obj_req->oid.hash); + req = new_http_object_request(obj_req->repo->base, &obj_req->oid); if (req == NULL) { obj_req->state = ABORTED; return; @@ -543,11 +543,11 @@ static int fetch_object(struct walker *walker, unsigned char *sha1) } else if (req->zret != Z_STREAM_END) { walker->corrupt_object_found++; ret = error("File %s (%s) corrupt", hex, req->url); - } else if (!hasheq(obj_req->oid.hash, req->real_sha1)) { + } else if (!oideq(&obj_req->oid, &req->real_oid)) { ret = error("File %s has bad hash", hex); } else if (req->rename < 0) { struct strbuf buf = STRBUF_INIT; - loose_object_path(the_repository, &buf, req->sha1); + loose_object_path(the_repository, &buf, req->oid.hash); ret = error("unable to write sha1 filename %s", buf.buf); strbuf_release(&buf); } -- cgit v1.3 From 514c5fdd03b914c72a91bb420e46bdc8886940cf Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 7 Jan 2019 03:35:42 -0500 Subject: sha1-file: modernize loose object file functions The loose object access code in sha1-file.c is some of the oldest in Git, and could use some modernizing. It mostly uses "unsigned char *" for object ids, which these days should be "struct object_id". It also uses the term "sha1_file" in many functions, which is confusing. The term "loose_objects" is much better. It clearly distinguishes them from packed objects (which didn't even exist back when the name "sha1_file" came into being). And it also distinguishes it from the checksummed-file concept in csum-file.c (which until recently was actually called "struct sha1file"!). This patch converts the functions {open,close,map,stat}_sha1_file() into open_loose_object(), etc, and switches their sha1 arguments for object_id structs. Similarly, path functions like fill_sha1_path() become fill_loose_path() and use object_ids. The function sha1_loose_object_info() already says "loose", so we can just drop the "sha1" (and teach it to use object_id). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- http-walker.c | 2 +- http.c | 4 +-- object-store.h | 8 +++--- sha1-file.c | 81 +++++++++++++++++++++++++++++----------------------------- streaming.c | 4 +-- 5 files changed, 51 insertions(+), 48 deletions(-) (limited to 'http-walker.c') diff --git a/http-walker.c b/http-walker.c index 856716c63d..29b59e2fe0 100644 --- a/http-walker.c +++ b/http-walker.c @@ -547,7 +547,7 @@ static int fetch_object(struct walker *walker, unsigned char *sha1) ret = error("File %s has bad hash", hex); } else if (req->rename < 0) { struct strbuf buf = STRBUF_INIT; - loose_object_path(the_repository, &buf, req->oid.hash); + loose_object_path(the_repository, &buf, &req->oid); ret = error("unable to write sha1 filename %s", buf.buf); strbuf_release(&buf); } diff --git a/http.c b/http.c index 8d42154792..43d06dd074 100644 --- a/http.c +++ b/http.c @@ -2353,7 +2353,7 @@ struct http_object_request *new_http_object_request(const char *base_url, oidcpy(&freq->oid, oid); freq->localfile = -1; - loose_object_path(the_repository, &filename, oid->hash); + loose_object_path(the_repository, &filename, oid); strbuf_addf(&freq->tmpfile, "%s.temp", filename.buf); strbuf_addf(&prevfile, "%s.prev", filename.buf); @@ -2504,7 +2504,7 @@ int finish_http_object_request(struct http_object_request *freq) unlink_or_warn(freq->tmpfile.buf); return -1; } - loose_object_path(the_repository, &filename, freq->oid.hash); + loose_object_path(the_repository, &filename, &freq->oid); freq->rename = finalize_object_file(freq->tmpfile.buf, filename.buf); strbuf_release(&filename); diff --git a/object-store.h b/object-store.h index e16aa38cae..139feb75b2 100644 --- a/object-store.h +++ b/object-store.h @@ -154,11 +154,13 @@ void raw_object_store_clear(struct raw_object_store *o); /* * Put in `buf` the name of the file in the local object database that - * would be used to store a loose object with the specified sha1. + * would be used to store a loose object with the specified oid. */ -const char *loose_object_path(struct repository *r, struct strbuf *buf, const unsigned char *sha1); +const char *loose_object_path(struct repository *r, struct strbuf *buf, + const struct object_id *oid); -void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size); +void *map_loose_object(struct repository *r, const struct object_id *oid, + unsigned long *size); extern void *read_object_file_extended(const struct object_id *oid, enum object_type *type, diff --git a/sha1-file.c b/sha1-file.c index c781ae847f..1af5fef7d2 100644 --- a/sha1-file.c +++ b/sha1-file.c @@ -333,12 +333,12 @@ out: return ret; } -static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1) +static void fill_loose_path(struct strbuf *buf, const struct object_id *oid) { int i; for (i = 0; i < the_hash_algo->rawsz; i++) { static char hex[] = "0123456789abcdef"; - unsigned int val = sha1[i]; + unsigned int val = oid->hash[i]; strbuf_addch(buf, hex[val >> 4]); strbuf_addch(buf, hex[val & 0xf]); if (!i) @@ -348,19 +348,19 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1) static const char *odb_loose_path(struct object_directory *odb, struct strbuf *buf, - const unsigned char *sha1) + const struct object_id *oid) { strbuf_reset(buf); strbuf_addstr(buf, odb->path); strbuf_addch(buf, '/'); - fill_sha1_path(buf, sha1); + fill_loose_path(buf, oid); return buf->buf; } const char *loose_object_path(struct repository *r, struct strbuf *buf, - const unsigned char *sha1) + const struct object_id *oid) { - return odb_loose_path(r->objects->odb, buf, sha1); + return odb_loose_path(r->objects->odb, buf, oid); } /* @@ -721,7 +721,7 @@ static int check_and_freshen_odb(struct object_directory *odb, int freshen) { static struct strbuf path = STRBUF_INIT; - odb_loose_path(odb, &path, oid->hash); + odb_loose_path(odb, &path, oid); return check_and_freshen_file(path.buf, freshen); } @@ -872,22 +872,22 @@ int git_open_cloexec(const char *name, int flags) } /* - * Find "sha1" as a loose object in the local repository or in an alternate. + * Find "oid" as a loose object in the local repository or in an alternate. * Returns 0 on success, negative on failure. * * The "path" out-parameter will give the path of the object we found (if any). * Note that it may point to static storage and is only valid until another - * call to stat_sha1_file(). + * call to stat_loose_object(). */ -static int stat_sha1_file(struct repository *r, const unsigned char *sha1, - struct stat *st, const char **path) +static int stat_loose_object(struct repository *r, const struct object_id *oid, + struct stat *st, const char **path) { struct object_directory *odb; static struct strbuf buf = STRBUF_INIT; prepare_alt_odb(r); for (odb = r->objects->odb; odb; odb = odb->next) { - *path = odb_loose_path(odb, &buf, sha1); + *path = odb_loose_path(odb, &buf, oid); if (!lstat(*path, st)) return 0; } @@ -896,11 +896,11 @@ static int stat_sha1_file(struct repository *r, const unsigned char *sha1, } /* - * Like stat_sha1_file(), but actually open the object and return the + * Like stat_loose_object(), but actually open the object and return the * descriptor. See the caveats on the "path" parameter above. */ -static int open_sha1_file(struct repository *r, - const unsigned char *sha1, const char **path) +static int open_loose_object(struct repository *r, + const struct object_id *oid, const char **path) { int fd; struct object_directory *odb; @@ -909,7 +909,7 @@ static int open_sha1_file(struct repository *r, prepare_alt_odb(r); for (odb = r->objects->odb; odb; odb = odb->next) { - *path = odb_loose_path(odb, &buf, sha1); + *path = odb_loose_path(odb, &buf, oid); fd = git_open(*path); if (fd >= 0) return fd; @@ -939,10 +939,10 @@ static int quick_has_loose(struct repository *r, /* * Map the loose object at "path" if it is not NULL, or the path found by - * searching for a loose object named "sha1". + * searching for a loose object named "oid". */ -static void *map_sha1_file_1(struct repository *r, const char *path, - const unsigned char *sha1, unsigned long *size) +static void *map_loose_object_1(struct repository *r, const char *path, + const struct object_id *oid, unsigned long *size) { void *map; int fd; @@ -950,7 +950,7 @@ static void *map_sha1_file_1(struct repository *r, const char *path, if (path) fd = git_open(path); else - fd = open_sha1_file(r, sha1, &path); + fd = open_loose_object(r, oid, &path); map = NULL; if (fd >= 0) { struct stat st; @@ -969,10 +969,11 @@ static void *map_sha1_file_1(struct repository *r, const char *path, return map; } -void *map_sha1_file(struct repository *r, - const unsigned char *sha1, unsigned long *size) +void *map_loose_object(struct repository *r, + const struct object_id *oid, + unsigned long *size) { - return map_sha1_file_1(r, NULL, sha1, size); + return map_loose_object_1(r, NULL, oid, size); } static int unpack_sha1_short_header(git_zstream *stream, @@ -1161,9 +1162,9 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep) return parse_sha1_header_extended(hdr, &oi, 0); } -static int sha1_loose_object_info(struct repository *r, - const unsigned char *sha1, - struct object_info *oi, int flags) +static int loose_object_info(struct repository *r, + const struct object_id *oid, + struct object_info *oi, int flags) { int status = 0; unsigned long mapsize; @@ -1188,15 +1189,15 @@ static int sha1_loose_object_info(struct repository *r, const char *path; struct stat st; if (!oi->disk_sizep && (flags & OBJECT_INFO_QUICK)) - return quick_has_loose(r, sha1) ? 0 : -1; - if (stat_sha1_file(r, sha1, &st, &path) < 0) + return quick_has_loose(r, oid->hash) ? 0 : -1; + if (stat_loose_object(r, oid, &st, &path) < 0) return -1; if (oi->disk_sizep) *oi->disk_sizep = st.st_size; return 0; } - map = map_sha1_file(r, sha1, &mapsize); + map = map_loose_object(r, oid, &mapsize); if (!map) return -1; @@ -1208,22 +1209,22 @@ static int sha1_loose_object_info(struct repository *r, if ((flags & OBJECT_INFO_ALLOW_UNKNOWN_TYPE)) { if (unpack_sha1_header_to_strbuf(&stream, map, mapsize, hdr, sizeof(hdr), &hdrbuf) < 0) status = error(_("unable to unpack %s header with --allow-unknown-type"), - sha1_to_hex(sha1)); + oid_to_hex(oid)); } else if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0) status = error(_("unable to unpack %s header"), - sha1_to_hex(sha1)); + oid_to_hex(oid)); if (status < 0) ; /* Do nothing */ else if (hdrbuf.len) { if ((status = parse_sha1_header_extended(hdrbuf.buf, oi, flags)) < 0) status = error(_("unable to parse %s header with --allow-unknown-type"), - sha1_to_hex(sha1)); + oid_to_hex(oid)); } else if ((status = parse_sha1_header_extended(hdr, oi, flags)) < 0) - status = error(_("unable to parse %s header"), sha1_to_hex(sha1)); + status = error(_("unable to parse %s header"), oid_to_hex(oid)); if (status >= 0 && oi->contentp) { *oi->contentp = unpack_sha1_rest(&stream, hdr, - *oi->sizep, sha1); + *oi->sizep, oid->hash); if (!*oi->contentp) { git_inflate_end(&stream); status = -1; @@ -1289,7 +1290,7 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid, return -1; /* Most likely it's a loose object. */ - if (!sha1_loose_object_info(r, real->hash, oi, flags)) + if (!loose_object_info(r, real, oi, flags)) return 0; /* Not a loose object; someone else may have just packed it. */ @@ -1417,7 +1418,7 @@ void *read_object_file_extended(const struct object_id *oid, die(_("replacement %s not found for %s"), oid_to_hex(repl), oid_to_hex(oid)); - if (!stat_sha1_file(the_repository, repl->hash, &st, &path)) + if (!stat_loose_object(the_repository, repl, &st, &path)) die(_("loose object %s (stored in %s) is corrupt"), oid_to_hex(repl), path); @@ -1552,7 +1553,7 @@ int hash_object_file(const void *buf, unsigned long len, const char *type, } /* Finalize a file on disk, and close it. */ -static void close_sha1_file(int fd) +static void close_loose_object(int fd) { if (fsync_object_files) fsync_or_die(fd, "sha1 file"); @@ -1617,7 +1618,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr, static struct strbuf tmp_file = STRBUF_INIT; static struct strbuf filename = STRBUF_INIT; - loose_object_path(the_repository, &filename, oid->hash); + loose_object_path(the_repository, &filename, oid); fd = create_tmpfile(&tmp_file, filename.buf); if (fd < 0) { @@ -1665,7 +1666,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr, die(_("confused by unstable object source data for %s"), oid_to_hex(oid)); - close_sha1_file(fd); + close_loose_object(fd); if (mtime) { struct utimbuf utb; @@ -2255,7 +2256,7 @@ int read_loose_object(const char *path, *contents = NULL; - map = map_sha1_file_1(the_repository, path, NULL, &mapsize); + map = map_loose_object_1(the_repository, path, NULL, &mapsize); if (!map) { error_errno(_("unable to mmap %s"), path); goto out; diff --git a/streaming.c b/streaming.c index ac7c7a22f9..9049146bc1 100644 --- a/streaming.c +++ b/streaming.c @@ -338,8 +338,8 @@ static struct stream_vtbl loose_vtbl = { static open_method_decl(loose) { - st->u.loose.mapped = map_sha1_file(the_repository, - oid->hash, &st->u.loose.mapsize); + st->u.loose.mapped = map_loose_object(the_repository, + oid, &st->u.loose.mapsize); if (!st->u.loose.mapped) return -1; if ((unpack_sha1_header(&st->z, -- cgit v1.3 From 98374a07c98d1acc200c423b87495365a59cce0b Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 7 Jan 2019 03:37:54 -0500 Subject: convert has_sha1_file() callers to has_object_file() The only remaining callers of has_sha1_file() actually have an object_id already. They can use the "object" variant, rather than dereferencing the hash themselves. The code changes here were completely generated by the included coccinelle patch. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- apply.c | 2 +- builtin/fetch.c | 7 +++---- builtin/index-pack.c | 2 +- builtin/reflog.c | 2 +- builtin/show-ref.c | 2 +- bulk-checkin.c | 2 +- cache-tree.c | 4 ++-- contrib/coccinelle/object_id.cocci | 32 ++++++++++++++++++++++++++++++++ http-walker.c | 4 ++-- refs.c | 2 +- send-pack.c | 2 +- sha1-file.c | 2 +- 12 files changed, 47 insertions(+), 16 deletions(-) (limited to 'http-walker.c') diff --git a/apply.c b/apply.c index 01793d6126..b8e257ead2 100644 --- a/apply.c +++ b/apply.c @@ -3183,7 +3183,7 @@ static int apply_binary(struct apply_state *state, return 0; /* deletion patch */ } - if (has_sha1_file(oid.hash)) { + if (has_object_file(&oid)) { /* We already have the postimage */ enum object_type type; unsigned long size; diff --git a/builtin/fetch.c b/builtin/fetch.c index e0140327aa..57f35c6a0a 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -317,8 +317,7 @@ static void find_non_local_tags(const struct ref *refs, !has_object_file_with_flags(&ref->old_oid, OBJECT_INFO_QUICK) && !will_fetch(head, ref->old_oid.hash) && - !has_sha1_file_with_flags(item->oid.hash, - OBJECT_INFO_QUICK) && + !has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) && !will_fetch(head, item->oid.hash)) oidclr(&item->oid); item = NULL; @@ -332,7 +331,7 @@ static void find_non_local_tags(const struct ref *refs, * fetch. */ if (item && - !has_sha1_file_with_flags(item->oid.hash, OBJECT_INFO_QUICK) && + !has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) && !will_fetch(head, item->oid.hash)) oidclr(&item->oid); @@ -353,7 +352,7 @@ static void find_non_local_tags(const struct ref *refs, * checked to see if it needs fetching. */ if (item && - !has_sha1_file_with_flags(item->oid.hash, OBJECT_INFO_QUICK) && + !has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) && !will_fetch(head, item->oid.hash)) oidclr(&item->oid); diff --git a/builtin/index-pack.c b/builtin/index-pack.c index ac1f4ea9a7..31046c7a0a 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -772,7 +772,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry, if (startup_info->have_repository) { read_lock(); collision_test_needed = - has_sha1_file_with_flags(oid->hash, OBJECT_INFO_QUICK); + has_object_file_with_flags(oid, OBJECT_INFO_QUICK); read_unlock(); } diff --git a/builtin/reflog.c b/builtin/reflog.c index 64a8df4f25..45e9e15006 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -94,7 +94,7 @@ static int tree_is_complete(const struct object_id *oid) init_tree_desc(&desc, tree->buffer, tree->size); complete = 1; while (tree_entry(&desc, &entry)) { - if (!has_sha1_file(entry.oid->hash) || + if (!has_object_file(entry.oid) || (S_ISDIR(entry.mode) && !tree_is_complete(entry.oid))) { tree->object.flags |= INCOMPLETE; complete = 0; diff --git a/builtin/show-ref.c b/builtin/show-ref.c index ed888ffa48..6a706c02a6 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -23,7 +23,7 @@ static void show_one(const char *refname, const struct object_id *oid) const char *hex; struct object_id peeled; - if (!has_sha1_file(oid->hash)) + if (!has_object_file(oid)) die("git show-ref: bad ref %s (%s)", refname, oid_to_hex(oid)); diff --git a/bulk-checkin.c b/bulk-checkin.c index 409ecb566b..39ee7d6107 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -67,7 +67,7 @@ static int already_written(struct bulk_checkin_state *state, struct object_id *o int i; /* The object may already exist in the repository */ - if (has_sha1_file(oid->hash)) + if (has_object_file(oid)) return 1; /* Might want to keep the list sorted */ diff --git a/cache-tree.c b/cache-tree.c index 190c6e5aa6..47f3464a1f 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -225,7 +225,7 @@ int cache_tree_fully_valid(struct cache_tree *it) int i; if (!it) return 0; - if (it->entry_count < 0 || !has_sha1_file(it->oid.hash)) + if (it->entry_count < 0 || !has_object_file(&it->oid)) return 0; for (i = 0; i < it->subtree_nr; i++) { if (!cache_tree_fully_valid(it->down[i]->cache_tree)) @@ -253,7 +253,7 @@ static int update_one(struct cache_tree *it, *skip_count = 0; - if (0 <= it->entry_count && has_sha1_file(it->oid.hash)) + if (0 <= it->entry_count && has_object_file(&it->oid)) return it->entry_count; /* diff --git a/contrib/coccinelle/object_id.cocci b/contrib/coccinelle/object_id.cocci index 6a7cf3e02d..73886ae583 100644 --- a/contrib/coccinelle/object_id.cocci +++ b/contrib/coccinelle/object_id.cocci @@ -147,3 +147,35 @@ expression E1, E2; - hashcmp(E1, E2) != 0 + !hasheq(E1, E2) ...>} + +@@ +struct object_id OID; +@@ +- has_sha1_file(OID.hash) ++ has_object_file(&OID) + +@@ +identifier f != has_object_file; +struct object_id *OIDPTR; +@@ + f(...) {<... +- has_sha1_file(OIDPTR->hash) ++ has_object_file(OIDPTR) + ...>} + +@@ +struct object_id OID; +expression E; +@@ +- has_sha1_file_with_flags(OID.hash, E) ++ has_object_file_with_flags(&OID, E) + +@@ +identifier f != has_object_file_with_flags; +struct object_id *OIDPTR; +expression E; +@@ + f(...) {<... +- has_sha1_file_with_flags(OIDPTR->hash, E) ++ has_object_file_with_flags(OIDPTR, E) + ...>} diff --git a/http-walker.c b/http-walker.c index 29b59e2fe0..8ae5d76c6a 100644 --- a/http-walker.c +++ b/http-walker.c @@ -131,7 +131,7 @@ static int fill_active_slot(struct walker *walker) list_for_each_safe(pos, tmp, head) { obj_req = list_entry(pos, struct object_request, node); if (obj_req->state == WAITING) { - if (has_sha1_file(obj_req->oid.hash)) + if (has_object_file(&obj_req->oid)) obj_req->state = COMPLETE; else { start_object_request(walker, obj_req); @@ -489,7 +489,7 @@ static int fetch_object(struct walker *walker, unsigned char *sha1) if (obj_req == NULL) return error("Couldn't find request for %s in the queue", hex); - if (has_sha1_file(obj_req->oid.hash)) { + if (has_object_file(&obj_req->oid)) { if (obj_req->req != NULL) abort_http_object_request(obj_req->req); abort_object_request(obj_req); diff --git a/refs.c b/refs.c index f9936355cd..142888a40a 100644 --- a/refs.c +++ b/refs.c @@ -188,7 +188,7 @@ int ref_resolves_to_object(const char *refname, { if (flags & REF_ISBROKEN) return 0; - if (!has_sha1_file(oid->hash)) { + if (!has_object_file(oid)) { error(_("%s does not point to a valid object!"), refname); return 0; } diff --git a/send-pack.c b/send-pack.c index f692686770..c673d3ed06 100644 --- a/send-pack.c +++ b/send-pack.c @@ -40,7 +40,7 @@ int option_parse_push_signed(const struct option *opt, static void feed_object(const struct object_id *oid, FILE *fh, int negative) { - if (negative && !has_sha1_file(oid->hash)) + if (negative && !has_object_file(oid)) return; if (negative) diff --git a/sha1-file.c b/sha1-file.c index 73e5cc6fa5..95186c019a 100644 --- a/sha1-file.c +++ b/sha1-file.c @@ -1372,7 +1372,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)) + if (has_object_file(oid) || find_cached_object(oid)) return 0; ALLOC_GROW(cached_objects, cached_object_nr + 1, cached_object_alloc); co = &cached_objects[cached_object_nr++]; -- cgit v1.3