object-file API: add a format_object_header() function
Add a convenience function to wrap the xsnprintf() command that generates loose object headers. This code was copy/pasted in various parts of the codebase, let's define it in one place and re-use it from there. All except one caller of it had a valid "enum object_type" for us, it's only write_object_file_prepare() which might need to deal with "git hash-object --literally" and a potential garbage type. Let's have the primary API use an "enum object_type", and define a *_literally() function that can take an arbitrary "const char *" for the type. See [1] for the discussion that prompted this patch, i.e. new code in object-file.c that wanted to copy/paste the xsnprintf() invocation. In the case of fast-import.c the callers unfortunately need to cast back & forth between "unsigned char *" and "char *", since format_object_header() ad encode_in_pack_object_header() take different signedness. 1. https://lore.kernel.org/git/211213.86bl1l9bfz.gmgdl@evledraar.gmail.com/ Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									63e05f9056
								
							
						
					
					
						commit
						b04cdea46c
					
				|  | @ -937,8 +937,8 @@ static int store_object( | ||||||
| 	git_hash_ctx c; | 	git_hash_ctx c; | ||||||
| 	git_zstream s; | 	git_zstream s; | ||||||
|  |  | ||||||
| 	hdrlen = xsnprintf((char *)hdr, sizeof(hdr), "%s %lu", | 	hdrlen = format_object_header((char *)hdr, sizeof(hdr), type, | ||||||
| 			   type_name(type), (unsigned long)dat->len) + 1; | 				      dat->len); | ||||||
| 	the_hash_algo->init_fn(&c); | 	the_hash_algo->init_fn(&c); | ||||||
| 	the_hash_algo->update_fn(&c, hdr, hdrlen); | 	the_hash_algo->update_fn(&c, hdr, hdrlen); | ||||||
| 	the_hash_algo->update_fn(&c, dat->buf, dat->len); | 	the_hash_algo->update_fn(&c, dat->buf, dat->len); | ||||||
|  | @ -1091,7 +1091,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) | ||||||
| 	hashfile_checkpoint(pack_file, &checkpoint); | 	hashfile_checkpoint(pack_file, &checkpoint); | ||||||
| 	offset = checkpoint.offset; | 	offset = checkpoint.offset; | ||||||
|  |  | ||||||
| 	hdrlen = xsnprintf((char *)out_buf, out_sz, "blob %" PRIuMAX, len) + 1; | 	hdrlen = format_object_header((char *)out_buf, out_sz, OBJ_BLOB, len); | ||||||
|  |  | ||||||
| 	the_hash_algo->init_fn(&c); | 	the_hash_algo->init_fn(&c); | ||||||
| 	the_hash_algo->update_fn(&c, out_buf, hdrlen); | 	the_hash_algo->update_fn(&c, out_buf, hdrlen); | ||||||
|  |  | ||||||
|  | @ -449,8 +449,7 @@ static void *unpack_entry_data(off_t offset, unsigned long size, | ||||||
| 	int hdrlen; | 	int hdrlen; | ||||||
|  |  | ||||||
| 	if (!is_delta_type(type)) { | 	if (!is_delta_type(type)) { | ||||||
| 		hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX, | 		hdrlen = format_object_header(hdr, sizeof(hdr), type, size); | ||||||
| 				   type_name(type),(uintmax_t)size) + 1; |  | ||||||
| 		the_hash_algo->init_fn(&c); | 		the_hash_algo->init_fn(&c); | ||||||
| 		the_hash_algo->update_fn(&c, hdr, hdrlen); | 		the_hash_algo->update_fn(&c, hdr, hdrlen); | ||||||
| 	} else | 	} else | ||||||
|  |  | ||||||
|  | @ -220,8 +220,8 @@ static int deflate_to_pack(struct bulk_checkin_state *state, | ||||||
| 	if (seekback == (off_t) -1) | 	if (seekback == (off_t) -1) | ||||||
| 		return error("cannot find the current offset"); | 		return error("cannot find the current offset"); | ||||||
|  |  | ||||||
| 	header_len = xsnprintf((char *)obuf, sizeof(obuf), "%s %" PRIuMAX, | 	header_len = format_object_header((char *)obuf, sizeof(obuf), | ||||||
| 			       type_name(type), (uintmax_t)size) + 1; | 					  type, size); | ||||||
| 	the_hash_algo->init_fn(&ctx); | 	the_hash_algo->init_fn(&ctx); | ||||||
| 	the_hash_algo->update_fn(&ctx, obuf, header_len); | 	the_hash_algo->update_fn(&ctx, obuf, header_len); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -363,7 +363,7 @@ static void start_put(struct transfer_request *request) | ||||||
| 	git_zstream stream; | 	git_zstream stream; | ||||||
|  |  | ||||||
| 	unpacked = read_object_file(&request->obj->oid, &type, &len); | 	unpacked = read_object_file(&request->obj->oid, &type, &len); | ||||||
| 	hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1; | 	hdrlen = format_object_header(hdr, sizeof(hdr), type, len); | ||||||
|  |  | ||||||
| 	/* Set it up */ | 	/* Set it up */ | ||||||
| 	git_deflate_init(&stream, zlib_compression_level); | 	git_deflate_init(&stream, zlib_compression_level); | ||||||
|  |  | ||||||
|  | @ -1049,6 +1049,23 @@ void *xmmap(void *start, size_t length, | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int format_object_header_literally(char *str, size_t size, | ||||||
|  | 					  const char *type, size_t objsize) | ||||||
|  | { | ||||||
|  | 	return xsnprintf(str, size, "%s %"PRIuMAX, type, (uintmax_t)objsize) + 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int format_object_header(char *str, size_t size, enum object_type type, | ||||||
|  | 			 size_t objsize) | ||||||
|  | { | ||||||
|  | 	const char *name = type_name(type); | ||||||
|  |  | ||||||
|  | 	if (!name) | ||||||
|  | 		BUG("could not get a type name for 'enum object_type' value %d", type); | ||||||
|  |  | ||||||
|  | 	return format_object_header_literally(str, size, name, objsize); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * With an in-core object data in "map", rehash it to make sure the |  * With an in-core object data in "map", rehash it to make sure the | ||||||
|  * object name actually matches "oid" to detect object corruption. |  * object name actually matches "oid" to detect object corruption. | ||||||
|  | @ -1077,7 +1094,7 @@ int check_object_signature(struct repository *r, const struct object_id *oid, | ||||||
| 		return -1; | 		return -1; | ||||||
|  |  | ||||||
| 	/* Generate the header */ | 	/* Generate the header */ | ||||||
| 	hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(obj_type), (uintmax_t)size) + 1; | 	hdrlen = format_object_header(hdr, sizeof(hdr), obj_type, size); | ||||||
|  |  | ||||||
| 	/* Sha1.. */ | 	/* Sha1.. */ | ||||||
| 	r->hash_algo->init_fn(&c); | 	r->hash_algo->init_fn(&c); | ||||||
|  | @ -1777,7 +1794,7 @@ static void write_object_file_prepare(const struct git_hash_algo *algo, | ||||||
| 	git_hash_ctx c; | 	git_hash_ctx c; | ||||||
|  |  | ||||||
| 	/* Generate the header */ | 	/* Generate the header */ | ||||||
| 	*hdrlen = xsnprintf(hdr, *hdrlen, "%s %"PRIuMAX , type, (uintmax_t)len)+1; | 	*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len); | ||||||
|  |  | ||||||
| 	/* Sha1.. */ | 	/* Sha1.. */ | ||||||
| 	algo->init_fn(&c); | 	algo->init_fn(&c); | ||||||
|  | @ -2051,7 +2068,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime) | ||||||
| 	buf = read_object(the_repository, oid, &type, &len); | 	buf = read_object(the_repository, oid, &type, &len); | ||||||
| 	if (!buf) | 	if (!buf) | ||||||
| 		return error(_("cannot read object for %s"), oid_to_hex(oid)); | 		return error(_("cannot read object for %s"), oid_to_hex(oid)); | ||||||
| 	hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1; | 	hdrlen = format_object_header(hdr, sizeof(hdr), type, len); | ||||||
| 	ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime, 0); | 	ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime, 0); | ||||||
| 	free(buf); | 	free(buf); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -331,6 +331,14 @@ int repo_has_object_file_with_flags(struct repository *r, | ||||||
|  */ |  */ | ||||||
| int has_loose_object_nonlocal(const struct object_id *); | int has_loose_object_nonlocal(const struct object_id *); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * format_object_header() is a thin wrapper around s xsnprintf() that | ||||||
|  |  * writes the initial "<type> <obj-len>" part of the loose object | ||||||
|  |  * header. It returns the size that snprintf() returns + 1. | ||||||
|  |  */ | ||||||
|  | int format_object_header(char *str, size_t size, enum object_type type, | ||||||
|  | 			 size_t objsize); | ||||||
|  |  | ||||||
| void assert_oid_type(const struct object_id *oid, enum object_type expect); | void assert_oid_type(const struct object_id *oid, enum object_type expect); | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Ævar Arnfjörð Bjarmason
						Ævar Arnfjörð Bjarmason