git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface
@ 2022-02-01 14:53 Ævar Arnfjörð Bjarmason
  2022-02-01 14:53 ` [PATCH 01/10] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
                   ` (10 more replies)
  0 siblings, 11 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 14:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

This is intended to help along the "unpack large blobs in stream"
series that Han Xin has been submitting. The v9 of it is available
at[1], but not currently picked up by Junio.

This changes those parts of the object-file.c API that took a "const
char *" type to take an "enum object_type" instead. We had a lot of
places that would convert back & forth between the two for no good
reason. We're still left with the "literally" interface for "git
hash-object --literally", but it's now a tiny part of the API that's
sidelined.

This also has various small API cleanups, such as returning "void" in
a case where no caller did (or should) use a return value in the case
of hash_object_file().

We then introduce the format_object_header() helper, part of that was
in Han Xin's version, but we had various other in-tree users that
could use it (which I found later, after my initial RFC patch).

We can then split up the two classes of API users of
check_object_signature() to use two different functions, which suits
their uses much better. Half of them were making use of a very early
return.

1. https://lore.kernel.org/git/20220120112114.47618-1-chiyutianyi@gmail.com/

Ævar Arnfjörð Bjarmason (10):
  object-file.c: split up declaration of unrelated variables
  object-file API: return "void", not "int" from hash_object_file()
  object-file API: add a format_object_header() function
  object-file API: have write_object_file() take "enum object_type"
  object-file API: provide a hash_object_file_oideq()
  object-file API: replace some use of check_object_signature()
  object-file API: have hash_object_file() take "enum object_type"
  object-file API: replace check_object_signature() with stream_*
  object-file.c: add a literal version of write_object_file_prepare()
  object-file API: pass an enum to read_object_with_reference()

 apply.c                  |  12 ++--
 builtin/cat-file.c       |  11 +--
 builtin/checkout.c       |   2 +-
 builtin/fast-export.c    |   4 +-
 builtin/fast-import.c    |  12 ++--
 builtin/grep.c           |   4 +-
 builtin/hash-object.c    |   4 +-
 builtin/index-pack.c     |  10 ++-
 builtin/mktag.c          |   7 +-
 builtin/mktree.c         |   2 +-
 builtin/notes.c          |   3 +-
 builtin/pack-objects.c   |   2 +-
 builtin/receive-pack.c   |   2 +-
 builtin/replace.c        |   4 +-
 builtin/tag.c            |   2 +-
 builtin/unpack-objects.c |   8 +--
 bulk-checkin.c           |   4 +-
 cache-tree.c             |   8 +--
 cache.h                  |  13 ++--
 commit.c                 |   2 +-
 convert.c                |   2 +-
 diffcore-rename.c        |   2 +-
 dir.c                    |   2 +-
 http-push.c              |   2 +-
 log-tree.c               |   2 +-
 match-trees.c            |   2 +-
 merge-ort.c              |   4 +-
 merge-recursive.c        |   2 +-
 notes-cache.c            |   2 +-
 notes.c                  |   8 +--
 object-file.c            | 142 ++++++++++++++++++++++++++-------------
 object-store.h           |  39 ++++++++---
 object.c                 |   6 +-
 pack-check.c             |   8 ++-
 read-cache.c             |   2 +-
 tree-walk.c              |   6 +-
 36 files changed, 213 insertions(+), 134 deletions(-)

-- 
2.35.0.913.g12b4baa2536


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 01/10] object-file.c: split up declaration of unrelated variables
  2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
@ 2022-02-01 14:53 ` Ævar Arnfjörð Bjarmason
  2022-02-01 14:53 ` [PATCH 02/10] object-file API: return "void", not "int" from hash_object_file() Ævar Arnfjörð Bjarmason
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 14:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Split up the declaration of the "ret" and "re_allocated"
variables. It's not our usual style to group variable declarations
simply because they share a type, we'd only prefer to do so when the
two are closely related (e.g. "int i, j"). This change makes a
subsequent and meaningful change's diff smaller.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 object-file.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/object-file.c b/object-file.c
index 8be57f48de7..ecc77973292 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2118,7 +2118,8 @@ static int index_mem(struct index_state *istate,
 		     enum object_type type,
 		     const char *path, unsigned flags)
 {
-	int ret, re_allocated = 0;
+	int ret;
+	int re_allocated = 0;
 	int write_object = flags & HASH_WRITE_OBJECT;
 
 	if (!type)
-- 
2.35.0.913.g12b4baa2536


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 02/10] object-file API: return "void", not "int" from hash_object_file()
  2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
  2022-02-01 14:53 ` [PATCH 01/10] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
@ 2022-02-01 14:53 ` Ævar Arnfjörð Bjarmason
  2022-02-01 14:53 ` [PATCH 03/10] object-file API: add a format_object_header() function Ævar Arnfjörð Bjarmason
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 14:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

The hash_object_file() function added in abdc3fc8421 (Add
hash_sha1_file(), 2006-10-14) did not have a meaningful return value,
and it never has.

One was seemingly added to avoid adding braces to the "ret = "
assignments being modified here. Let's instead assign "0" to the "ret"
variables at the beginning of the relevant functions, and have them
return "void".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 object-file.c  | 16 ++++++++--------
 object-store.h |  6 +++---
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/object-file.c b/object-file.c
index ecc77973292..eeb6814780a 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1836,14 +1836,13 @@ static int write_buffer(int fd, const void *buf, size_t len)
 	return 0;
 }
 
-int hash_object_file(const struct git_hash_algo *algo, const void *buf,
+void hash_object_file(const struct git_hash_algo *algo, const void *buf,
 		     unsigned long len, const char *type,
 		     struct object_id *oid)
 {
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen = sizeof(hdr);
 	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
-	return 0;
 }
 
 /* Finalize a file on disk, and close it. */
@@ -2118,7 +2117,7 @@ static int index_mem(struct index_state *istate,
 		     enum object_type type,
 		     const char *path, unsigned flags)
 {
-	int ret;
+	int ret = 0;
 	int re_allocated = 0;
 	int write_object = flags & HASH_WRITE_OBJECT;
 
@@ -2148,8 +2147,9 @@ static int index_mem(struct index_state *istate,
 	if (write_object)
 		ret = write_object_file(buf, size, type_name(type), oid);
 	else
-		ret = hash_object_file(the_hash_algo, buf, size,
-				       type_name(type), oid);
+		hash_object_file(the_hash_algo, buf, size, type_name(type),
+				 oid);
+
 	if (re_allocated)
 		free(buf);
 	return ret;
@@ -2161,7 +2161,7 @@ static int index_stream_convert_blob(struct index_state *istate,
 				     const char *path,
 				     unsigned flags)
 {
-	int ret;
+	int ret = 0;
 	const int write_object = flags & HASH_WRITE_OBJECT;
 	struct strbuf sbuf = STRBUF_INIT;
 
@@ -2175,8 +2175,8 @@ static int index_stream_convert_blob(struct index_state *istate,
 		ret = write_object_file(sbuf.buf, sbuf.len, type_name(OBJ_BLOB),
 					oid);
 	else
-		ret = hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
-				       type_name(OBJ_BLOB), oid);
+		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
+				 type_name(OBJ_BLOB), oid);
 	strbuf_release(&sbuf);
 	return ret;
 }
diff --git a/object-store.h b/object-store.h
index 6f89482df03..44f6868cc9c 100644
--- a/object-store.h
+++ b/object-store.h
@@ -245,9 +245,9 @@ static inline void *repo_read_object_file(struct repository *r,
 /* Read and unpack an object file into memory, write memory to an object file */
 int oid_object_info(struct repository *r, const struct object_id *, unsigned long *);
 
-int hash_object_file(const struct git_hash_algo *algo, const void *buf,
-		     unsigned long len, const char *type,
-		     struct object_id *oid);
+void hash_object_file(const struct git_hash_algo *algo, const void *buf,
+		      unsigned long len, const char *type,
+		      struct object_id *oid);
 
 int write_object_file_flags(const void *buf, unsigned long len,
 			    const char *type, struct object_id *oid,
-- 
2.35.0.913.g12b4baa2536


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 03/10] object-file API: add a format_object_header() function
  2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
  2022-02-01 14:53 ` [PATCH 01/10] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
  2022-02-01 14:53 ` [PATCH 02/10] object-file API: return "void", not "int" from hash_object_file() Ævar Arnfjörð Bjarmason
@ 2022-02-01 14:53 ` Ævar Arnfjörð Bjarmason
  2022-02-01 14:53 ` [PATCH 04/10] object-file API: have write_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 14:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

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>
---
 builtin/fast-import.c |  6 +++---
 builtin/index-pack.c  |  3 +--
 bulk-checkin.c        |  4 ++--
 http-push.c           |  2 +-
 object-file.c         | 23 ++++++++++++++++++++---
 object-store.h        |  8 ++++++++
 6 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 2b2e28bad79..123df7d9a53 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -937,8 +937,8 @@ static int store_object(
 	git_hash_ctx c;
 	git_zstream s;
 
-	hdrlen = xsnprintf((char *)hdr, sizeof(hdr), "%s %lu",
-			   type_name(type), (unsigned long)dat->len) + 1;
+	hdrlen = format_object_header((char *)hdr, sizeof(hdr), type,
+				      dat->len);
 	the_hash_algo->init_fn(&c);
 	the_hash_algo->update_fn(&c, hdr, hdrlen);
 	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);
 	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->update_fn(&c, out_buf, hdrlen);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 3c2e6aee3cc..01574378ce2 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -449,8 +449,7 @@ static void *unpack_entry_data(off_t offset, unsigned long size,
 	int hdrlen;
 
 	if (!is_delta_type(type)) {
-		hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX,
-				   type_name(type),(uintmax_t)size) + 1;
+		hdrlen = format_object_header(hdr, sizeof(hdr), type, size);
 		the_hash_algo->init_fn(&c);
 		the_hash_algo->update_fn(&c, hdr, hdrlen);
 	} else
diff --git a/bulk-checkin.c b/bulk-checkin.c
index 8785b2ac806..85b3ebaf971 100644
--- a/bulk-checkin.c
+++ b/bulk-checkin.c
@@ -220,8 +220,8 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
 	if (seekback == (off_t) -1)
 		return error("cannot find the current offset");
 
-	header_len = xsnprintf((char *)obuf, sizeof(obuf), "%s %" PRIuMAX,
-			       type_name(type), (uintmax_t)size) + 1;
+	header_len = format_object_header((char *)obuf, sizeof(obuf),
+					  type, size);
 	the_hash_algo->init_fn(&ctx);
 	the_hash_algo->update_fn(&ctx, obuf, header_len);
 
diff --git a/http-push.c b/http-push.c
index 3309aaf004a..f0c044dcf76 100644
--- a/http-push.c
+++ b/http-push.c
@@ -363,7 +363,7 @@ static void start_put(struct transfer_request *request)
 	git_zstream stream;
 
 	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 */
 	git_deflate_init(&stream, zlib_compression_level);
diff --git a/object-file.c b/object-file.c
index eeb6814780a..3fcd46cf9ed 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1049,6 +1049,23 @@ void *xmmap(void *start, size_t length,
 	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
  * 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;
 
 	/* 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.. */
 	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;
 
 	/* Generate the header */
-	*hdrlen = xsnprintf(hdr, *hdrlen, "%s %"PRIuMAX , type, (uintmax_t)len)+1;
+	*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
 
 	/* Sha1.. */
 	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);
 	if (!buf)
 		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);
 	free(buf);
 
diff --git a/object-store.h b/object-store.h
index 44f6868cc9c..8b4413d0ce7 100644
--- a/object-store.h
+++ b/object-store.h
@@ -331,6 +331,14 @@ int repo_has_object_file_with_flags(struct repository *r,
  */
 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);
 
 /*
-- 
2.35.0.913.g12b4baa2536


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 04/10] object-file API: have write_object_file() take "enum object_type"
  2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                   ` (2 preceding siblings ...)
  2022-02-01 14:53 ` [PATCH 03/10] object-file API: add a format_object_header() function Ævar Arnfjörð Bjarmason
@ 2022-02-01 14:53 ` Ævar Arnfjörð Bjarmason
  2022-02-01 18:58   ` Junio C Hamano
  2022-02-01 14:53 ` [PATCH 05/10] object-file API: provide a hash_object_file_oideq() Ævar Arnfjörð Bjarmason
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 14:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the write_object_file() function to take an "enum object_type"
instead of a "const char *type". Its callers either passed
{commit,tree,blob,tag}_type and can pass the corresponding OBJ_* type
instead, or were hardcoding strings like "blob".

This avoids the back & forth fragility where the callers of
write_object_file() would have the enum type, and convert it
themselves via type_name(). We do have to now do that conversion
ourselves before calling write_object_file_prepare(), but those
codepaths will be similarly adjusted in subsequent commits.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 apply.c                  |  8 ++++----
 builtin/checkout.c       |  2 +-
 builtin/mktag.c          |  2 +-
 builtin/mktree.c         |  2 +-
 builtin/notes.c          |  3 +--
 builtin/receive-pack.c   |  2 +-
 builtin/replace.c        |  2 +-
 builtin/tag.c            |  2 +-
 builtin/unpack-objects.c |  6 +++---
 cache-tree.c             |  2 +-
 commit.c                 |  2 +-
 match-trees.c            |  2 +-
 merge-ort.c              |  4 ++--
 merge-recursive.c        |  2 +-
 notes-cache.c            |  2 +-
 notes.c                  |  8 ++++----
 object-file.c            | 10 +++++-----
 object-store.h           |  4 ++--
 read-cache.c             |  2 +-
 19 files changed, 33 insertions(+), 34 deletions(-)

diff --git a/apply.c b/apply.c
index 7ffadc3b17a..e82a7c30f01 100644
--- a/apply.c
+++ b/apply.c
@@ -3589,7 +3589,7 @@ static int try_threeway(struct apply_state *state,
 
 	/* Preimage the patch was prepared for */
 	if (patch->is_new)
-		write_object_file("", 0, blob_type, &pre_oid);
+		write_object_file("", 0, OBJ_BLOB, &pre_oid);
 	else if (get_oid(patch->old_oid_prefix, &pre_oid) ||
 		 read_blob_object(&buf, &pre_oid, patch->old_mode))
 		return error(_("repository lacks the necessary blob to perform 3-way merge."));
@@ -3605,7 +3605,7 @@ static int try_threeway(struct apply_state *state,
 		return -1;
 	}
 	/* post_oid is theirs */
-	write_object_file(tmp_image.buf, tmp_image.len, blob_type, &post_oid);
+	write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &post_oid);
 	clear_image(&tmp_image);
 
 	/* our_oid is ours */
@@ -3618,7 +3618,7 @@ static int try_threeway(struct apply_state *state,
 			return error(_("cannot read the current contents of '%s'"),
 				     patch->old_name);
 	}
-	write_object_file(tmp_image.buf, tmp_image.len, blob_type, &our_oid);
+	write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &our_oid);
 	clear_image(&tmp_image);
 
 	/* in-core three-way merge between post and our using pre as base */
@@ -4346,7 +4346,7 @@ static int add_index_file(struct apply_state *state,
 			}
 			fill_stat_cache_info(state->repo->index, ce, &st);
 		}
-		if (write_object_file(buf, size, blob_type, &ce->oid) < 0) {
+		if (write_object_file(buf, size, OBJ_BLOB, &ce->oid) < 0) {
 			discard_cache_entry(ce);
 			return error(_("unable to create backing store "
 				       "for newly created file %s"), path);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index cc804ba8e1e..24cc235939f 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -298,7 +298,7 @@ static int checkout_merged(int pos, const struct checkout *state,
 	 * (it also writes the merge result to the object database even
 	 * when it may contain conflicts).
 	 */
-	if (write_object_file(result_buf.ptr, result_buf.size, blob_type, &oid))
+	if (write_object_file(result_buf.ptr, result_buf.size, OBJ_BLOB, &oid))
 		die(_("Unable to add merge result for '%s'"), path);
 	free(result_buf.ptr);
 	ce = make_transient_cache_entry(mode, &oid, path, 2, ce_mem_pool);
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 3b2dbbb37e6..96a3686af53 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -100,7 +100,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (verify_object_in_tag(&tagged_oid, &tagged_type))
 		die(_("tag on stdin did not refer to a valid object"));
 
-	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
+	if (write_object_file(buf.buf, buf.len, OBJ_TAG, &result) < 0)
 		die(_("unable to write tag file"));
 
 	strbuf_release(&buf);
diff --git a/builtin/mktree.c b/builtin/mktree.c
index ae78ca1c029..a1213aaa961 100644
--- a/builtin/mktree.c
+++ b/builtin/mktree.c
@@ -58,7 +58,7 @@ static void write_tree(struct object_id *oid)
 		strbuf_add(&buf, ent->oid.hash, the_hash_algo->rawsz);
 	}
 
-	write_object_file(buf.buf, buf.len, tree_type, oid);
+	write_object_file(buf.buf, buf.len, OBJ_TREE, oid);
 	strbuf_release(&buf);
 }
 
diff --git a/builtin/notes.c b/builtin/notes.c
index 05d60483e82..d81acaeaf78 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -199,9 +199,8 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
 
 static void write_note_data(struct note_data *d, struct object_id *oid)
 {
-	if (write_object_file(d->buf.buf, d->buf.len, blob_type, oid)) {
+	if (write_object_file(d->buf.buf, d->buf.len, OBJ_BLOB, oid)) {
 		int status = die_message(_("unable to write note object"));
-
 		if (d->edit_path)
 			die_message(_("the note contents have been left in %s"),
 				    d->edit_path);
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 9f4a0b816cf..231d576927b 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -762,7 +762,7 @@ static void prepare_push_cert_sha1(struct child_process *proc)
 		int bogs /* beginning_of_gpg_sig */;
 
 		already_done = 1;
-		if (write_object_file(push_cert.buf, push_cert.len, "blob",
+		if (write_object_file(push_cert.buf, push_cert.len, OBJ_BLOB,
 				      &push_cert_oid))
 			oidclr(&push_cert_oid);
 
diff --git a/builtin/replace.c b/builtin/replace.c
index 6ff1734d587..995ca683302 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -474,7 +474,7 @@ static int create_graft(int argc, const char **argv, int force, int gentle)
 		return -1;
 	}
 
-	if (write_object_file(buf.buf, buf.len, commit_type, &new_oid)) {
+	if (write_object_file(buf.buf, buf.len, OBJ_COMMIT, &new_oid)) {
 		strbuf_release(&buf);
 		return error(_("could not write replacement commit for: '%s'"),
 			     old_ref);
diff --git a/builtin/tag.c b/builtin/tag.c
index 134b3f1edf0..31e6b155c04 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -238,7 +238,7 @@ static int build_tag_object(struct strbuf *buf, int sign, struct object_id *resu
 {
 	if (sign && do_sign(buf) < 0)
 		return error(_("unable to sign the tag"));
-	if (write_object_file(buf->buf, buf->len, tag_type, result) < 0)
+	if (write_object_file(buf->buf, buf->len, OBJ_TAG, result) < 0)
 		return error(_("unable to write tag file"));
 	return 0;
 }
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 4a9466295ba..808041551fd 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -177,7 +177,7 @@ static void write_cached_object(struct object *obj, struct obj_buffer *obj_buf)
 	struct object_id oid;
 
 	if (write_object_file(obj_buf->buffer, obj_buf->size,
-			      type_name(obj->type), &oid) < 0)
+			      obj->type, &oid) < 0)
 		die("failed to write object %s", oid_to_hex(&obj->oid));
 	obj->flags |= FLAG_WRITTEN;
 }
@@ -243,7 +243,7 @@ static void write_object(unsigned nr, enum object_type type,
 			 void *buf, unsigned long size)
 {
 	if (!strict) {
-		if (write_object_file(buf, size, type_name(type),
+		if (write_object_file(buf, size, type,
 				      &obj_list[nr].oid) < 0)
 			die("failed to write object");
 		added_object(nr, type, buf, size);
@@ -251,7 +251,7 @@ static void write_object(unsigned nr, enum object_type type,
 		obj_list[nr].obj = NULL;
 	} else if (type == OBJ_BLOB) {
 		struct blob *blob;
-		if (write_object_file(buf, size, type_name(type),
+		if (write_object_file(buf, size, type,
 				      &obj_list[nr].oid) < 0)
 			die("failed to write object");
 		added_object(nr, type, buf, size);
diff --git a/cache-tree.c b/cache-tree.c
index 65ca9933613..fdbbd191d22 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -440,7 +440,7 @@ static int update_one(struct cache_tree *it,
 	} else if (dryrun) {
 		hash_object_file(the_hash_algo, buffer.buf, buffer.len,
 				 tree_type, &it->oid);
-	} else if (write_object_file_flags(buffer.buf, buffer.len, tree_type,
+	} else if (write_object_file_flags(buffer.buf, buffer.len, OBJ_TREE,
 					   &it->oid, flags & WRITE_TREE_SILENT
 					   ? HASH_SILENT : 0)) {
 		strbuf_release(&buffer);
diff --git a/commit.c b/commit.c
index a348f085b2b..6cc0ba9c11b 100644
--- a/commit.c
+++ b/commit.c
@@ -1567,7 +1567,7 @@ int commit_tree_extended(const char *msg, size_t msg_len,
 		goto out;
 	}
 
-	result = write_object_file(buffer.buf, buffer.len, commit_type, ret);
+	result = write_object_file(buffer.buf, buffer.len, OBJ_COMMIT, ret);
 out:
 	strbuf_release(&buffer);
 	return result;
diff --git a/match-trees.c b/match-trees.c
index df413989fa8..49398e599fe 100644
--- a/match-trees.c
+++ b/match-trees.c
@@ -235,7 +235,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
 		rewrite_with = oid2;
 	}
 	hashcpy(rewrite_here, rewrite_with->hash);
-	status = write_object_file(buf, sz, tree_type, result);
+	status = write_object_file(buf, sz, OBJ_TREE, result);
 	free(buf);
 	return status;
 }
diff --git a/merge-ort.c b/merge-ort.c
index c3197970219..d4ba2955f11 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -1888,7 +1888,7 @@ static int handle_content_merge(struct merge_options *opt,
 
 		if (!ret &&
 		    write_object_file(result_buf.ptr, result_buf.size,
-				      blob_type, &result->oid))
+				      OBJ_BLOB, &result->oid))
 			ret = err(opt, _("Unable to add %s to database"),
 				  path);
 
@@ -3343,7 +3343,7 @@ static void write_tree(struct object_id *result_oid,
 	}
 
 	/* Write this object file out, and record in result_oid */
-	write_object_file(buf.buf, buf.len, tree_type, result_oid);
+	write_object_file(buf.buf, buf.len, OBJ_TREE, result_oid);
 	strbuf_release(&buf);
 }
 
diff --git a/merge-recursive.c b/merge-recursive.c
index d9457797dbb..e0cbbf2d022 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1373,7 +1373,7 @@ static int merge_mode_and_contents(struct merge_options *opt,
 
 			if (!ret &&
 			    write_object_file(result_buf.ptr, result_buf.size,
-					      blob_type, &result->blob.oid))
+					      OBJ_BLOB, &result->blob.oid))
 				ret = err(opt, _("Unable to add %s to database"),
 					  a->path);
 
diff --git a/notes-cache.c b/notes-cache.c
index 2473314d686..9dfd251a815 100644
--- a/notes-cache.c
+++ b/notes-cache.c
@@ -92,7 +92,7 @@ int notes_cache_put(struct notes_cache *c, struct object_id *key_oid,
 {
 	struct object_id value_oid;
 
-	if (write_object_file(data, size, "blob", &value_oid) < 0)
+	if (write_object_file(data, size, OBJ_BLOB, &value_oid) < 0)
 		return -1;
 	return add_note(&c->tree, key_oid, &value_oid, NULL);
 }
diff --git a/notes.c b/notes.c
index f87dac40684..7452e71cc8d 100644
--- a/notes.c
+++ b/notes.c
@@ -675,7 +675,7 @@ static int tree_write_stack_finish_subtree(struct tree_write_stack *tws)
 		ret = tree_write_stack_finish_subtree(n);
 		if (ret)
 			return ret;
-		ret = write_object_file(n->buf.buf, n->buf.len, tree_type, &s);
+		ret = write_object_file(n->buf.buf, n->buf.len, OBJ_TREE, &s);
 		if (ret)
 			return ret;
 		strbuf_release(&n->buf);
@@ -836,7 +836,7 @@ int combine_notes_concatenate(struct object_id *cur_oid,
 	free(new_msg);
 
 	/* create a new blob object from buf */
-	ret = write_object_file(buf, buf_len, blob_type, cur_oid);
+	ret = write_object_file(buf, buf_len, OBJ_BLOB, cur_oid);
 	free(buf);
 	return ret;
 }
@@ -916,7 +916,7 @@ int combine_notes_cat_sort_uniq(struct object_id *cur_oid,
 				 string_list_join_lines_helper, &buf))
 		goto out;
 
-	ret = write_object_file(buf.buf, buf.len, blob_type, cur_oid);
+	ret = write_object_file(buf.buf, buf.len, OBJ_BLOB, cur_oid);
 
 out:
 	strbuf_release(&buf);
@@ -1192,7 +1192,7 @@ int write_notes_tree(struct notes_tree *t, struct object_id *result)
 	ret = for_each_note(t, flags, write_each_note, &cb_data) ||
 	      write_each_non_note_until(NULL, &cb_data) ||
 	      tree_write_stack_finish_subtree(&root) ||
-	      write_object_file(root.buf.buf, root.buf.len, tree_type, result);
+	      write_object_file(root.buf.buf, root.buf.len, OBJ_TREE, result);
 	strbuf_release(&root.buf);
 	return ret;
 }
diff --git a/object-file.c b/object-file.c
index 3fcd46cf9ed..59eb793e0ac 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2014,7 +2014,7 @@ static int freshen_packed_object(const struct object_id *oid)
 }
 
 int write_object_file_flags(const void *buf, unsigned long len,
-			    const char *type, struct object_id *oid,
+			    enum object_type type, struct object_id *oid,
 			    unsigned flags)
 {
 	char hdr[MAX_HEADER_LEN];
@@ -2023,7 +2023,7 @@ int write_object_file_flags(const void *buf, unsigned long len,
 	/* Normally if we have it in the pack then we do not bother writing
 	 * it out into .git/objects/??/?{38} file.
 	 */
-	write_object_file_prepare(the_hash_algo, buf, len, type, oid, hdr,
+	write_object_file_prepare(the_hash_algo, buf, len, type_name(type), oid, hdr,
 				  &hdrlen);
 	if (freshen_packed_object(oid) || freshen_loose_object(oid))
 		return 0;
@@ -2162,7 +2162,7 @@ static int index_mem(struct index_state *istate,
 	}
 
 	if (write_object)
-		ret = write_object_file(buf, size, type_name(type), oid);
+		ret = write_object_file(buf, size, type, oid);
 	else
 		hash_object_file(the_hash_algo, buf, size, type_name(type),
 				 oid);
@@ -2189,7 +2189,7 @@ static int index_stream_convert_blob(struct index_state *istate,
 				 get_conv_flags(flags));
 
 	if (write_object)
-		ret = write_object_file(sbuf.buf, sbuf.len, type_name(OBJ_BLOB),
+		ret = write_object_file(sbuf.buf, sbuf.len, OBJ_BLOB,
 					oid);
 	else
 		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
@@ -2313,7 +2313,7 @@ int index_path(struct index_state *istate, struct object_id *oid,
 		if (!(flags & HASH_WRITE_OBJECT))
 			hash_object_file(the_hash_algo, sb.buf, sb.len,
 					 blob_type, oid);
-		else if (write_object_file(sb.buf, sb.len, blob_type, oid))
+		else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid))
 			rc = error(_("%s: failed to insert into database"), path);
 		strbuf_release(&sb);
 		break;
diff --git a/object-store.h b/object-store.h
index 8b4413d0ce7..eab1e2a967e 100644
--- a/object-store.h
+++ b/object-store.h
@@ -250,10 +250,10 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf,
 		      struct object_id *oid);
 
 int write_object_file_flags(const void *buf, unsigned long len,
-			    const char *type, struct object_id *oid,
+			    enum object_type type, struct object_id *oid,
 			    unsigned flags);
 static inline int write_object_file(const void *buf, unsigned long len,
-				    const char *type, struct object_id *oid)
+				    enum object_type type, struct object_id *oid)
 {
 	return write_object_file_flags(buf, len, type, oid, 0);
 }
diff --git a/read-cache.c b/read-cache.c
index cbe73f14e5e..b8ae30a0e71 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -735,7 +735,7 @@ static struct cache_entry *create_alias_ce(struct index_state *istate,
 void set_object_name_for_intent_to_add_entry(struct cache_entry *ce)
 {
 	struct object_id oid;
-	if (write_object_file("", 0, blob_type, &oid))
+	if (write_object_file("", 0, OBJ_BLOB, &oid))
 		die(_("cannot create an empty blob in the object database"));
 	oidcpy(&ce->oid, &oid);
 }
-- 
2.35.0.913.g12b4baa2536


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 05/10] object-file API: provide a hash_object_file_oideq()
  2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                   ` (3 preceding siblings ...)
  2022-02-01 14:53 ` [PATCH 04/10] object-file API: have write_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
@ 2022-02-01 14:53 ` Ævar Arnfjörð Bjarmason
  2022-02-01 19:08   ` Junio C Hamano
  2022-02-01 14:53 ` [PATCH 06/10] object-file API: replace some use of check_object_signature() Ævar Arnfjörð Bjarmason
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 14:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Provide a new hash_object_file_oideq() for those callers of
check_object_signature() that don't care about its streaming
interface. I.e. at the start of that function we do:

	if (map) {
		hash_object_file(r->hash_algo, map, size, type, real_oid);
		return !oideq(oid, real_oid) ? -1 : 0;
	}

These callers always provide a "map" (or "buf[fer]"). Let's have them
call this simpler hash_object_file_oideq() function instead.

None of them use a non-NULL "real_oid" argument, but let's provide it
like check_object_signature() did. This'll make it easy to have these
emit better error messages in the future as was done in
96e41f58fe1 (fsck: report invalid object type-path combinations,
2021-10-01), i.e. the die() calls here can emit not only the OID we
expected, but also what we got.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/fast-export.c |  4 ++--
 builtin/index-pack.c  |  5 ++---
 builtin/mktag.c       |  5 ++---
 object-file.c         | 13 +++++++++++++
 object-store.h        | 14 ++++++++++++++
 object.c              |  4 ++--
 6 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 9f1c730e587..f084da198c7 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -299,8 +299,8 @@ static void export_blob(const struct object_id *oid)
 		buf = read_object_file(oid, &type, &size);
 		if (!buf)
 			die("could not read blob %s", oid_to_hex(oid));
-		if (check_object_signature(the_repository, oid, buf, size,
-					   type_name(type), NULL) < 0)
+		if (!hash_object_file_oideq(the_repository->hash_algo, buf,
+					    size, type, oid, NULL))
 			die("oid mismatch in blob %s", oid_to_hex(oid));
 		object = parse_object_buffer(the_repository, oid, type,
 					     size, buf, &eaten);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 01574378ce2..5531a6d8bae 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1412,9 +1412,8 @@ static void fix_unresolved_deltas(struct hashfile *f)
 		if (!data)
 			continue;
 
-		if (check_object_signature(the_repository, &d->oid,
-					   data, size,
-					   type_name(type), NULL))
+		if (!hash_object_file_oideq(the_repository->hash_algo, data,
+					    size, type, &d->oid, NULL))
 			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
 
 		/*
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 96a3686af53..d8c7cf836b7 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -61,9 +61,8 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 		    type_name(*tagged_type), type_name(type));
 
 	repl = lookup_replace_object(the_repository, tagged_oid);
-	ret = check_object_signature(the_repository, repl,
-				     buffer, size, type_name(*tagged_type),
-				     NULL);
+	ret = !hash_object_file_oideq(the_repository->hash_algo, buffer, size,
+				      *tagged_type, repl, NULL);
 	free(buffer);
 
 	return ret;
diff --git a/object-file.c b/object-file.c
index 59eb793e0ac..27d10112960 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1862,6 +1862,19 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf,
 	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
 }
 
+int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
+			   unsigned long len, enum object_type type,
+			   const struct object_id *oid,
+			   struct object_id *real_oidp)
+{
+	struct object_id tmp;
+	struct object_id *real_oid = real_oidp ? real_oidp : &tmp;
+
+	hash_object_file(algo, buf, len, type_name(type), real_oid);
+
+	return oideq(oid, real_oid);
+}
+
 /* Finalize a file on disk, and close it. */
 static void close_loose_object(int fd)
 {
diff --git a/object-store.h b/object-store.h
index eab1e2a967e..95907062682 100644
--- a/object-store.h
+++ b/object-store.h
@@ -249,6 +249,20 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf,
 		      unsigned long len, const char *type,
 		      struct object_id *oid);
 
+/**
+ * hash_object_file_oideq() is like hash_object_file() except that
+ * asserts that "real_oid" is equivalent to an input "oid", and the
+ * return value is that of oideq(oid, real_oid).
+ *
+ * The "real_oid" can be NULL, when non-NULL the caller provides a
+ * "struct object_id *" that can be used to print what the real OID
+ * was.
+ */
+int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
+			   unsigned long len, enum object_type type,
+			   const struct object_id *oid,
+			   struct object_id *real_oidp);
+
 int write_object_file_flags(const void *buf, unsigned long len,
 			    enum object_type type, struct object_id *oid,
 			    unsigned flags);
diff --git a/object.c b/object.c
index c37501fc120..d7673332582 100644
--- a/object.c
+++ b/object.c
@@ -289,8 +289,8 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
 
 	buffer = repo_read_object_file(r, oid, &type, &size);
 	if (buffer) {
-		if (check_object_signature(r, repl, buffer, size,
-					   type_name(type), NULL) < 0) {
+		if (!hash_object_file_oideq(r->hash_algo, buffer, size,
+					    type, repl, NULL)) {
 			free(buffer);
 			error(_("hash mismatch %s"), oid_to_hex(repl));
 			return NULL;
-- 
2.35.0.913.g12b4baa2536


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 06/10] object-file API: replace some use of check_object_signature()
  2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                   ` (4 preceding siblings ...)
  2022-02-01 14:53 ` [PATCH 05/10] object-file API: provide a hash_object_file_oideq() Ævar Arnfjörð Bjarmason
@ 2022-02-01 14:53 ` Ævar Arnfjörð Bjarmason
  2022-02-01 19:16   ` Junio C Hamano
  2022-02-01 14:53 ` [PATCH 07/10] object-file API: have hash_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 14:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Add a "hash_object_file_literally()" function to go with the existing
"hash_object_file()" function. This is currently a wrapper for its
sibling, but this change will allow us to change it to take an "enum
object_type" in a subsequent commit.

The only caller that wanted to pass a custom type to
"check_object_signature()" was the "git fsck" via its
"read_loose_object()", which is being changed here.

There was an existing hash_object_file_literally() which I'm renaming
to "hash_write_object_file_literally()", that function is only used
for "hash-object --literally". That renaming is being done because it
would be confusing to have a "hash_object_file_literally()" and a
"hash_object_file()" that do very different things.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/hash-object.c |  4 ++--
 object-file.c         | 18 +++++++++++++-----
 object-store.h        |  6 +++---
 3 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index c7b3ad74c60..624e9e677fb 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -25,8 +25,8 @@ static int hash_literally(struct object_id *oid, int fd, const char *type, unsig
 	if (strbuf_read(&buf, fd, 4096) < 0)
 		ret = -1;
 	else
-		ret = hash_object_file_literally(buf.buf, buf.len, type, oid,
-						 flags);
+		ret = hash_write_object_file_literally(buf.buf, buf.len, type, oid,
+						       flags);
 	strbuf_release(&buf);
 	return ret;
 }
diff --git a/object-file.c b/object-file.c
index 27d10112960..9fc959fa05d 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1862,6 +1862,13 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf,
 	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
 }
 
+static void hash_object_file_literally(const struct git_hash_algo *algo, const void *buf,
+				       unsigned long len, const char *type,
+				       struct object_id *oid)
+{
+	hash_object_file(algo, buf, len, type, oid);
+}
+
 int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
 			   unsigned long len, enum object_type type,
 			   const struct object_id *oid,
@@ -2043,9 +2050,9 @@ int write_object_file_flags(const void *buf, unsigned long len,
 	return write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags);
 }
 
-int hash_object_file_literally(const void *buf, unsigned long len,
-			       const char *type, struct object_id *oid,
-			       unsigned flags)
+int hash_write_object_file_literally(const void *buf, unsigned long len,
+				     const char *type, struct object_id *oid,
+				     unsigned flags)
 {
 	char *header;
 	int hdrlen, status = 0;
@@ -2630,9 +2637,10 @@ int read_loose_object(const char *path,
 			git_inflate_end(&stream);
 			goto out;
 		}
-		if (check_object_signature(the_repository, expected_oid,
+		hash_object_file_literally(the_repository->hash_algo,
 					   *contents, *size,
-					   oi->type_name->buf, real_oid))
+					   oi->type_name->buf, real_oid);
+		if (!oideq(expected_oid, real_oid))
 			goto out;
 	}
 
diff --git a/object-store.h b/object-store.h
index 95907062682..2ddc20b3304 100644
--- a/object-store.h
+++ b/object-store.h
@@ -272,9 +272,9 @@ static inline int write_object_file(const void *buf, unsigned long len,
 	return write_object_file_flags(buf, len, type, oid, 0);
 }
 
-int hash_object_file_literally(const void *buf, unsigned long len,
-			       const char *type, struct object_id *oid,
-			       unsigned flags);
+int hash_write_object_file_literally(const void *buf, unsigned long len,
+				     const char *type, struct object_id *oid,
+				     unsigned flags);
 
 /*
  * Add an object file to the in-memory object store, without writing it
-- 
2.35.0.913.g12b4baa2536


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 07/10] object-file API: have hash_object_file() take "enum object_type"
  2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                   ` (5 preceding siblings ...)
  2022-02-01 14:53 ` [PATCH 06/10] object-file API: replace some use of check_object_signature() Ævar Arnfjörð Bjarmason
@ 2022-02-01 14:53 ` Ævar Arnfjörð Bjarmason
  2022-02-01 14:53 ` [PATCH 08/10] object-file API: replace check_object_signature() with stream_* Ævar Arnfjörð Bjarmason
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 14:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the hash_object_file() function to take an "enum
object_type".

Almost all of its callers were passing either
"{commit,tree,blob,tag}_type", or the result of a call to
type_name(). Let's instead benefit from type checking and use the enum
directly.

"Almost" because one caller here will now pass OBJ_BAD. The previous
"NULL" value was not used, as "check_object_signature()" will never
use its "type" argument when given a NULL "map" argument, which that
caller in "parse_object()" also does. We'll deal with it in a
subsequent commit, but for now it'll pass an "OBJ_BAD" placeholder.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 apply.c                  |  4 ++--
 builtin/index-pack.c     |  2 +-
 builtin/replace.c        |  2 +-
 builtin/unpack-objects.c |  2 +-
 cache-tree.c             |  6 +++---
 cache.h                  |  2 +-
 convert.c                |  2 +-
 diffcore-rename.c        |  2 +-
 dir.c                    |  2 +-
 log-tree.c               |  2 +-
 object-file.c            | 26 ++++++++++++++------------
 object-store.h           |  3 ++-
 object.c                 |  2 +-
 pack-check.c             |  2 +-
 14 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/apply.c b/apply.c
index e82a7c30f01..8513755e254 100644
--- a/apply.c
+++ b/apply.c
@@ -3157,7 +3157,7 @@ static int apply_binary(struct apply_state *state,
 		 * See if the old one matches what the patch
 		 * applies to.
 		 */
-		hash_object_file(the_hash_algo, img->buf, img->len, blob_type,
+		hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB,
 				 &oid);
 		if (strcmp(oid_to_hex(&oid), patch->old_oid_prefix))
 			return error(_("the patch applies to '%s' (%s), "
@@ -3203,7 +3203,7 @@ static int apply_binary(struct apply_state *state,
 				     name);
 
 		/* verify that the result matches */
-		hash_object_file(the_hash_algo, img->buf, img->len, blob_type,
+		hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB,
 				 &oid);
 		if (strcmp(oid_to_hex(&oid), patch->new_oid_prefix))
 			return error(_("binary patch to '%s' creates incorrect result (expecting %s, got %s)"),
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 5531a6d8bae..4f2f4550e2e 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -970,7 +970,7 @@ static struct base_data *resolve_delta(struct object_entry *delta_obj,
 	if (!result_data)
 		bad_object(delta_obj->idx.offset, _("failed to apply delta"));
 	hash_object_file(the_hash_algo, result_data, result_size,
-			 type_name(delta_obj->real_type), &delta_obj->idx.oid);
+			 delta_obj->real_type, &delta_obj->idx.oid);
 	sha1_object(result_data, NULL, result_size, delta_obj->real_type,
 		    &delta_obj->idx.oid);
 
diff --git a/builtin/replace.c b/builtin/replace.c
index 995ca683302..53a3b246570 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -409,7 +409,7 @@ static int check_one_mergetag(struct commit *commit,
 	int i;
 
 	hash_object_file(the_hash_algo, extra->value, extra->len,
-			 type_name(OBJ_TAG), &tag_oid);
+			 OBJ_TAG, &tag_oid);
 	tag = lookup_tag(the_repository, &tag_oid);
 	if (!tag)
 		return error(_("bad mergetag in commit '%s'"), ref);
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 808041551fd..dbeb0680a58 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -266,7 +266,7 @@ static void write_object(unsigned nr, enum object_type type,
 	} else {
 		struct object *obj;
 		int eaten;
-		hash_object_file(the_hash_algo, buf, size, type_name(type),
+		hash_object_file(the_hash_algo, buf, size, type,
 				 &obj_list[nr].oid);
 		added_object(nr, type, buf, size);
 		obj = parse_object_buffer(the_repository, &obj_list[nr].oid,
diff --git a/cache-tree.c b/cache-tree.c
index fdbbd191d22..6752f69d515 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -432,14 +432,14 @@ static int update_one(struct cache_tree *it,
 	if (repair) {
 		struct object_id oid;
 		hash_object_file(the_hash_algo, buffer.buf, buffer.len,
-				 tree_type, &oid);
+				 OBJ_TREE, &oid);
 		if (has_object_file_with_flags(&oid, OBJECT_INFO_SKIP_FETCH_OBJECT))
 			oidcpy(&it->oid, &oid);
 		else
 			to_invalidate = 1;
 	} else if (dryrun) {
 		hash_object_file(the_hash_algo, buffer.buf, buffer.len,
-				 tree_type, &it->oid);
+				 OBJ_TREE, &it->oid);
 	} else if (write_object_file_flags(buffer.buf, buffer.len, OBJ_TREE,
 					   &it->oid, flags & WRITE_TREE_SILENT
 					   ? HASH_SILENT : 0)) {
@@ -948,7 +948,7 @@ static int verify_one(struct repository *r,
 		strbuf_addf(&tree_buf, "%o %.*s%c", mode, entlen, name, '\0');
 		strbuf_add(&tree_buf, oid->hash, r->hash_algo->rawsz);
 	}
-	hash_object_file(r->hash_algo, tree_buf.buf, tree_buf.len, tree_type,
+	hash_object_file(r->hash_algo, tree_buf.buf, tree_buf.len, OBJ_TREE,
 			 &new_oid);
 	if (!oideq(&new_oid, &it->oid))
 		BUG("cache-tree for path %.*s does not match. "
diff --git a/cache.h b/cache.h
index 281f00ab1b1..d9c68c66d53 100644
--- a/cache.h
+++ b/cache.h
@@ -1320,7 +1320,7 @@ struct object_info;
 int parse_loose_header(const char *hdr, struct object_info *oi);
 
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *buf, unsigned long size, const char *type,
+			   void *buf, unsigned long size, enum object_type type,
 			   struct object_id *real_oidp);
 
 int finalize_object_file(const char *tmpfile, const char *filename);
diff --git a/convert.c b/convert.c
index df7186bd813..d88072fe320 100644
--- a/convert.c
+++ b/convert.c
@@ -1159,7 +1159,7 @@ static int ident_to_worktree(const char *src, size_t len,
 	/* are we "faking" in place editing ? */
 	if (src == buf->buf)
 		to_free = strbuf_detach(buf, NULL);
-	hash_object_file(the_hash_algo, src, len, "blob", &oid);
+	hash_object_file(the_hash_algo, src, len, OBJ_BLOB, &oid);
 
 	strbuf_grow(buf, len + cnt * (the_hash_algo->hexsz + 3));
 	for (;;) {
diff --git a/diffcore-rename.c b/diffcore-rename.c
index bebd4ed6a42..c0422d9e709 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -261,7 +261,7 @@ static unsigned int hash_filespec(struct repository *r,
 		if (diff_populate_filespec(r, filespec, NULL))
 			return 0;
 		hash_object_file(r->hash_algo, filespec->data, filespec->size,
-				 "blob", &filespec->oid);
+				 OBJ_BLOB, &filespec->oid);
 	}
 	return oidhash(&filespec->oid);
 }
diff --git a/dir.c b/dir.c
index d91295f2bcd..5674e8a6256 100644
--- a/dir.c
+++ b/dir.c
@@ -1113,7 +1113,7 @@ static int add_patterns(const char *fname, const char *base, int baselen,
 				       &istate->cache[pos]->oid);
 			else
 				hash_object_file(the_hash_algo, buf, size,
-						 "blob", &oid_stat->oid);
+						 OBJ_BLOB, &oid_stat->oid);
 			fill_stat_data(&oid_stat->stat, &st);
 			oid_stat->valid = 1;
 		}
diff --git a/log-tree.c b/log-tree.c
index d3e7a40b648..27a5b0bd61a 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -561,7 +561,7 @@ static int show_one_mergetag(struct commit *commit,
 	struct strbuf signature = STRBUF_INIT;
 
 	hash_object_file(the_hash_algo, extra->value, extra->len,
-			 type_name(OBJ_TAG), &oid);
+			 OBJ_TAG, &oid);
 	tag = lookup_tag(the_repository, &oid);
 	if (!tag)
 		return -1; /* error message already given */
diff --git a/object-file.c b/object-file.c
index 9fc959fa05d..4a23a7aa79f 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1073,7 +1073,7 @@ int format_object_header(char *str, size_t size, enum object_type type,
  * the streaming interface and rehash it to do the same.
  */
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *map, unsigned long size, const char *type,
+			   void *map, unsigned long size, enum object_type type,
 			   struct object_id *real_oidp)
 {
 	struct object_id tmp;
@@ -1679,7 +1679,7 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
 {
 	struct cached_object *co;
 
-	hash_object_file(the_hash_algo, buf, len, type_name(type), oid);
+	hash_object_file(the_hash_algo, buf, len, type, oid);
 	if (has_object_file_with_flags(oid, OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT) ||
 	    find_cached_object(oid))
 		return 0;
@@ -1854,19 +1854,23 @@ static int write_buffer(int fd, const void *buf, size_t len)
 }
 
 void hash_object_file(const struct git_hash_algo *algo, const void *buf,
-		     unsigned long len, const char *type,
+		     unsigned long len, enum object_type type,
 		     struct object_id *oid)
 {
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen = sizeof(hdr);
-	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
+
+	write_object_file_prepare(algo, buf, len, type_name(type), oid, hdr, &hdrlen);
 }
 
 static void hash_object_file_literally(const struct git_hash_algo *algo, const void *buf,
 				       unsigned long len, const char *type,
 				       struct object_id *oid)
 {
-	hash_object_file(algo, buf, len, type, oid);
+	char hdr[MAX_HEADER_LEN];
+	int hdrlen = sizeof(hdr);
+
+	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
 }
 
 int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
@@ -1877,7 +1881,7 @@ int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
 	struct object_id tmp;
 	struct object_id *real_oid = real_oidp ? real_oidp : &tmp;
 
-	hash_object_file(algo, buf, len, type_name(type), real_oid);
+	hash_object_file(algo, buf, len, type, real_oid);
 
 	return oideq(oid, real_oid);
 }
@@ -2184,9 +2188,7 @@ static int index_mem(struct index_state *istate,
 	if (write_object)
 		ret = write_object_file(buf, size, type, oid);
 	else
-		hash_object_file(the_hash_algo, buf, size, type_name(type),
-				 oid);
-
+		hash_object_file(the_hash_algo, buf, size, type, oid);
 	if (re_allocated)
 		free(buf);
 	return ret;
@@ -2212,8 +2214,8 @@ static int index_stream_convert_blob(struct index_state *istate,
 		ret = write_object_file(sbuf.buf, sbuf.len, OBJ_BLOB,
 					oid);
 	else
-		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
-				 type_name(OBJ_BLOB), oid);
+		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len, OBJ_BLOB,
+				 oid);
 	strbuf_release(&sbuf);
 	return ret;
 }
@@ -2332,7 +2334,7 @@ int index_path(struct index_state *istate, struct object_id *oid,
 			return error_errno("readlink(\"%s\")", path);
 		if (!(flags & HASH_WRITE_OBJECT))
 			hash_object_file(the_hash_algo, sb.buf, sb.len,
-					 blob_type, oid);
+					 OBJ_BLOB, oid);
 		else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid))
 			rc = error(_("%s: failed to insert into database"), path);
 		strbuf_release(&sb);
diff --git a/object-store.h b/object-store.h
index 2ddc20b3304..719122f047f 100644
--- a/object-store.h
+++ b/object-store.h
@@ -245,8 +245,9 @@ static inline void *repo_read_object_file(struct repository *r,
 /* Read and unpack an object file into memory, write memory to an object file */
 int oid_object_info(struct repository *r, const struct object_id *, unsigned long *);
 
+
 void hash_object_file(const struct git_hash_algo *algo, const void *buf,
-		      unsigned long len, const char *type,
+		      unsigned long len, enum object_type type,
 		      struct object_id *oid);
 
 /**
diff --git a/object.c b/object.c
index d7673332582..795b1356a1b 100644
--- a/object.c
+++ b/object.c
@@ -279,7 +279,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
 	if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
 	    (!obj && repo_has_object_file(r, oid) &&
 	     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
-		if (check_object_signature(r, repl, NULL, 0, NULL, NULL) < 0) {
+		if (check_object_signature(r, repl, NULL, 0, OBJ_BAD, NULL) < 0) {
 			error(_("hash mismatch %s"), oid_to_hex(oid));
 			return NULL;
 		}
diff --git a/pack-check.c b/pack-check.c
index 3f418e3a6af..faceae610d3 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -143,7 +143,7 @@ static int verify_packfile(struct repository *r,
 				    oid_to_hex(&oid), p->pack_name,
 				    (uintmax_t)entries[i].offset);
 		else if (check_object_signature(r, &oid, data, size,
-						type_name(type), NULL))
+						type, NULL))
 			err = error("packed %s from %s is corrupt",
 				    oid_to_hex(&oid), p->pack_name);
 		else if (fn) {
-- 
2.35.0.913.g12b4baa2536


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 08/10] object-file API: replace check_object_signature() with stream_*
  2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                   ` (6 preceding siblings ...)
  2022-02-01 14:53 ` [PATCH 07/10] object-file API: have hash_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
@ 2022-02-01 14:53 ` Ævar Arnfjörð Bjarmason
  2022-02-01 14:53 ` [PATCH 09/10] object-file.c: add a literal version of write_object_file_prepare() Ævar Arnfjörð Bjarmason
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 14:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the task of the the check_object_signature() function so that
it no longer confusingly does two unrelated things.

Now the "!map" branch of it is exposed as a renamed
stream_object_signature(). In preceding commits we migrated all of the
"if (map)" callers over to "hash_object_file_oideq()" or
"hash_object_file_literally()" followed by "!oideq(...)".

This makes the caller in parse_object() less confusing, as we'll now
no longer need to pass NULL for "map" and "OBJ_BAD" for the unused
"type" argument. The "verify_packfile()" caller is arguably a bit
worse off than before, but as we're only using this function in a
couple of places now a bit more verbosity there is acceptable.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 cache.h       | 11 ++++++++---
 object-file.c | 17 +++--------------
 object.c      |  2 +-
 pack-check.c  |  8 ++++++--
 4 files changed, 18 insertions(+), 20 deletions(-)

diff --git a/cache.h b/cache.h
index d9c68c66d53..881ae36fd47 100644
--- a/cache.h
+++ b/cache.h
@@ -1319,9 +1319,14 @@ enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
 struct object_info;
 int parse_loose_header(const char *hdr, struct object_info *oi);
 
-int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *buf, unsigned long size, enum object_type type,
-			   struct object_id *real_oidp);
+
+/**
+ * stream_object_signature() tries to read the object named with "oid"
+ * using the streaming interface and rehash it to make sure the object
+ * name actually matches "oid" to detect object corruption.
+ */
+int stream_object_signature(struct repository *r, const struct object_id *oid,
+			    struct object_id *real_oidp);
 
 int finalize_object_file(const char *tmpfile, const char *filename);
 
diff --git a/object-file.c b/object-file.c
index 4a23a7aa79f..27f587d1dcd 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1066,29 +1066,18 @@ int format_object_header(char *str, size_t size, enum object_type type,
 	return format_object_header_literally(str, size, name, objsize);
 }
 
-/*
- * With an in-core object data in "map", rehash it to make sure the
- * object name actually matches "oid" to detect object corruption.
- * With "map" == NULL, try reading the object named with "oid" using
- * the streaming interface and rehash it to do the same.
- */
-int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *map, unsigned long size, enum object_type type,
-			   struct object_id *real_oidp)
+int stream_object_signature(struct repository *r, const struct object_id *oid,
+			    struct object_id *real_oidp)
 {
 	struct object_id tmp;
 	struct object_id *real_oid = real_oidp ? real_oidp : &tmp;
+	unsigned long size;
 	enum object_type obj_type;
 	struct git_istream *st;
 	git_hash_ctx c;
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen;
 
-	if (map) {
-		hash_object_file(r->hash_algo, map, size, type, real_oid);
-		return !oideq(oid, real_oid) ? -1 : 0;
-	}
-
 	st = open_istream(r, oid, &obj_type, &size, NULL);
 	if (!st)
 		return -1;
diff --git a/object.c b/object.c
index 795b1356a1b..bf51b2056e9 100644
--- a/object.c
+++ b/object.c
@@ -279,7 +279,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
 	if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
 	    (!obj && repo_has_object_file(r, oid) &&
 	     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
-		if (check_object_signature(r, repl, NULL, 0, OBJ_BAD, NULL) < 0) {
+		if (stream_object_signature(r, repl, NULL) < 0) {
 			error(_("hash mismatch %s"), oid_to_hex(oid));
 			return NULL;
 		}
diff --git a/pack-check.c b/pack-check.c
index faceae610d3..5d5169507ec 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -142,8 +142,12 @@ static int verify_packfile(struct repository *r,
 			err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
 				    oid_to_hex(&oid), p->pack_name,
 				    (uintmax_t)entries[i].offset);
-		else if (check_object_signature(r, &oid, data, size,
-						type, NULL))
+		else if (data && !hash_object_file_oideq(r->hash_algo, data,
+							 size, type, &oid,
+							 NULL))
+			err = error("packed %s from %s is corrupt",
+				    oid_to_hex(&oid), p->pack_name);
+		else if (!data && stream_object_signature(r, &oid, NULL))
 			err = error("packed %s from %s is corrupt",
 				    oid_to_hex(&oid), p->pack_name);
 		else if (fn) {
-- 
2.35.0.913.g12b4baa2536


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 09/10] object-file.c: add a literal version of write_object_file_prepare()
  2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                   ` (7 preceding siblings ...)
  2022-02-01 14:53 ` [PATCH 08/10] object-file API: replace check_object_signature() with stream_* Ævar Arnfjörð Bjarmason
@ 2022-02-01 14:53 ` Ævar Arnfjörð Bjarmason
  2022-02-01 14:53 ` [PATCH 10/10] object-file API: pass an enum to read_object_with_reference() Ævar Arnfjörð Bjarmason
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
  10 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 14:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Split off a *_literally() variant of the write_object_file_prepare()
function. To do this create a new "hash_object_body()" static helper.

We now defer the type_name() call until the very last moment in
format_object_header() for those callers that aren't "hash-object
--literally".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 object-file.c | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/object-file.c b/object-file.c
index 27f587d1dcd..0a6d56db39f 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1775,21 +1775,40 @@ void *read_object_with_reference(struct repository *r,
 	}
 }
 
+static void hash_object_body(const struct git_hash_algo *algo, git_hash_ctx *c,
+			     const void *buf, unsigned long len,
+			     struct object_id *oid,
+			     char *hdr, int *hdrlen)
+{
+	algo->init_fn(c);
+	algo->update_fn(c, hdr, *hdrlen);
+	algo->update_fn(c, buf, len);
+	algo->final_oid_fn(oid, c);
+}
+
 static void write_object_file_prepare(const struct git_hash_algo *algo,
 				      const void *buf, unsigned long len,
-				      const char *type, struct object_id *oid,
+				      enum object_type type, struct object_id *oid,
 				      char *hdr, int *hdrlen)
 {
 	git_hash_ctx c;
 
 	/* Generate the header */
-	*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
+	*hdrlen = format_object_header(hdr, *hdrlen, type, len);
 
 	/* Sha1.. */
-	algo->init_fn(&c);
-	algo->update_fn(&c, hdr, *hdrlen);
-	algo->update_fn(&c, buf, len);
-	algo->final_oid_fn(oid, &c);
+	hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen);
+}
+
+static void write_object_file_prepare_literally(const struct git_hash_algo *algo,
+				      const void *buf, unsigned long len,
+				      const char *type, struct object_id *oid,
+				      char *hdr, int *hdrlen)
+{
+	git_hash_ctx c;
+
+	*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
+	hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen);
 }
 
 /*
@@ -1849,7 +1868,7 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf,
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen = sizeof(hdr);
 
-	write_object_file_prepare(algo, buf, len, type_name(type), oid, hdr, &hdrlen);
+	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
 }
 
 static void hash_object_file_literally(const struct git_hash_algo *algo, const void *buf,
@@ -1859,7 +1878,7 @@ static void hash_object_file_literally(const struct git_hash_algo *algo, const v
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen = sizeof(hdr);
 
-	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
+	write_object_file_prepare_literally(algo, buf, len, type, oid, hdr, &hdrlen);
 }
 
 int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
@@ -2036,7 +2055,7 @@ int write_object_file_flags(const void *buf, unsigned long len,
 	/* Normally if we have it in the pack then we do not bother writing
 	 * it out into .git/objects/??/?{38} file.
 	 */
-	write_object_file_prepare(the_hash_algo, buf, len, type_name(type), oid, hdr,
+	write_object_file_prepare(the_hash_algo, buf, len, type, oid, hdr,
 				  &hdrlen);
 	if (freshen_packed_object(oid) || freshen_loose_object(oid))
 		return 0;
@@ -2053,8 +2072,8 @@ int hash_write_object_file_literally(const void *buf, unsigned long len,
 	/* type string, SP, %lu of the length plus NUL must fit this */
 	hdrlen = strlen(type) + MAX_HEADER_LEN;
 	header = xmalloc(hdrlen);
-	write_object_file_prepare(the_hash_algo, buf, len, type, oid, header,
-				  &hdrlen);
+	write_object_file_prepare_literally(the_hash_algo, buf, len, type,
+					    oid, header, &hdrlen);
 
 	if (!(flags & HASH_WRITE_OBJECT))
 		goto cleanup;
-- 
2.35.0.913.g12b4baa2536


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 10/10] object-file API: pass an enum to read_object_with_reference()
  2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                   ` (8 preceding siblings ...)
  2022-02-01 14:53 ` [PATCH 09/10] object-file.c: add a literal version of write_object_file_prepare() Ævar Arnfjörð Bjarmason
@ 2022-02-01 14:53 ` Ævar Arnfjörð Bjarmason
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
  10 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 14:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the read_object_with_reference() function to take an "enum
object_type". It was not prepared to handle an arbitrary "const
char *type", as it was itself calling type_from_string().

Let's change the only caller that passes in user data to use
type_from_string(), and convert the rest to use e.g. "OBJ_TREE"
instead of "tree_type".

The "cat-file" caller is not on the codepath that
handles"--allow-unknown", so the type_from_string() there is safe. Its
use of type_from_string() doesn't functionally differ from that of the
pre-image.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/cat-file.c     | 11 +++++++----
 builtin/fast-import.c  |  6 +++---
 builtin/grep.c         |  4 ++--
 builtin/pack-objects.c |  2 +-
 cache.h                |  2 +-
 object-file.c          |  5 ++---
 tree-walk.c            |  6 +++---
 7 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index d94050e6c18..3c5bc505e0a 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -154,7 +154,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 		break;
 
 	case 0:
-		if (type_from_string(exp_type) == OBJ_BLOB) {
+	{
+		enum object_type exp_type_id = type_from_string(exp_type);
+
+		if (exp_type_id == OBJ_BLOB) {
 			struct object_id blob_oid;
 			if (oid_object_info(the_repository, &oid, NULL) == OBJ_TAG) {
 				char *buffer = read_object_file(&oid, &type,
@@ -176,10 +179,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 			 * fall-back to the usual case.
 			 */
 		}
-		buf = read_object_with_reference(the_repository,
-						 &oid, exp_type, &size, NULL);
+		buf = read_object_with_reference(the_repository, &oid,
+						 exp_type_id, &size, NULL);
 		break;
-
+	}
 	default:
 		die("git cat-file: unknown option: %s", exp_type);
 	}
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 123df7d9a53..c52e807f56e 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -2483,7 +2483,7 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa
 		unsigned long size;
 		char *buf = read_object_with_reference(the_repository,
 						       &commit_oid,
-						       commit_type, &size,
+						       OBJ_COMMIT, &size,
 						       &commit_oid);
 		if (!buf || size < the_hash_algo->hexsz + 6)
 			die("Not a valid commit: %s", p);
@@ -2555,7 +2555,7 @@ static void parse_from_existing(struct branch *b)
 		char *buf;
 
 		buf = read_object_with_reference(the_repository,
-						 &b->oid, commit_type, &size,
+						 &b->oid, OBJ_COMMIT, &size,
 						 &b->oid);
 		parse_from_commit(b, buf, size);
 		free(buf);
@@ -2651,7 +2651,7 @@ static struct hash_list *parse_merge(unsigned int *count)
 			unsigned long size;
 			char *buf = read_object_with_reference(the_repository,
 							       &n->oid,
-							       commit_type,
+							       OBJ_COMMIT,
 							       &size, &n->oid);
 			if (!buf || size < the_hash_algo->hexsz + 6)
 				die("Not a valid commit: %s", from);
diff --git a/builtin/grep.c b/builtin/grep.c
index 9e34a820ad4..75e07b5623a 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -482,7 +482,7 @@ static int grep_submodule(struct grep_opt *opt,
 		object_type = oid_object_info(subrepo, oid, NULL);
 		obj_read_unlock();
 		data = read_object_with_reference(subrepo,
-						  oid, tree_type,
+						  oid, OBJ_TREE,
 						  &size, NULL);
 		if (!data)
 			die(_("unable to read tree (%s)"), oid_to_hex(oid));
@@ -651,7 +651,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
 		int hit, len;
 
 		data = read_object_with_reference(opt->repo,
-						  &obj->oid, tree_type,
+						  &obj->oid, OBJ_TREE,
 						  &size, NULL);
 		if (!data)
 			die(_("unable to read tree (%s)"), oid_to_hex(&obj->oid));
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index ba2006f2212..c4df3df3141 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1802,7 +1802,7 @@ static void add_preferred_base(struct object_id *oid)
 		return;
 
 	data = read_object_with_reference(the_repository, oid,
-					  tree_type, &size, &tree_oid);
+					  OBJ_TREE, &size, &tree_oid);
 	if (!data)
 		return;
 
diff --git a/cache.h b/cache.h
index 881ae36fd47..92da61ef47a 100644
--- a/cache.h
+++ b/cache.h
@@ -1552,7 +1552,7 @@ int cache_name_stage_compare(const char *name1, int len1, int stage1, const char
 
 void *read_object_with_reference(struct repository *r,
 				 const struct object_id *oid,
-				 const char *required_type,
+				 enum object_type required_type,
 				 unsigned long *size,
 				 struct object_id *oid_ret);
 
diff --git a/object-file.c b/object-file.c
index 0a6d56db39f..6c6e21ccc92 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1728,16 +1728,15 @@ void *read_object_file_extended(struct repository *r,
 
 void *read_object_with_reference(struct repository *r,
 				 const struct object_id *oid,
-				 const char *required_type_name,
+				 enum object_type required_type,
 				 unsigned long *size,
 				 struct object_id *actual_oid_return)
 {
-	enum object_type type, required_type;
+	enum object_type type;
 	void *buffer;
 	unsigned long isize;
 	struct object_id actual_oid;
 
-	required_type = type_from_string(required_type_name);
 	oidcpy(&actual_oid, oid);
 	while (1) {
 		int ref_length = -1;
diff --git a/tree-walk.c b/tree-walk.c
index 3a94959d64a..506234b4b81 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -89,7 +89,7 @@ void *fill_tree_descriptor(struct repository *r,
 	void *buf = NULL;
 
 	if (oid) {
-		buf = read_object_with_reference(r, oid, tree_type, &size, NULL);
+		buf = read_object_with_reference(r, oid, OBJ_TREE, &size, NULL);
 		if (!buf)
 			die("unable to read tree %s", oid_to_hex(oid));
 	}
@@ -605,7 +605,7 @@ int get_tree_entry(struct repository *r,
 	unsigned long size;
 	struct object_id root;
 
-	tree = read_object_with_reference(r, tree_oid, tree_type, &size, &root);
+	tree = read_object_with_reference(r, tree_oid, OBJ_TREE, &size, &root);
 	if (!tree)
 		return -1;
 
@@ -677,7 +677,7 @@ enum get_oid_result get_tree_entry_follow_symlinks(struct repository *r,
 			unsigned long size;
 			tree = read_object_with_reference(r,
 							  &current_tree_oid,
-							  tree_type, &size,
+							  OBJ_TREE, &size,
 							  &root);
 			if (!tree)
 				goto done;
-- 
2.35.0.913.g12b4baa2536


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH 04/10] object-file API: have write_object_file() take "enum object_type"
  2022-02-01 14:53 ` [PATCH 04/10] object-file API: have write_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
@ 2022-02-01 18:58   ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2022-02-01 18:58 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Han Xin, Jiang Xin, René Scharfe, Derrick Stolee

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change the write_object_file() function to take an "enum object_type"
> instead of a "const char *type". Its callers either passed
> {commit,tree,blob,tag}_type and can pass the corresponding OBJ_* type
> instead, or were hardcoding strings like "blob".
>
> This avoids the back & forth fragility where the callers of
> write_object_file() would have the enum type, and convert it
> themselves via type_name(). We do have to now do that conversion
> ourselves before calling write_object_file_prepare(), but those
> codepaths will be similarly adjusted in subsequent commits.

Up to this point, the series makes sense to me (I didn't check for
calls that were left uncoverted by mistake, or new callers that were
added on other topics---the compiler should flag them all).



^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 05/10] object-file API: provide a hash_object_file_oideq()
  2022-02-01 14:53 ` [PATCH 05/10] object-file API: provide a hash_object_file_oideq() Ævar Arnfjörð Bjarmason
@ 2022-02-01 19:08   ` Junio C Hamano
  2022-02-01 20:56     ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 46+ messages in thread
From: Junio C Hamano @ 2022-02-01 19:08 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Han Xin, Jiang Xin, René Scharfe, Derrick Stolee

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Provide a new hash_object_file_oideq() for those callers of
> check_object_signature() that don't care about its streaming
> interface. I.e. at the start of that function we do:
>
> 	if (map) {
> 		hash_object_file(r->hash_algo, map, size, type, real_oid);
> 		return !oideq(oid, real_oid) ? -1 : 0;
> 	}
>
> These callers always provide a "map" (or "buf[fer]"). Let's have them
> call this simpler hash_object_file_oideq() function instead.
>
> None of them use a non-NULL "real_oid" argument, but let's provide it
> like check_object_signature() did. This'll make it easy to have these
> emit better error messages in the future as was done in
> 96e41f58fe1 (fsck: report invalid object type-path combinations,
> 2021-10-01), i.e. the die() calls here can emit not only the OID we
> expected, but also what we got.

This has a potential to moving us in the wrong direction when made
to code paths that currently fully slurp an object in-core but may
want to shrink the memory footprint by using streaming API more.

Having said that, I think all of these want to also use the in-core
version of hte object data (mostly to write them out), and they need
more work to move them in the other direction, so I'd say it is OK
to introduce the new helper to simplify these callsites.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 06/10] object-file API: replace some use of check_object_signature()
  2022-02-01 14:53 ` [PATCH 06/10] object-file API: replace some use of check_object_signature() Ævar Arnfjörð Bjarmason
@ 2022-02-01 19:16   ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2022-02-01 19:16 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Han Xin, Jiang Xin, René Scharfe, Derrick Stolee

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Add a "hash_object_file_literally()" function to go with the existing
> "hash_object_file()" function. This is currently a wrapper for its
> sibling, but this change will allow us to change it to take an "enum
> object_type" in a subsequent commit.

This is a confusing renaming, because there is already a public
function that exists under that name.  And with this implementation,
...

> +static void hash_object_file_literally(const struct git_hash_algo *algo, const void *buf,
> +				       unsigned long len, const char *type,
> +				       struct object_id *oid)
> +{
> +	hash_object_file(algo, buf, len, type, oid);
> +}

... it is dubious why we need it.

> -int hash_object_file_literally(const void *buf, unsigned long len,
> -			       const char *type, struct object_id *oid,
> -			       unsigned flags)
> +int hash_write_object_file_literally(const void *buf, unsigned long len,
> +				     const char *type, struct object_id *oid,
> +				     unsigned flags)

This renaming is actually OK, if hash_object_file() which is also
public is renamed to hash_write_object_file() at the same time.

But I would say we should try to avoid such name churn to the public
namespace.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 05/10] object-file API: provide a hash_object_file_oideq()
  2022-02-01 19:08   ` Junio C Hamano
@ 2022-02-01 20:56     ` Ævar Arnfjörð Bjarmason
  0 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-01 20:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Han Xin, Jiang Xin, René Scharfe, Derrick Stolee


On Tue, Feb 01 2022, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:
>
>> Provide a new hash_object_file_oideq() for those callers of
>> check_object_signature() that don't care about its streaming
>> interface. I.e. at the start of that function we do:
>>
>> 	if (map) {
>> 		hash_object_file(r->hash_algo, map, size, type, real_oid);
>> 		return !oideq(oid, real_oid) ? -1 : 0;
>> 	}
>>
>> These callers always provide a "map" (or "buf[fer]"). Let's have them
>> call this simpler hash_object_file_oideq() function instead.
>>
>> None of them use a non-NULL "real_oid" argument, but let's provide it
>> like check_object_signature() did. This'll make it easy to have these
>> emit better error messages in the future as was done in
>> 96e41f58fe1 (fsck: report invalid object type-path combinations,
>> 2021-10-01), i.e. the die() calls here can emit not only the OID we
>> expected, but also what we got.
>
> This has a potential to moving us in the wrong direction when made
> to code paths that currently fully slurp an object in-core but may
> want to shrink the memory footprint by using streaming API more.
>
> Having said that, I think all of these want to also use the in-core
> version of hte object data (mostly to write them out), and they need
> more work to move them in the other direction, so I'd say it is OK
> to introduce the new helper to simplify these callsites.

Yes, I'm avoiding any value-judgement on whether the callers that use
these APIs should or shouldn't be using something else.

But I think as the end-state shows splitting apart the two very
different API users that do and don't provide the "map" parameter makes
sense. We're effectively calling two different functions in all but name
before this change.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface
  2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                   ` (9 preceding siblings ...)
  2022-02-01 14:53 ` [PATCH 10/10] object-file API: pass an enum to read_object_with_reference() Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51 ` Ævar Arnfjörð Bjarmason
  2022-02-04 13:51   ` [PATCH v2 01/11] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
                     ` (11 more replies)
  10 siblings, 12 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

This is a topic to prepare APIs for Han Xin's streaming "git
unpack-objects" topic, which I'll be re-rolling on top of this with
his approval[1].

Since v1 of this topic[2] I've thoroughly addressed the feedback Junio
had on it. I was introducing some new object-name.c APIs for reasons
that turned out to be that I was making things too complex, by doing
the "enum" step in-between several incremental updates to
check_object_signature() and its callers.

That's now a much simpler 05-07/11, with the changing of the API users
being one atomic change.

I also made some other amendmends to reduce the diff size, e.g. not
moving the check_object_signature() prototype from cache.h to
object-store.h (a sensible change, but can be done in some other
cleanup).

1. https://lore.kernel.org/git/CAO0brD2Pe0aKSiBphZS861gC=nZk+q2GtXDN4pPjAQnPdns3TA@mail.gmail.com/
2. https://lore.kernel.org/git/cover-00.10-00000000000-20220201T144803Z-avarab@gmail.com/

Ævar Arnfjörð Bjarmason (11):
  object-file.c: split up declaration of unrelated variables
  object-file API: return "void", not "int" from hash_object_file()
  object-file API: add a format_object_header() function
  object-file API: have write_object_file() take "enum object_type"
  object API: correct "buf" v.s. "map" mismatch in *.c and *.h
  object API: make check_object_signature() oideq()-like, move docs
  object-file API: split up and simplify check_object_signature()
  object API: rename hash_object_file_literally() to write_*()
  object-file API: have hash_object_file() take "enum object_type"
  object-file.c: add a literal version of write_object_file_prepare()
  object-file API: pass an enum to read_object_with_reference()

 apply.c                  |  12 ++--
 builtin/cat-file.c       |  11 +--
 builtin/checkout.c       |   2 +-
 builtin/fast-export.c    |   4 +-
 builtin/fast-import.c    |  12 ++--
 builtin/grep.c           |   4 +-
 builtin/hash-object.c    |   2 +-
 builtin/index-pack.c     |  10 ++-
 builtin/mktag.c          |   7 +-
 builtin/mktree.c         |   2 +-
 builtin/notes.c          |   3 +-
 builtin/pack-objects.c   |   2 +-
 builtin/receive-pack.c   |   2 +-
 builtin/replace.c        |   4 +-
 builtin/tag.c            |   2 +-
 builtin/unpack-objects.c |   8 +--
 bulk-checkin.c           |   4 +-
 cache-tree.c             |   8 +--
 cache.h                  |  20 +++++-
 commit.c                 |   2 +-
 convert.c                |   2 +-
 diffcore-rename.c        |   2 +-
 dir.c                    |   2 +-
 http-push.c              |   2 +-
 log-tree.c               |   2 +-
 match-trees.c            |   2 +-
 merge-ort.c              |   4 +-
 merge-recursive.c        |   2 +-
 notes-cache.c            |   2 +-
 notes.c                  |   8 +--
 object-file.c            | 146 +++++++++++++++++++++++++--------------
 object-store.h           |  24 ++++---
 object.c                 |   5 +-
 pack-check.c             |   9 ++-
 read-cache.c             |   2 +-
 tree-walk.c              |   6 +-
 36 files changed, 203 insertions(+), 138 deletions(-)

Range-diff against v1:
 1:  53334bc970a =  1:  53334bc970a object-file.c: split up declaration of unrelated variables
 2:  ab1d204f49b =  2:  5ba49778ac1 object-file API: return "void", not "int" from hash_object_file()
 3:  64484e046ea =  3:  92fd020d199 object-file API: add a format_object_header() function
 4:  d6231ac68fe =  4:  d259f901114 object-file API: have write_object_file() take "enum object_type"
 -:  ----------- >  5:  207aec4eb64 object API: correct "buf" v.s. "map" mismatch in *.c and *.h
 5:  719fcfbe13c !  6:  636a647ac51 object-file API: provide a hash_object_file_oideq()
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    object-file API: provide a hash_object_file_oideq()
    +    object API: make check_object_signature() oideq()-like, move docs
     
    -    Provide a new hash_object_file_oideq() for those callers of
    -    check_object_signature() that don't care about its streaming
    -    interface. I.e. at the start of that function we do:
    +    Make the return value of check_object_signature() behave like oideq()
    +    and memcmp() instead of returning negative values on failure.
     
    -            if (map) {
    -                    hash_object_file(r->hash_algo, map, size, type, real_oid);
    -                    return !oideq(oid, real_oid) ? -1 : 0;
    -            }
    +    This reduces the boilerplate required when calling the function, and
    +    makes the calling code behave the same is if though we'd called
    +    oideq(), which is basically what we're doing here. We already had some
    +    callers using "f() < 0", with others using "!f()". Instead of
    +    declaring the latter a bug let's convert all callers to it.
     
    -    These callers always provide a "map" (or "buf[fer]"). Let's have them
    -    call this simpler hash_object_file_oideq() function instead.
    +    It is unfortunate that there's also cases where we "return -1" on
    +    various errors, and we can't tell those apart from the expected OID
    +    being less than the real OID, but this was the case already.
     
    -    None of them use a non-NULL "real_oid" argument, but let's provide it
    -    like check_object_signature() did. This'll make it easy to have these
    -    emit better error messages in the future as was done in
    -    96e41f58fe1 (fsck: report invalid object type-path combinations,
    -    2021-10-01), i.e. the die() calls here can emit not only the OID we
    -    expected, but also what we got.
    +    This change is rather dangerous stand-alone as we're changing the
    +    return semantics, but not changing the prototype. Therefore any
    +    out-of-tree code rebased on this change would start doing the opposite
    +    of what it was meant to do. In a subsequent commit we'll make that a
    +    non-issue by changing the signature of the function, ensuring that the
    +    compiler will catch any such misuse.
    +
    +    While we're at it let's re-flow some of the callers to wrap at 79
    +    characters, and move the API documentation to cache.h, where the
    +    prototype of this function lives.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ builtin/fast-export.c: static void export_blob(const struct object_id *oid)
      			die("could not read blob %s", oid_to_hex(oid));
     -		if (check_object_signature(the_repository, oid, buf, size,
     -					   type_name(type), NULL) < 0)
    -+		if (!hash_object_file_oideq(the_repository->hash_algo, buf,
    -+					    size, type, oid, NULL))
    ++		if (!check_object_signature(the_repository, oid, buf, size,
    ++					    type_name(type), NULL))
      			die("oid mismatch in blob %s", oid_to_hex(oid));
      		object = parse_object_buffer(the_repository, oid, type,
      					     size, buf, &eaten);
    @@ builtin/index-pack.c: static void fix_unresolved_deltas(struct hashfile *f)
     -		if (check_object_signature(the_repository, &d->oid,
     -					   data, size,
     -					   type_name(type), NULL))
    -+		if (!hash_object_file_oideq(the_repository->hash_algo, data,
    -+					    size, type, &d->oid, NULL))
    ++		if (!check_object_signature(the_repository, &d->oid, data,
    ++					    size, type_name(type), NULL))
      			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
      
      		/*
    @@ builtin/mktag.c: static int verify_object_in_tag(struct object_id *tagged_oid, i
     -	ret = check_object_signature(the_repository, repl,
     -				     buffer, size, type_name(*tagged_type),
     -				     NULL);
    -+	ret = !hash_object_file_oideq(the_repository->hash_algo, buffer, size,
    -+				      *tagged_type, repl, NULL);
    ++	ret = !check_object_signature(the_repository, repl, buffer, size,
    ++				      type_name(*tagged_type), NULL);
      	free(buffer);
      
      	return ret;
     
    + ## cache.h ##
    +@@ cache.h: enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
    + struct object_info;
    + int parse_loose_header(const char *hdr, struct object_info *oi);
    + 
    ++/**
    ++ * With in-core object data in "buf", rehash it to make sure the
    ++ * object name actually matches "oid" to detect object corruption.
    ++ * With "buf" == NULL, try reading the object named with "oid" using
    ++ * the streaming interface and rehash it to do the same.
    ++ *
    ++ * Treat the return value like oideq() (which is like memcmp()),
    ++ * except that negative values might also indicate a generic error.
    ++ */
    + int check_object_signature(struct repository *r, const struct object_id *oid,
    + 			   void *buf, unsigned long size, const char *type,
    + 			   struct object_id *real_oidp);
    +
      ## object-file.c ##
    -@@ object-file.c: void hash_object_file(const struct git_hash_algo *algo, const void *buf,
    - 	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
    +@@ object-file.c: int format_object_header(char *str, size_t size, enum object_type type,
    + 	return format_object_header_literally(str, size, name, objsize);
      }
      
    -+int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
    -+			   unsigned long len, enum object_type type,
    -+			   const struct object_id *oid,
    -+			   struct object_id *real_oidp)
    -+{
    -+	struct object_id tmp;
    -+	struct object_id *real_oid = real_oidp ? real_oidp : &tmp;
    -+
    -+	hash_object_file(algo, buf, len, type_name(type), real_oid);
    -+
    +-/*
    +- * With in-core object data in "buf", rehash it to make sure the
    +- * object name actually matches "oid" to detect object corruption.
    +- * With "buf" == NULL, try reading the object named with "oid" using
    +- * the streaming interface and rehash it to do the same.
    +- */
    + int check_object_signature(struct repository *r, const struct object_id *oid,
    + 			   void *buf, unsigned long size, const char *type,
    + 			   struct object_id *real_oidp)
    +@@ object-file.c: int check_object_signature(struct repository *r, const struct object_id *oid,
    + 
    + 	if (buf) {
    + 		hash_object_file(r->hash_algo, buf, size, type, real_oid);
    +-		return !oideq(oid, real_oid) ? -1 : 0;
    ++		return oideq(oid, real_oid);
    + 	}
    + 
    + 	st = open_istream(r, oid, &obj_type, &size, NULL);
    +@@ object-file.c: int check_object_signature(struct repository *r, const struct object_id *oid,
    + 	}
    + 	r->hash_algo->final_oid_fn(real_oid, &c);
    + 	close_istream(st);
    +-	return !oideq(oid, real_oid) ? -1 : 0;
     +	return oideq(oid, real_oid);
    -+}
    -+
    - /* Finalize a file on disk, and close it. */
    - static void close_loose_object(int fd)
    - {
    -
    - ## object-store.h ##
    -@@ object-store.h: void hash_object_file(const struct git_hash_algo *algo, const void *buf,
    - 		      unsigned long len, const char *type,
    - 		      struct object_id *oid);
    + }
    + 
    + int git_open_cloexec(const char *name, int flags)
    +@@ object-file.c: int read_loose_object(const char *path,
    + 			git_inflate_end(&stream);
    + 			goto out;
    + 		}
    +-		if (check_object_signature(the_repository, expected_oid,
    +-					   *contents, *size,
    +-					   oi->type_name->buf, real_oid))
    ++		if (!check_object_signature(the_repository, expected_oid,
    ++					    *contents, *size,
    ++					    oi->type_name->buf, real_oid))
    + 			goto out;
    + 	}
      
    -+/**
    -+ * hash_object_file_oideq() is like hash_object_file() except that
    -+ * asserts that "real_oid" is equivalent to an input "oid", and the
    -+ * return value is that of oideq(oid, real_oid).
    -+ *
    -+ * The "real_oid" can be NULL, when non-NULL the caller provides a
    -+ * "struct object_id *" that can be used to print what the real OID
    -+ * was.
    -+ */
    -+int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
    -+			   unsigned long len, enum object_type type,
    -+			   const struct object_id *oid,
    -+			   struct object_id *real_oidp);
    -+
    - int write_object_file_flags(const void *buf, unsigned long len,
    - 			    enum object_type type, struct object_id *oid,
    - 			    unsigned flags);
     
      ## object.c ##
     @@ object.c: struct object *parse_object(struct repository *r, const struct object_id *oid)
    + 	if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
    + 	    (!obj && repo_has_object_file(r, oid) &&
    + 	     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
    +-		if (check_object_signature(r, repl, NULL, 0, NULL, NULL) < 0) {
    ++		if (!check_object_signature(r, repl, NULL, 0, NULL, NULL)) {
    + 			error(_("hash mismatch %s"), oid_to_hex(oid));
    + 			return NULL;
    + 		}
    +@@ object.c: struct object *parse_object(struct repository *r, const struct object_id *oid)
      
      	buffer = repo_read_object_file(r, oid, &type, &size);
      	if (buffer) {
     -		if (check_object_signature(r, repl, buffer, size,
     -					   type_name(type), NULL) < 0) {
    -+		if (!hash_object_file_oideq(r->hash_algo, buffer, size,
    -+					    type, repl, NULL)) {
    ++		if (!check_object_signature(r, repl, buffer, size,
    ++					    type_name(type), NULL)) {
      			free(buffer);
      			error(_("hash mismatch %s"), oid_to_hex(repl));
      			return NULL;
    +
    + ## pack-check.c ##
    +@@ pack-check.c: static int verify_packfile(struct repository *r,
    + 			err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
    + 				    oid_to_hex(&oid), p->pack_name,
    + 				    (uintmax_t)entries[i].offset);
    +-		else if (check_object_signature(r, &oid, data, size,
    +-						type_name(type), NULL))
    ++		else if (!check_object_signature(r, &oid, data, size,
    ++						 type_name(type), NULL))
    + 			err = error("packed %s from %s is corrupt",
    + 				    oid_to_hex(&oid), p->pack_name);
    + 		else if (fn) {
 8:  70c3e84dd0d !  7:  c38af53e889 object-file API: replace check_object_signature() with stream_*
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    object-file API: replace check_object_signature() with stream_*
    +    object-file API: split up and simplify check_object_signature()
     
    -    Change the task of the the check_object_signature() function so that
    -    it no longer confusingly does two unrelated things.
    +    Split up the check_object_signature() function into that non-streaming
    +    version (it accepts an already filled "buf"), and a new
    +    stream_object_signature() which will retrieve the object from storage,
    +    and hash it on-the-fly.
     
    -    Now the "!map" branch of it is exposed as a renamed
    -    stream_object_signature(). In preceding commits we migrated all of the
    -    "if (map)" callers over to "hash_object_file_oideq()" or
    -    "hash_object_file_literally()" followed by "!oideq(...)".
    +    All of the callers of check_object_signature() were effectively
    +    calling two different functions, if we go by cyclomatic
    +    complexity. I.e. they'd either take the early "if (map)" branch and
    +    return early, or not. This has been the case since the "if (map)"
    +    condition was added in 090ea12671b (parse_object: avoid putting whole
    +    blob in core, 2012-03-07).
     
    -    This makes the caller in parse_object() less confusing, as we'll now
    -    no longer need to pass NULL for "map" and "OBJ_BAD" for the unused
    -    "type" argument. The "verify_packfile()" caller is arguably a bit
    -    worse off than before, but as we're only using this function in a
    -    couple of places now a bit more verbosity there is acceptable.
    +    We can then further simplify the resulting check_object_signature()
    +    function since only one caller wanted to pass a non-NULL "buf" and a
    +    non-NULL "real_oidp". That "read_loose_object()" codepath used by "git
    +    fsck" can instead use hash_object_file() followed by oideq().
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    - ## cache.h ##
    -@@ cache.h: enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
    - struct object_info;
    - int parse_loose_header(const char *hdr, struct object_info *oi);
    + ## builtin/fast-export.c ##
    +@@ builtin/fast-export.c: static void export_blob(const struct object_id *oid)
    + 		if (!buf)
    + 			die("could not read blob %s", oid_to_hex(oid));
    + 		if (!check_object_signature(the_repository, oid, buf, size,
    +-					    type_name(type), NULL))
    ++					    type_name(type)))
    + 			die("oid mismatch in blob %s", oid_to_hex(oid));
    + 		object = parse_object_buffer(the_repository, oid, type,
    + 					     size, buf, &eaten);
    +
    + ## builtin/index-pack.c ##
    +@@ builtin/index-pack.c: static void fix_unresolved_deltas(struct hashfile *f)
    + 			continue;
    + 
    + 		if (!check_object_signature(the_repository, &d->oid, data,
    +-					    size, type_name(type), NULL))
    ++					    size, type_name(type)))
    + 			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
    + 
    + 		/*
    +
    + ## builtin/mktag.c ##
    +@@ builtin/mktag.c: static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
    + 
    + 	repl = lookup_replace_object(the_repository, tagged_oid);
    + 	ret = !check_object_signature(the_repository, repl, buffer, size,
    +-				      type_name(*tagged_type), NULL);
    ++				      type_name(*tagged_type));
    + 	free(buffer);
      
    --int check_object_signature(struct repository *r, const struct object_id *oid,
    --			   void *buf, unsigned long size, enum object_type type,
    + 	return ret;
    +
    + ## cache.h ##
    +@@ cache.h: int parse_loose_header(const char *hdr, struct object_info *oi);
    + /**
    +  * With in-core object data in "buf", rehash it to make sure the
    +  * object name actually matches "oid" to detect object corruption.
    +- * With "buf" == NULL, try reading the object named with "oid" using
    +- * the streaming interface and rehash it to do the same.
    +  *
    +  * Treat the return value like oideq() (which is like memcmp()),
    +  * except that negative values might also indicate a generic error.
    +  */
    + int check_object_signature(struct repository *r, const struct object_id *oid,
    +-			   void *buf, unsigned long size, const char *type,
     -			   struct object_id *real_oidp);
    ++			   void *buf, unsigned long size, const char *type);
     +
     +/**
    -+ * stream_object_signature() tries to read the object named with "oid"
    -+ * using the streaming interface and rehash it to make sure the object
    -+ * name actually matches "oid" to detect object corruption.
    ++ * A streaming version of check_object_signature().
    ++ * Try reading the object named with "oid" using
    ++ * the streaming interface and rehash it to do the same.
     + */
    -+int stream_object_signature(struct repository *r, const struct object_id *oid,
    -+			    struct object_id *real_oidp);
    ++int stream_object_signature(struct repository *r, const struct object_id *oid);
      
      int finalize_object_file(const char *tmpfile, const char *filename);
      
     
      ## object-file.c ##
     @@ object-file.c: int format_object_header(char *str, size_t size, enum object_type type,
    - 	return format_object_header_literally(str, size, name, objsize);
      }
      
    --/*
    -- * With an in-core object data in "map", rehash it to make sure the
    -- * object name actually matches "oid" to detect object corruption.
    -- * With "map" == NULL, try reading the object named with "oid" using
    -- * the streaming interface and rehash it to do the same.
    -- */
    --int check_object_signature(struct repository *r, const struct object_id *oid,
    --			   void *map, unsigned long size, enum object_type type,
    + int check_object_signature(struct repository *r, const struct object_id *oid,
    +-			   void *buf, unsigned long size, const char *type,
     -			   struct object_id *real_oidp)
    -+int stream_object_signature(struct repository *r, const struct object_id *oid,
    -+			    struct object_id *real_oidp)
    ++			   void *buf, unsigned long size, const char *type)
      {
    - 	struct object_id tmp;
    - 	struct object_id *real_oid = real_oidp ? real_oidp : &tmp;
    +-	struct object_id tmp;
    +-	struct object_id *real_oid = real_oidp ? real_oidp : &tmp;
    ++	struct object_id real_oid;
    ++
    ++	hash_object_file(r->hash_algo, buf, size, type, &real_oid);
    ++
    ++	return oideq(oid, &real_oid);
    ++}
    ++
    ++int stream_object_signature(struct repository *r, const struct object_id *oid)
    ++{
    ++	struct object_id real_oid;
     +	unsigned long size;
      	enum object_type obj_type;
      	struct git_istream *st;
    @@ object-file.c: int format_object_header(char *str, size_t size, enum object_type
      	char hdr[MAX_HEADER_LEN];
      	int hdrlen;
      
    --	if (map) {
    --		hash_object_file(r->hash_algo, map, size, type, real_oid);
    --		return !oideq(oid, real_oid) ? -1 : 0;
    +-	if (buf) {
    +-		hash_object_file(r->hash_algo, buf, size, type, real_oid);
    +-		return oideq(oid, real_oid);
     -	}
     -
      	st = open_istream(r, oid, &obj_type, &size, NULL);
      	if (!st)
      		return -1;
    +@@ object-file.c: int check_object_signature(struct repository *r, const struct object_id *oid,
    + 			break;
    + 		r->hash_algo->update_fn(&c, buf, readlen);
    + 	}
    +-	r->hash_algo->final_oid_fn(real_oid, &c);
    ++	r->hash_algo->final_oid_fn(&real_oid, &c);
    + 	close_istream(st);
    +-	return oideq(oid, real_oid);
    ++	return oideq(oid, &real_oid);
    + }
    + 
    + int git_open_cloexec(const char *name, int flags)
    +@@ object-file.c: int read_loose_object(const char *path,
    + 			git_inflate_end(&stream);
    + 			goto out;
    + 		}
    +-		if (!check_object_signature(the_repository, expected_oid,
    +-					    *contents, *size,
    +-					    oi->type_name->buf, real_oid))
    ++
    ++		hash_object_file(the_repository->hash_algo,
    ++				 *contents, *size, oi->type_name->buf,
    ++				 real_oid);
    ++		if (!oideq(expected_oid, real_oid))
    + 			goto out;
    + 	}
    + 
     
      ## object.c ##
     @@ object.c: struct object *parse_object(struct repository *r, const struct object_id *oid)
      	if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
      	    (!obj && repo_has_object_file(r, oid) &&
      	     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
    --		if (check_object_signature(r, repl, NULL, 0, OBJ_BAD, NULL) < 0) {
    -+		if (stream_object_signature(r, repl, NULL) < 0) {
    +-		if (!check_object_signature(r, repl, NULL, 0, NULL, NULL)) {
    ++		if (!stream_object_signature(r, repl)) {
      			error(_("hash mismatch %s"), oid_to_hex(oid));
      			return NULL;
      		}
    +@@ object.c: struct object *parse_object(struct repository *r, const struct object_id *oid)
    + 	buffer = repo_read_object_file(r, oid, &type, &size);
    + 	if (buffer) {
    + 		if (!check_object_signature(r, repl, buffer, size,
    +-					    type_name(type), NULL)) {
    ++					    type_name(type))) {
    + 			free(buffer);
    + 			error(_("hash mismatch %s"), oid_to_hex(repl));
    + 			return NULL;
     
      ## pack-check.c ##
     @@ pack-check.c: static int verify_packfile(struct repository *r,
    + 
    + 		if (type == OBJ_BLOB && big_file_threshold <= size) {
    + 			/*
    +-			 * Let check_object_signature() check it with
    ++			 * Let stream_object_signature() check it with
    + 			 * the streaming interface; no point slurping
    + 			 * the data in-core only to discard.
    + 			 */
    +@@ pack-check.c: static int verify_packfile(struct repository *r,
      			err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
      				    oid_to_hex(&oid), p->pack_name,
      				    (uintmax_t)entries[i].offset);
    --		else if (check_object_signature(r, &oid, data, size,
    --						type, NULL))
    -+		else if (data && !hash_object_file_oideq(r->hash_algo, data,
    -+							 size, type, &oid,
    -+							 NULL))
    +-		else if (!check_object_signature(r, &oid, data, size,
    +-						 type_name(type), NULL))
    ++		else if (data && !check_object_signature(r, &oid, data, size,
    ++							 type_name(type)))
     +			err = error("packed %s from %s is corrupt",
     +				    oid_to_hex(&oid), p->pack_name);
    -+		else if (!data && stream_object_signature(r, &oid, NULL))
    ++		else if (!data && !stream_object_signature(r, &oid))
      			err = error("packed %s from %s is corrupt",
      				    oid_to_hex(&oid), p->pack_name);
      		else if (fn) {
 6:  2a065bf23da !  8:  a5ebd04d462 object-file API: replace some use of check_object_signature()
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    object-file API: replace some use of check_object_signature()
    +    object API: rename hash_object_file_literally() to write_*()
     
    -    Add a "hash_object_file_literally()" function to go with the existing
    -    "hash_object_file()" function. This is currently a wrapper for its
    -    sibling, but this change will allow us to change it to take an "enum
    -    object_type" in a subsequent commit.
    +    Before 0c3db67cc81 (hash-object --literally: fix buffer overrun with
    +    extra-long object type, 2015-05-04) the hash-object code being changed
    +    here called write_sha1_file() to both hash and write a loose
    +    object. Before that we'd use hash_sha1_file() to if "-w" wasn't
    +    provided, and otherwise call write_sha1_file().
     
    -    The only caller that wanted to pass a custom type to
    -    "check_object_signature()" was the "git fsck" via its
    -    "read_loose_object()", which is being changed here.
    -
    -    There was an existing hash_object_file_literally() which I'm renaming
    -    to "hash_write_object_file_literally()", that function is only used
    -    for "hash-object --literally". That renaming is being done because it
    -    would be confusing to have a "hash_object_file_literally()" and a
    -    "hash_object_file()" that do very different things.
    +    Now we'll always call the same function for both writing. Let's rename
    +    it from hash_*_literally() to write_*_literally(). Even though the
    +    write_*() might not actually write if HASH_WRITE_OBJECT isn't in
    +    "flags", having it be more similar to write_object_file_flags() than
    +    hash_object_file(), but carrying a name that would suggest that it's a
    +    variant of the latter is confusing.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ builtin/hash-object.c: static int hash_literally(struct object_id *oid, int fd,
      		ret = -1;
      	else
     -		ret = hash_object_file_literally(buf.buf, buf.len, type, oid,
    --						 flags);
    -+		ret = hash_write_object_file_literally(buf.buf, buf.len, type, oid,
    -+						       flags);
    ++		ret = write_object_file_literally(buf.buf, buf.len, type, oid,
    + 						 flags);
      	strbuf_release(&buf);
      	return ret;
    - }
     
      ## object-file.c ##
    -@@ object-file.c: void hash_object_file(const struct git_hash_algo *algo, const void *buf,
    - 	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
    - }
    - 
    -+static void hash_object_file_literally(const struct git_hash_algo *algo, const void *buf,
    -+				       unsigned long len, const char *type,
    -+				       struct object_id *oid)
    -+{
    -+	hash_object_file(algo, buf, len, type, oid);
    -+}
    -+
    - int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
    - 			   unsigned long len, enum object_type type,
    - 			   const struct object_id *oid,
     @@ object-file.c: int write_object_file_flags(const void *buf, unsigned long len,
      	return write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags);
      }
    @@ object-file.c: int write_object_file_flags(const void *buf, unsigned long len,
     -int hash_object_file_literally(const void *buf, unsigned long len,
     -			       const char *type, struct object_id *oid,
     -			       unsigned flags)
    -+int hash_write_object_file_literally(const void *buf, unsigned long len,
    -+				     const char *type, struct object_id *oid,
    -+				     unsigned flags)
    ++int write_object_file_literally(const void *buf, unsigned long len,
    ++				const char *type, struct object_id *oid,
    ++				unsigned flags)
      {
      	char *header;
      	int hdrlen, status = 0;
    -@@ object-file.c: int read_loose_object(const char *path,
    - 			git_inflate_end(&stream);
    - 			goto out;
    - 		}
    --		if (check_object_signature(the_repository, expected_oid,
    -+		hash_object_file_literally(the_repository->hash_algo,
    - 					   *contents, *size,
    --					   oi->type_name->buf, real_oid))
    -+					   oi->type_name->buf, real_oid);
    -+		if (!oideq(expected_oid, real_oid))
    - 			goto out;
    - 	}
    - 
     
      ## object-store.h ##
     @@ object-store.h: static inline int write_object_file(const void *buf, unsigned long len,
    @@ object-store.h: static inline int write_object_file(const void *buf, unsigned lo
     -int hash_object_file_literally(const void *buf, unsigned long len,
     -			       const char *type, struct object_id *oid,
     -			       unsigned flags);
    -+int hash_write_object_file_literally(const void *buf, unsigned long len,
    -+				     const char *type, struct object_id *oid,
    -+				     unsigned flags);
    ++int write_object_file_literally(const void *buf, unsigned long len,
    ++				const char *type, struct object_id *oid,
    ++				unsigned flags);
      
      /*
       * Add an object file to the in-memory object store, without writing it
 7:  ad5d94714cc !  9:  40647be525b object-file API: have hash_object_file() take "enum object_type"
    @@ Commit message
         Change the hash_object_file() function to take an "enum
         object_type".
     
    -    Almost all of its callers were passing either
    -    "{commit,tree,blob,tag}_type", or the result of a call to
    -    type_name(). Let's instead benefit from type checking and use the enum
    -    directly.
    -
    -    "Almost" because one caller here will now pass OBJ_BAD. The previous
    -    "NULL" value was not used, as "check_object_signature()" will never
    -    use its "type" argument when given a NULL "map" argument, which that
    -    caller in "parse_object()" also does. We'll deal with it in a
    -    subsequent commit, but for now it'll pass an "OBJ_BAD" placeholder.
    +    Since a preceding commit all of its callers are passing either
    +    "{commit,tree,blob,tag}_type", or the result of a call to type_name(),
    +    the parse_object() caller that would pass NULL is now using
    +    stream_object_signature().
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ apply.c: static int apply_binary(struct apply_state *state,
      		if (strcmp(oid_to_hex(&oid), patch->new_oid_prefix))
      			return error(_("binary patch to '%s' creates incorrect result (expecting %s, got %s)"),
     
    + ## builtin/fast-export.c ##
    +@@ builtin/fast-export.c: static void export_blob(const struct object_id *oid)
    + 		if (!buf)
    + 			die("could not read blob %s", oid_to_hex(oid));
    + 		if (!check_object_signature(the_repository, oid, buf, size,
    +-					    type_name(type)))
    ++					    type))
    + 			die("oid mismatch in blob %s", oid_to_hex(oid));
    + 		object = parse_object_buffer(the_repository, oid, type,
    + 					     size, buf, &eaten);
    +
      ## builtin/index-pack.c ##
     @@ builtin/index-pack.c: static struct base_data *resolve_delta(struct object_entry *delta_obj,
      	if (!result_data)
    @@ builtin/index-pack.c: static struct base_data *resolve_delta(struct object_entry
      	sha1_object(result_data, NULL, result_size, delta_obj->real_type,
      		    &delta_obj->idx.oid);
      
    +@@ builtin/index-pack.c: static void fix_unresolved_deltas(struct hashfile *f)
    + 			continue;
    + 
    + 		if (!check_object_signature(the_repository, &d->oid, data,
    +-					    size, type_name(type)))
    ++					    size, type))
    + 			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
    + 
    + 		/*
    +
    + ## builtin/mktag.c ##
    +@@ builtin/mktag.c: static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
    + 
    + 	repl = lookup_replace_object(the_repository, tagged_oid);
    + 	ret = !check_object_signature(the_repository, repl, buffer, size,
    +-				      type_name(*tagged_type));
    ++				     *tagged_type);
    + 	free(buffer);
    + 
    + 	return ret;
     
      ## builtin/replace.c ##
     @@ builtin/replace.c: static int check_one_mergetag(struct commit *commit,
    @@ cache-tree.c: static int verify_one(struct repository *r,
      		BUG("cache-tree for path %.*s does not match. "
     
      ## cache.h ##
    -@@ cache.h: struct object_info;
    - int parse_loose_header(const char *hdr, struct object_info *oi);
    - 
    +@@ cache.h: int parse_loose_header(const char *hdr, struct object_info *oi);
    +  * except that negative values might also indicate a generic error.
    +  */
      int check_object_signature(struct repository *r, const struct object_id *oid,
    --			   void *buf, unsigned long size, const char *type,
    -+			   void *buf, unsigned long size, enum object_type type,
    - 			   struct object_id *real_oidp);
    +-			   void *buf, unsigned long size, const char *type);
    ++			   void *map, unsigned long size,
    ++			   enum object_type type);
      
    - int finalize_object_file(const char *tmpfile, const char *filename);
    + /**
    +  * A streaming version of check_object_signature().
     
      ## convert.c ##
     @@ convert.c: static int ident_to_worktree(const char *src, size_t len,
    @@ log-tree.c: static int show_one_mergetag(struct commit *commit,
     
      ## object-file.c ##
     @@ object-file.c: int format_object_header(char *str, size_t size, enum object_type type,
    -  * the streaming interface and rehash it to do the same.
    -  */
    + }
    + 
      int check_object_signature(struct repository *r, const struct object_id *oid,
    --			   void *map, unsigned long size, const char *type,
    -+			   void *map, unsigned long size, enum object_type type,
    - 			   struct object_id *real_oidp)
    +-			   void *buf, unsigned long size, const char *type)
    ++			   void *buf, unsigned long size,
    ++			   enum object_type type)
      {
    - 	struct object_id tmp;
    + 	struct object_id real_oid;
    + 
     @@ object-file.c: int pretend_object_file(void *buf, unsigned long len, enum object_type type,
      {
      	struct cached_object *co;
    @@ object-file.c: int pretend_object_file(void *buf, unsigned long len, enum object
      	    find_cached_object(oid))
      		return 0;
     @@ object-file.c: static int write_buffer(int fd, const void *buf, size_t len)
    + 	return 0;
      }
      
    - void hash_object_file(const struct git_hash_algo *algo, const void *buf,
    +-void hash_object_file(const struct git_hash_algo *algo, const void *buf,
     -		     unsigned long len, const char *type,
    -+		     unsigned long len, enum object_type type,
    - 		     struct object_id *oid)
    +-		     struct object_id *oid)
    ++static void hash_object_file_literally(const struct git_hash_algo *algo,
    ++				       const void *buf, unsigned long len,
    ++				       const char *type, struct object_id *oid)
      {
      	char hdr[MAX_HEADER_LEN];
      	int hdrlen = sizeof(hdr);
    --	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
     +
    -+	write_object_file_prepare(algo, buf, len, type_name(type), oid, hdr, &hdrlen);
    + 	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
      }
      
    - static void hash_object_file_literally(const struct git_hash_algo *algo, const void *buf,
    - 				       unsigned long len, const char *type,
    - 				       struct object_id *oid)
    - {
    --	hash_object_file(algo, buf, len, type, oid);
    -+	char hdr[MAX_HEADER_LEN];
    -+	int hdrlen = sizeof(hdr);
    ++void hash_object_file(const struct git_hash_algo *algo, const void *buf,
    ++		      unsigned long len, enum object_type type,
    ++		      struct object_id *oid)
    ++{
    ++	hash_object_file_literally(algo, buf, len, type_name(type), oid);
    ++}
     +
    -+	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
    - }
    - 
    - int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
    -@@ object-file.c: int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
    - 	struct object_id tmp;
    - 	struct object_id *real_oid = real_oidp ? real_oidp : &tmp;
    - 
    --	hash_object_file(algo, buf, len, type_name(type), real_oid);
    -+	hash_object_file(algo, buf, len, type, real_oid);
    - 
    - 	return oideq(oid, real_oid);
    - }
    + /* Finalize a file on disk, and close it. */
    + static void close_loose_object(int fd)
    + {
     @@ object-file.c: static int index_mem(struct index_state *istate,
      	if (write_object)
      		ret = write_object_file(buf, size, type, oid);
    @@ object-file.c: int index_path(struct index_state *istate, struct object_id *oid,
      		else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid))
      			rc = error(_("%s: failed to insert into database"), path);
      		strbuf_release(&sb);
    +@@ object-file.c: int read_loose_object(const char *path,
    + 			goto out;
    + 		}
    + 
    +-		hash_object_file(the_repository->hash_algo,
    +-				 *contents, *size, oi->type_name->buf,
    +-				 real_oid);
    ++		hash_object_file_literally(the_repository->hash_algo,
    ++					   *contents, *size,
    ++					   oi->type_name->buf, real_oid);
    + 		if (!oideq(expected_oid, real_oid))
    + 			goto out;
    + 	}
     
      ## object-store.h ##
     @@ object-store.h: static inline void *repo_read_object_file(struct repository *r,
    - /* Read and unpack an object file into memory, write memory to an object file */
      int oid_object_info(struct repository *r, const struct object_id *, unsigned long *);
      
    -+
      void hash_object_file(const struct git_hash_algo *algo, const void *buf,
     -		      unsigned long len, const char *type,
     +		      unsigned long len, enum object_type type,
      		      struct object_id *oid);
      
    - /**
    + int write_object_file_flags(const void *buf, unsigned long len,
     
      ## object.c ##
     @@ object.c: struct object *parse_object(struct repository *r, const struct object_id *oid)
    - 	if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
    - 	    (!obj && repo_has_object_file(r, oid) &&
    - 	     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
    --		if (check_object_signature(r, repl, NULL, 0, NULL, NULL) < 0) {
    -+		if (check_object_signature(r, repl, NULL, 0, OBJ_BAD, NULL) < 0) {
    - 			error(_("hash mismatch %s"), oid_to_hex(oid));
    + 
    + 	buffer = repo_read_object_file(r, oid, &type, &size);
    + 	if (buffer) {
    +-		if (!check_object_signature(r, repl, buffer, size,
    +-					    type_name(type))) {
    ++		if (!check_object_signature(r, repl, buffer, size, type)) {
    + 			free(buffer);
    + 			error(_("hash mismatch %s"), oid_to_hex(repl));
      			return NULL;
    - 		}
     
      ## pack-check.c ##
     @@ pack-check.c: static int verify_packfile(struct repository *r,
      				    oid_to_hex(&oid), p->pack_name,
      				    (uintmax_t)entries[i].offset);
    - 		else if (check_object_signature(r, &oid, data, size,
    --						type_name(type), NULL))
    -+						type, NULL))
    + 		else if (data && !check_object_signature(r, &oid, data, size,
    +-							 type_name(type)))
    ++							 type))
      			err = error("packed %s from %s is corrupt",
      				    oid_to_hex(&oid), p->pack_name);
    - 		else if (fn) {
    + 		else if (!data && !stream_object_signature(r, &oid))
 9:  009b6604d6f ! 10:  e39edfbce05 object-file.c: add a literal version of write_object_file_prepare()
    @@ object-file.c: void *read_object_with_reference(struct repository *r,
      }
      
      /*
    -@@ object-file.c: void hash_object_file(const struct git_hash_algo *algo, const void *buf,
    - 	char hdr[MAX_HEADER_LEN];
    - 	int hdrlen = sizeof(hdr);
    - 
    --	write_object_file_prepare(algo, buf, len, type_name(type), oid, hdr, &hdrlen);
    -+	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
    - }
    - 
    - static void hash_object_file_literally(const struct git_hash_algo *algo, const void *buf,
    -@@ object-file.c: static void hash_object_file_literally(const struct git_hash_algo *algo, const v
    +@@ object-file.c: static void hash_object_file_literally(const struct git_hash_algo *algo,
      	char hdr[MAX_HEADER_LEN];
      	int hdrlen = sizeof(hdr);
      
    @@ object-file.c: static void hash_object_file_literally(const struct git_hash_algo
     +	write_object_file_prepare_literally(algo, buf, len, type, oid, hdr, &hdrlen);
      }
      
    - int hash_object_file_oideq(const struct git_hash_algo *algo, const void *buf,
    + void hash_object_file(const struct git_hash_algo *algo, const void *buf,
     @@ object-file.c: int write_object_file_flags(const void *buf, unsigned long len,
      	/* Normally if we have it in the pack then we do not bother writing
      	 * it out into .git/objects/??/?{38} file.
    @@ object-file.c: int write_object_file_flags(const void *buf, unsigned long len,
      				  &hdrlen);
      	if (freshen_packed_object(oid) || freshen_loose_object(oid))
      		return 0;
    -@@ object-file.c: int hash_write_object_file_literally(const void *buf, unsigned long len,
    +@@ object-file.c: int write_object_file_literally(const void *buf, unsigned long len,
      	/* type string, SP, %lu of the length plus NUL must fit this */
      	hdrlen = strlen(type) + MAX_HEADER_LEN;
      	header = xmalloc(hdrlen);
10:  d89fe344c70 = 11:  f2b1cb861a0 object-file API: pass an enum to read_object_with_reference()
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2 01/11] object-file.c: split up declaration of unrelated variables
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51   ` Ævar Arnfjörð Bjarmason
  2022-02-04 13:51   ` [PATCH v2 02/11] object-file API: return "void", not "int" from hash_object_file() Ævar Arnfjörð Bjarmason
                     ` (10 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Split up the declaration of the "ret" and "re_allocated"
variables. It's not our usual style to group variable declarations
simply because they share a type, we'd only prefer to do so when the
two are closely related (e.g. "int i, j"). This change makes a
subsequent and meaningful change's diff smaller.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 object-file.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/object-file.c b/object-file.c
index 8be57f48de7..ecc77973292 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2118,7 +2118,8 @@ static int index_mem(struct index_state *istate,
 		     enum object_type type,
 		     const char *path, unsigned flags)
 {
-	int ret, re_allocated = 0;
+	int ret;
+	int re_allocated = 0;
 	int write_object = flags & HASH_WRITE_OBJECT;
 
 	if (!type)
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v2 02/11] object-file API: return "void", not "int" from hash_object_file()
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
  2022-02-04 13:51   ` [PATCH v2 01/11] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51   ` Ævar Arnfjörð Bjarmason
  2022-02-04 13:51   ` [PATCH v2 03/11] object-file API: add a format_object_header() function Ævar Arnfjörð Bjarmason
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

The hash_object_file() function added in abdc3fc8421 (Add
hash_sha1_file(), 2006-10-14) did not have a meaningful return value,
and it never has.

One was seemingly added to avoid adding braces to the "ret = "
assignments being modified here. Let's instead assign "0" to the "ret"
variables at the beginning of the relevant functions, and have them
return "void".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 object-file.c  | 16 ++++++++--------
 object-store.h |  6 +++---
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/object-file.c b/object-file.c
index ecc77973292..eeb6814780a 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1836,14 +1836,13 @@ static int write_buffer(int fd, const void *buf, size_t len)
 	return 0;
 }
 
-int hash_object_file(const struct git_hash_algo *algo, const void *buf,
+void hash_object_file(const struct git_hash_algo *algo, const void *buf,
 		     unsigned long len, const char *type,
 		     struct object_id *oid)
 {
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen = sizeof(hdr);
 	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
-	return 0;
 }
 
 /* Finalize a file on disk, and close it. */
@@ -2118,7 +2117,7 @@ static int index_mem(struct index_state *istate,
 		     enum object_type type,
 		     const char *path, unsigned flags)
 {
-	int ret;
+	int ret = 0;
 	int re_allocated = 0;
 	int write_object = flags & HASH_WRITE_OBJECT;
 
@@ -2148,8 +2147,9 @@ static int index_mem(struct index_state *istate,
 	if (write_object)
 		ret = write_object_file(buf, size, type_name(type), oid);
 	else
-		ret = hash_object_file(the_hash_algo, buf, size,
-				       type_name(type), oid);
+		hash_object_file(the_hash_algo, buf, size, type_name(type),
+				 oid);
+
 	if (re_allocated)
 		free(buf);
 	return ret;
@@ -2161,7 +2161,7 @@ static int index_stream_convert_blob(struct index_state *istate,
 				     const char *path,
 				     unsigned flags)
 {
-	int ret;
+	int ret = 0;
 	const int write_object = flags & HASH_WRITE_OBJECT;
 	struct strbuf sbuf = STRBUF_INIT;
 
@@ -2175,8 +2175,8 @@ static int index_stream_convert_blob(struct index_state *istate,
 		ret = write_object_file(sbuf.buf, sbuf.len, type_name(OBJ_BLOB),
 					oid);
 	else
-		ret = hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
-				       type_name(OBJ_BLOB), oid);
+		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
+				 type_name(OBJ_BLOB), oid);
 	strbuf_release(&sbuf);
 	return ret;
 }
diff --git a/object-store.h b/object-store.h
index 6f89482df03..44f6868cc9c 100644
--- a/object-store.h
+++ b/object-store.h
@@ -245,9 +245,9 @@ static inline void *repo_read_object_file(struct repository *r,
 /* Read and unpack an object file into memory, write memory to an object file */
 int oid_object_info(struct repository *r, const struct object_id *, unsigned long *);
 
-int hash_object_file(const struct git_hash_algo *algo, const void *buf,
-		     unsigned long len, const char *type,
-		     struct object_id *oid);
+void hash_object_file(const struct git_hash_algo *algo, const void *buf,
+		      unsigned long len, const char *type,
+		      struct object_id *oid);
 
 int write_object_file_flags(const void *buf, unsigned long len,
 			    const char *type, struct object_id *oid,
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v2 03/11] object-file API: add a format_object_header() function
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
  2022-02-04 13:51   ` [PATCH v2 01/11] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
  2022-02-04 13:51   ` [PATCH v2 02/11] object-file API: return "void", not "int" from hash_object_file() Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51   ` Ævar Arnfjörð Bjarmason
  2022-02-04 13:51   ` [PATCH v2 04/11] object-file API: have write_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

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>
---
 builtin/fast-import.c |  6 +++---
 builtin/index-pack.c  |  3 +--
 bulk-checkin.c        |  4 ++--
 http-push.c           |  2 +-
 object-file.c         | 23 ++++++++++++++++++++---
 object-store.h        |  8 ++++++++
 6 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 2b2e28bad79..123df7d9a53 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -937,8 +937,8 @@ static int store_object(
 	git_hash_ctx c;
 	git_zstream s;
 
-	hdrlen = xsnprintf((char *)hdr, sizeof(hdr), "%s %lu",
-			   type_name(type), (unsigned long)dat->len) + 1;
+	hdrlen = format_object_header((char *)hdr, sizeof(hdr), type,
+				      dat->len);
 	the_hash_algo->init_fn(&c);
 	the_hash_algo->update_fn(&c, hdr, hdrlen);
 	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);
 	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->update_fn(&c, out_buf, hdrlen);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 3c2e6aee3cc..01574378ce2 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -449,8 +449,7 @@ static void *unpack_entry_data(off_t offset, unsigned long size,
 	int hdrlen;
 
 	if (!is_delta_type(type)) {
-		hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX,
-				   type_name(type),(uintmax_t)size) + 1;
+		hdrlen = format_object_header(hdr, sizeof(hdr), type, size);
 		the_hash_algo->init_fn(&c);
 		the_hash_algo->update_fn(&c, hdr, hdrlen);
 	} else
diff --git a/bulk-checkin.c b/bulk-checkin.c
index 8785b2ac806..85b3ebaf971 100644
--- a/bulk-checkin.c
+++ b/bulk-checkin.c
@@ -220,8 +220,8 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
 	if (seekback == (off_t) -1)
 		return error("cannot find the current offset");
 
-	header_len = xsnprintf((char *)obuf, sizeof(obuf), "%s %" PRIuMAX,
-			       type_name(type), (uintmax_t)size) + 1;
+	header_len = format_object_header((char *)obuf, sizeof(obuf),
+					  type, size);
 	the_hash_algo->init_fn(&ctx);
 	the_hash_algo->update_fn(&ctx, obuf, header_len);
 
diff --git a/http-push.c b/http-push.c
index 3309aaf004a..f0c044dcf76 100644
--- a/http-push.c
+++ b/http-push.c
@@ -363,7 +363,7 @@ static void start_put(struct transfer_request *request)
 	git_zstream stream;
 
 	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 */
 	git_deflate_init(&stream, zlib_compression_level);
diff --git a/object-file.c b/object-file.c
index eeb6814780a..3fcd46cf9ed 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1049,6 +1049,23 @@ void *xmmap(void *start, size_t length,
 	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
  * 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;
 
 	/* 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.. */
 	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;
 
 	/* Generate the header */
-	*hdrlen = xsnprintf(hdr, *hdrlen, "%s %"PRIuMAX , type, (uintmax_t)len)+1;
+	*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
 
 	/* Sha1.. */
 	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);
 	if (!buf)
 		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);
 	free(buf);
 
diff --git a/object-store.h b/object-store.h
index 44f6868cc9c..8b4413d0ce7 100644
--- a/object-store.h
+++ b/object-store.h
@@ -331,6 +331,14 @@ int repo_has_object_file_with_flags(struct repository *r,
  */
 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);
 
 /*
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v2 04/11] object-file API: have write_object_file() take "enum object_type"
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                     ` (2 preceding siblings ...)
  2022-02-04 13:51   ` [PATCH v2 03/11] object-file API: add a format_object_header() function Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51   ` Ævar Arnfjörð Bjarmason
  2022-02-04 20:52     ` Junio C Hamano
  2022-02-04 13:51   ` [PATCH v2 05/11] object API: correct "buf" v.s. "map" mismatch in *.c and *.h Ævar Arnfjörð Bjarmason
                     ` (7 subsequent siblings)
  11 siblings, 1 reply; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the write_object_file() function to take an "enum object_type"
instead of a "const char *type". Its callers either passed
{commit,tree,blob,tag}_type and can pass the corresponding OBJ_* type
instead, or were hardcoding strings like "blob".

This avoids the back & forth fragility where the callers of
write_object_file() would have the enum type, and convert it
themselves via type_name(). We do have to now do that conversion
ourselves before calling write_object_file_prepare(), but those
codepaths will be similarly adjusted in subsequent commits.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 apply.c                  |  8 ++++----
 builtin/checkout.c       |  2 +-
 builtin/mktag.c          |  2 +-
 builtin/mktree.c         |  2 +-
 builtin/notes.c          |  3 +--
 builtin/receive-pack.c   |  2 +-
 builtin/replace.c        |  2 +-
 builtin/tag.c            |  2 +-
 builtin/unpack-objects.c |  6 +++---
 cache-tree.c             |  2 +-
 commit.c                 |  2 +-
 match-trees.c            |  2 +-
 merge-ort.c              |  4 ++--
 merge-recursive.c        |  2 +-
 notes-cache.c            |  2 +-
 notes.c                  |  8 ++++----
 object-file.c            | 10 +++++-----
 object-store.h           |  4 ++--
 read-cache.c             |  2 +-
 19 files changed, 33 insertions(+), 34 deletions(-)

diff --git a/apply.c b/apply.c
index 7ffadc3b17a..e82a7c30f01 100644
--- a/apply.c
+++ b/apply.c
@@ -3589,7 +3589,7 @@ static int try_threeway(struct apply_state *state,
 
 	/* Preimage the patch was prepared for */
 	if (patch->is_new)
-		write_object_file("", 0, blob_type, &pre_oid);
+		write_object_file("", 0, OBJ_BLOB, &pre_oid);
 	else if (get_oid(patch->old_oid_prefix, &pre_oid) ||
 		 read_blob_object(&buf, &pre_oid, patch->old_mode))
 		return error(_("repository lacks the necessary blob to perform 3-way merge."));
@@ -3605,7 +3605,7 @@ static int try_threeway(struct apply_state *state,
 		return -1;
 	}
 	/* post_oid is theirs */
-	write_object_file(tmp_image.buf, tmp_image.len, blob_type, &post_oid);
+	write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &post_oid);
 	clear_image(&tmp_image);
 
 	/* our_oid is ours */
@@ -3618,7 +3618,7 @@ static int try_threeway(struct apply_state *state,
 			return error(_("cannot read the current contents of '%s'"),
 				     patch->old_name);
 	}
-	write_object_file(tmp_image.buf, tmp_image.len, blob_type, &our_oid);
+	write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &our_oid);
 	clear_image(&tmp_image);
 
 	/* in-core three-way merge between post and our using pre as base */
@@ -4346,7 +4346,7 @@ static int add_index_file(struct apply_state *state,
 			}
 			fill_stat_cache_info(state->repo->index, ce, &st);
 		}
-		if (write_object_file(buf, size, blob_type, &ce->oid) < 0) {
+		if (write_object_file(buf, size, OBJ_BLOB, &ce->oid) < 0) {
 			discard_cache_entry(ce);
 			return error(_("unable to create backing store "
 				       "for newly created file %s"), path);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index cc804ba8e1e..24cc235939f 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -298,7 +298,7 @@ static int checkout_merged(int pos, const struct checkout *state,
 	 * (it also writes the merge result to the object database even
 	 * when it may contain conflicts).
 	 */
-	if (write_object_file(result_buf.ptr, result_buf.size, blob_type, &oid))
+	if (write_object_file(result_buf.ptr, result_buf.size, OBJ_BLOB, &oid))
 		die(_("Unable to add merge result for '%s'"), path);
 	free(result_buf.ptr);
 	ce = make_transient_cache_entry(mode, &oid, path, 2, ce_mem_pool);
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 3b2dbbb37e6..96a3686af53 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -100,7 +100,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (verify_object_in_tag(&tagged_oid, &tagged_type))
 		die(_("tag on stdin did not refer to a valid object"));
 
-	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
+	if (write_object_file(buf.buf, buf.len, OBJ_TAG, &result) < 0)
 		die(_("unable to write tag file"));
 
 	strbuf_release(&buf);
diff --git a/builtin/mktree.c b/builtin/mktree.c
index ae78ca1c029..a1213aaa961 100644
--- a/builtin/mktree.c
+++ b/builtin/mktree.c
@@ -58,7 +58,7 @@ static void write_tree(struct object_id *oid)
 		strbuf_add(&buf, ent->oid.hash, the_hash_algo->rawsz);
 	}
 
-	write_object_file(buf.buf, buf.len, tree_type, oid);
+	write_object_file(buf.buf, buf.len, OBJ_TREE, oid);
 	strbuf_release(&buf);
 }
 
diff --git a/builtin/notes.c b/builtin/notes.c
index 05d60483e82..d81acaeaf78 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -199,9 +199,8 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
 
 static void write_note_data(struct note_data *d, struct object_id *oid)
 {
-	if (write_object_file(d->buf.buf, d->buf.len, blob_type, oid)) {
+	if (write_object_file(d->buf.buf, d->buf.len, OBJ_BLOB, oid)) {
 		int status = die_message(_("unable to write note object"));
-
 		if (d->edit_path)
 			die_message(_("the note contents have been left in %s"),
 				    d->edit_path);
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 9f4a0b816cf..231d576927b 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -762,7 +762,7 @@ static void prepare_push_cert_sha1(struct child_process *proc)
 		int bogs /* beginning_of_gpg_sig */;
 
 		already_done = 1;
-		if (write_object_file(push_cert.buf, push_cert.len, "blob",
+		if (write_object_file(push_cert.buf, push_cert.len, OBJ_BLOB,
 				      &push_cert_oid))
 			oidclr(&push_cert_oid);
 
diff --git a/builtin/replace.c b/builtin/replace.c
index 6ff1734d587..995ca683302 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -474,7 +474,7 @@ static int create_graft(int argc, const char **argv, int force, int gentle)
 		return -1;
 	}
 
-	if (write_object_file(buf.buf, buf.len, commit_type, &new_oid)) {
+	if (write_object_file(buf.buf, buf.len, OBJ_COMMIT, &new_oid)) {
 		strbuf_release(&buf);
 		return error(_("could not write replacement commit for: '%s'"),
 			     old_ref);
diff --git a/builtin/tag.c b/builtin/tag.c
index 134b3f1edf0..31e6b155c04 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -238,7 +238,7 @@ static int build_tag_object(struct strbuf *buf, int sign, struct object_id *resu
 {
 	if (sign && do_sign(buf) < 0)
 		return error(_("unable to sign the tag"));
-	if (write_object_file(buf->buf, buf->len, tag_type, result) < 0)
+	if (write_object_file(buf->buf, buf->len, OBJ_TAG, result) < 0)
 		return error(_("unable to write tag file"));
 	return 0;
 }
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 4a9466295ba..808041551fd 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -177,7 +177,7 @@ static void write_cached_object(struct object *obj, struct obj_buffer *obj_buf)
 	struct object_id oid;
 
 	if (write_object_file(obj_buf->buffer, obj_buf->size,
-			      type_name(obj->type), &oid) < 0)
+			      obj->type, &oid) < 0)
 		die("failed to write object %s", oid_to_hex(&obj->oid));
 	obj->flags |= FLAG_WRITTEN;
 }
@@ -243,7 +243,7 @@ static void write_object(unsigned nr, enum object_type type,
 			 void *buf, unsigned long size)
 {
 	if (!strict) {
-		if (write_object_file(buf, size, type_name(type),
+		if (write_object_file(buf, size, type,
 				      &obj_list[nr].oid) < 0)
 			die("failed to write object");
 		added_object(nr, type, buf, size);
@@ -251,7 +251,7 @@ static void write_object(unsigned nr, enum object_type type,
 		obj_list[nr].obj = NULL;
 	} else if (type == OBJ_BLOB) {
 		struct blob *blob;
-		if (write_object_file(buf, size, type_name(type),
+		if (write_object_file(buf, size, type,
 				      &obj_list[nr].oid) < 0)
 			die("failed to write object");
 		added_object(nr, type, buf, size);
diff --git a/cache-tree.c b/cache-tree.c
index 65ca9933613..fdbbd191d22 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -440,7 +440,7 @@ static int update_one(struct cache_tree *it,
 	} else if (dryrun) {
 		hash_object_file(the_hash_algo, buffer.buf, buffer.len,
 				 tree_type, &it->oid);
-	} else if (write_object_file_flags(buffer.buf, buffer.len, tree_type,
+	} else if (write_object_file_flags(buffer.buf, buffer.len, OBJ_TREE,
 					   &it->oid, flags & WRITE_TREE_SILENT
 					   ? HASH_SILENT : 0)) {
 		strbuf_release(&buffer);
diff --git a/commit.c b/commit.c
index a348f085b2b..6cc0ba9c11b 100644
--- a/commit.c
+++ b/commit.c
@@ -1567,7 +1567,7 @@ int commit_tree_extended(const char *msg, size_t msg_len,
 		goto out;
 	}
 
-	result = write_object_file(buffer.buf, buffer.len, commit_type, ret);
+	result = write_object_file(buffer.buf, buffer.len, OBJ_COMMIT, ret);
 out:
 	strbuf_release(&buffer);
 	return result;
diff --git a/match-trees.c b/match-trees.c
index df413989fa8..49398e599fe 100644
--- a/match-trees.c
+++ b/match-trees.c
@@ -235,7 +235,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
 		rewrite_with = oid2;
 	}
 	hashcpy(rewrite_here, rewrite_with->hash);
-	status = write_object_file(buf, sz, tree_type, result);
+	status = write_object_file(buf, sz, OBJ_TREE, result);
 	free(buf);
 	return status;
 }
diff --git a/merge-ort.c b/merge-ort.c
index c3197970219..d4ba2955f11 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -1888,7 +1888,7 @@ static int handle_content_merge(struct merge_options *opt,
 
 		if (!ret &&
 		    write_object_file(result_buf.ptr, result_buf.size,
-				      blob_type, &result->oid))
+				      OBJ_BLOB, &result->oid))
 			ret = err(opt, _("Unable to add %s to database"),
 				  path);
 
@@ -3343,7 +3343,7 @@ static void write_tree(struct object_id *result_oid,
 	}
 
 	/* Write this object file out, and record in result_oid */
-	write_object_file(buf.buf, buf.len, tree_type, result_oid);
+	write_object_file(buf.buf, buf.len, OBJ_TREE, result_oid);
 	strbuf_release(&buf);
 }
 
diff --git a/merge-recursive.c b/merge-recursive.c
index d9457797dbb..e0cbbf2d022 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1373,7 +1373,7 @@ static int merge_mode_and_contents(struct merge_options *opt,
 
 			if (!ret &&
 			    write_object_file(result_buf.ptr, result_buf.size,
-					      blob_type, &result->blob.oid))
+					      OBJ_BLOB, &result->blob.oid))
 				ret = err(opt, _("Unable to add %s to database"),
 					  a->path);
 
diff --git a/notes-cache.c b/notes-cache.c
index 2473314d686..9dfd251a815 100644
--- a/notes-cache.c
+++ b/notes-cache.c
@@ -92,7 +92,7 @@ int notes_cache_put(struct notes_cache *c, struct object_id *key_oid,
 {
 	struct object_id value_oid;
 
-	if (write_object_file(data, size, "blob", &value_oid) < 0)
+	if (write_object_file(data, size, OBJ_BLOB, &value_oid) < 0)
 		return -1;
 	return add_note(&c->tree, key_oid, &value_oid, NULL);
 }
diff --git a/notes.c b/notes.c
index f87dac40684..7452e71cc8d 100644
--- a/notes.c
+++ b/notes.c
@@ -675,7 +675,7 @@ static int tree_write_stack_finish_subtree(struct tree_write_stack *tws)
 		ret = tree_write_stack_finish_subtree(n);
 		if (ret)
 			return ret;
-		ret = write_object_file(n->buf.buf, n->buf.len, tree_type, &s);
+		ret = write_object_file(n->buf.buf, n->buf.len, OBJ_TREE, &s);
 		if (ret)
 			return ret;
 		strbuf_release(&n->buf);
@@ -836,7 +836,7 @@ int combine_notes_concatenate(struct object_id *cur_oid,
 	free(new_msg);
 
 	/* create a new blob object from buf */
-	ret = write_object_file(buf, buf_len, blob_type, cur_oid);
+	ret = write_object_file(buf, buf_len, OBJ_BLOB, cur_oid);
 	free(buf);
 	return ret;
 }
@@ -916,7 +916,7 @@ int combine_notes_cat_sort_uniq(struct object_id *cur_oid,
 				 string_list_join_lines_helper, &buf))
 		goto out;
 
-	ret = write_object_file(buf.buf, buf.len, blob_type, cur_oid);
+	ret = write_object_file(buf.buf, buf.len, OBJ_BLOB, cur_oid);
 
 out:
 	strbuf_release(&buf);
@@ -1192,7 +1192,7 @@ int write_notes_tree(struct notes_tree *t, struct object_id *result)
 	ret = for_each_note(t, flags, write_each_note, &cb_data) ||
 	      write_each_non_note_until(NULL, &cb_data) ||
 	      tree_write_stack_finish_subtree(&root) ||
-	      write_object_file(root.buf.buf, root.buf.len, tree_type, result);
+	      write_object_file(root.buf.buf, root.buf.len, OBJ_TREE, result);
 	strbuf_release(&root.buf);
 	return ret;
 }
diff --git a/object-file.c b/object-file.c
index 3fcd46cf9ed..59eb793e0ac 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2014,7 +2014,7 @@ static int freshen_packed_object(const struct object_id *oid)
 }
 
 int write_object_file_flags(const void *buf, unsigned long len,
-			    const char *type, struct object_id *oid,
+			    enum object_type type, struct object_id *oid,
 			    unsigned flags)
 {
 	char hdr[MAX_HEADER_LEN];
@@ -2023,7 +2023,7 @@ int write_object_file_flags(const void *buf, unsigned long len,
 	/* Normally if we have it in the pack then we do not bother writing
 	 * it out into .git/objects/??/?{38} file.
 	 */
-	write_object_file_prepare(the_hash_algo, buf, len, type, oid, hdr,
+	write_object_file_prepare(the_hash_algo, buf, len, type_name(type), oid, hdr,
 				  &hdrlen);
 	if (freshen_packed_object(oid) || freshen_loose_object(oid))
 		return 0;
@@ -2162,7 +2162,7 @@ static int index_mem(struct index_state *istate,
 	}
 
 	if (write_object)
-		ret = write_object_file(buf, size, type_name(type), oid);
+		ret = write_object_file(buf, size, type, oid);
 	else
 		hash_object_file(the_hash_algo, buf, size, type_name(type),
 				 oid);
@@ -2189,7 +2189,7 @@ static int index_stream_convert_blob(struct index_state *istate,
 				 get_conv_flags(flags));
 
 	if (write_object)
-		ret = write_object_file(sbuf.buf, sbuf.len, type_name(OBJ_BLOB),
+		ret = write_object_file(sbuf.buf, sbuf.len, OBJ_BLOB,
 					oid);
 	else
 		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
@@ -2313,7 +2313,7 @@ int index_path(struct index_state *istate, struct object_id *oid,
 		if (!(flags & HASH_WRITE_OBJECT))
 			hash_object_file(the_hash_algo, sb.buf, sb.len,
 					 blob_type, oid);
-		else if (write_object_file(sb.buf, sb.len, blob_type, oid))
+		else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid))
 			rc = error(_("%s: failed to insert into database"), path);
 		strbuf_release(&sb);
 		break;
diff --git a/object-store.h b/object-store.h
index 8b4413d0ce7..eab1e2a967e 100644
--- a/object-store.h
+++ b/object-store.h
@@ -250,10 +250,10 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf,
 		      struct object_id *oid);
 
 int write_object_file_flags(const void *buf, unsigned long len,
-			    const char *type, struct object_id *oid,
+			    enum object_type type, struct object_id *oid,
 			    unsigned flags);
 static inline int write_object_file(const void *buf, unsigned long len,
-				    const char *type, struct object_id *oid)
+				    enum object_type type, struct object_id *oid)
 {
 	return write_object_file_flags(buf, len, type, oid, 0);
 }
diff --git a/read-cache.c b/read-cache.c
index cbe73f14e5e..b8ae30a0e71 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -735,7 +735,7 @@ static struct cache_entry *create_alias_ce(struct index_state *istate,
 void set_object_name_for_intent_to_add_entry(struct cache_entry *ce)
 {
 	struct object_id oid;
-	if (write_object_file("", 0, blob_type, &oid))
+	if (write_object_file("", 0, OBJ_BLOB, &oid))
 		die(_("cannot create an empty blob in the object database"));
 	oidcpy(&ce->oid, &oid);
 }
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v2 05/11] object API: correct "buf" v.s. "map" mismatch in *.c and *.h
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                     ` (3 preceding siblings ...)
  2022-02-04 13:51   ` [PATCH v2 04/11] object-file API: have write_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51   ` Ævar Arnfjörð Bjarmason
  2022-02-04 20:54     ` Junio C Hamano
  2022-02-04 13:51   ` [PATCH v2 06/11] object API: make check_object_signature() oideq()-like, move docs Ævar Arnfjörð Bjarmason
                     ` (6 subsequent siblings)
  11 siblings, 1 reply; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the name of the second argument to check_object_signature() to
be "buf" in object-file.c, making it consistent with the prototype in
cache..h

This fixes an inconsistency that's been with us since 2ade9340262 (Add
"check_sha1_signature()" helper function, 2005-04-08), and makes a
subsequent commit's diff smaller, as we'll move these API docs to
cache.h.

While we're at it fix a small grammar error in the documentation,
dropping an "an" before "in-core object-data".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 object-file.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/object-file.c b/object-file.c
index 59eb793e0ac..271acf4dd15 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1067,13 +1067,13 @@ int format_object_header(char *str, size_t size, enum object_type type,
 }
 
 /*
- * With an in-core object data in "map", rehash it to make sure the
+ * With in-core object data in "buf", rehash it to make sure the
  * object name actually matches "oid" to detect object corruption.
- * With "map" == NULL, try reading the object named with "oid" using
+ * With "buf" == NULL, try reading the object named with "oid" using
  * the streaming interface and rehash it to do the same.
  */
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *map, unsigned long size, const char *type,
+			   void *buf, unsigned long size, const char *type,
 			   struct object_id *real_oidp)
 {
 	struct object_id tmp;
@@ -1084,8 +1084,8 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen;
 
-	if (map) {
-		hash_object_file(r->hash_algo, map, size, type, real_oid);
+	if (buf) {
+		hash_object_file(r->hash_algo, buf, size, type, real_oid);
 		return !oideq(oid, real_oid) ? -1 : 0;
 	}
 
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v2 06/11] object API: make check_object_signature() oideq()-like, move docs
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                     ` (4 preceding siblings ...)
  2022-02-04 13:51   ` [PATCH v2 05/11] object API: correct "buf" v.s. "map" mismatch in *.c and *.h Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51   ` Ævar Arnfjörð Bjarmason
  2022-02-04 21:15     ` Junio C Hamano
  2022-02-04 13:51   ` [PATCH v2 07/11] object-file API: split up and simplify check_object_signature() Ævar Arnfjörð Bjarmason
                     ` (5 subsequent siblings)
  11 siblings, 1 reply; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Make the return value of check_object_signature() behave like oideq()
and memcmp() instead of returning negative values on failure.

This reduces the boilerplate required when calling the function, and
makes the calling code behave the same is if though we'd called
oideq(), which is basically what we're doing here. We already had some
callers using "f() < 0", with others using "!f()". Instead of
declaring the latter a bug let's convert all callers to it.

It is unfortunate that there's also cases where we "return -1" on
various errors, and we can't tell those apart from the expected OID
being less than the real OID, but this was the case already.

This change is rather dangerous stand-alone as we're changing the
return semantics, but not changing the prototype. Therefore any
out-of-tree code rebased on this change would start doing the opposite
of what it was meant to do. In a subsequent commit we'll make that a
non-issue by changing the signature of the function, ensuring that the
compiler will catch any such misuse.

While we're at it let's re-flow some of the callers to wrap at 79
characters, and move the API documentation to cache.h, where the
prototype of this function lives.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/fast-export.c |  4 ++--
 builtin/index-pack.c  |  5 ++---
 builtin/mktag.c       |  5 ++---
 cache.h               |  9 +++++++++
 object-file.c         | 16 +++++-----------
 object.c              |  6 +++---
 pack-check.c          |  4 ++--
 7 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 9f1c730e587..7a79cb186b1 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -299,8 +299,8 @@ static void export_blob(const struct object_id *oid)
 		buf = read_object_file(oid, &type, &size);
 		if (!buf)
 			die("could not read blob %s", oid_to_hex(oid));
-		if (check_object_signature(the_repository, oid, buf, size,
-					   type_name(type), NULL) < 0)
+		if (!check_object_signature(the_repository, oid, buf, size,
+					    type_name(type), NULL))
 			die("oid mismatch in blob %s", oid_to_hex(oid));
 		object = parse_object_buffer(the_repository, oid, type,
 					     size, buf, &eaten);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 01574378ce2..6db3e728ff4 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1412,9 +1412,8 @@ static void fix_unresolved_deltas(struct hashfile *f)
 		if (!data)
 			continue;
 
-		if (check_object_signature(the_repository, &d->oid,
-					   data, size,
-					   type_name(type), NULL))
+		if (!check_object_signature(the_repository, &d->oid, data,
+					    size, type_name(type), NULL))
 			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
 
 		/*
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 96a3686af53..a715bf53cf0 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -61,9 +61,8 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 		    type_name(*tagged_type), type_name(type));
 
 	repl = lookup_replace_object(the_repository, tagged_oid);
-	ret = check_object_signature(the_repository, repl,
-				     buffer, size, type_name(*tagged_type),
-				     NULL);
+	ret = !check_object_signature(the_repository, repl, buffer, size,
+				      type_name(*tagged_type), NULL);
 	free(buffer);
 
 	return ret;
diff --git a/cache.h b/cache.h
index 281f00ab1b1..3a156dcb37b 100644
--- a/cache.h
+++ b/cache.h
@@ -1319,6 +1319,15 @@ enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
 struct object_info;
 int parse_loose_header(const char *hdr, struct object_info *oi);
 
+/**
+ * With in-core object data in "buf", rehash it to make sure the
+ * object name actually matches "oid" to detect object corruption.
+ * With "buf" == NULL, try reading the object named with "oid" using
+ * the streaming interface and rehash it to do the same.
+ *
+ * Treat the return value like oideq() (which is like memcmp()),
+ * except that negative values might also indicate a generic error.
+ */
 int check_object_signature(struct repository *r, const struct object_id *oid,
 			   void *buf, unsigned long size, const char *type,
 			   struct object_id *real_oidp);
diff --git a/object-file.c b/object-file.c
index 271acf4dd15..4c38ddad5dc 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1066,12 +1066,6 @@ int format_object_header(char *str, size_t size, enum object_type type,
 	return format_object_header_literally(str, size, name, objsize);
 }
 
-/*
- * With in-core object data in "buf", rehash it to make sure the
- * object name actually matches "oid" to detect object corruption.
- * With "buf" == NULL, try reading the object named with "oid" using
- * the streaming interface and rehash it to do the same.
- */
 int check_object_signature(struct repository *r, const struct object_id *oid,
 			   void *buf, unsigned long size, const char *type,
 			   struct object_id *real_oidp)
@@ -1086,7 +1080,7 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
 
 	if (buf) {
 		hash_object_file(r->hash_algo, buf, size, type, real_oid);
-		return !oideq(oid, real_oid) ? -1 : 0;
+		return oideq(oid, real_oid);
 	}
 
 	st = open_istream(r, oid, &obj_type, &size, NULL);
@@ -1113,7 +1107,7 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
 	}
 	r->hash_algo->final_oid_fn(real_oid, &c);
 	close_istream(st);
-	return !oideq(oid, real_oid) ? -1 : 0;
+	return oideq(oid, real_oid);
 }
 
 int git_open_cloexec(const char *name, int flags)
@@ -2617,9 +2611,9 @@ int read_loose_object(const char *path,
 			git_inflate_end(&stream);
 			goto out;
 		}
-		if (check_object_signature(the_repository, expected_oid,
-					   *contents, *size,
-					   oi->type_name->buf, real_oid))
+		if (!check_object_signature(the_repository, expected_oid,
+					    *contents, *size,
+					    oi->type_name->buf, real_oid))
 			goto out;
 	}
 
diff --git a/object.c b/object.c
index c37501fc120..b778b32407d 100644
--- a/object.c
+++ b/object.c
@@ -279,7 +279,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
 	if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
 	    (!obj && repo_has_object_file(r, oid) &&
 	     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
-		if (check_object_signature(r, repl, NULL, 0, NULL, NULL) < 0) {
+		if (!check_object_signature(r, repl, NULL, 0, NULL, NULL)) {
 			error(_("hash mismatch %s"), oid_to_hex(oid));
 			return NULL;
 		}
@@ -289,8 +289,8 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
 
 	buffer = repo_read_object_file(r, oid, &type, &size);
 	if (buffer) {
-		if (check_object_signature(r, repl, buffer, size,
-					   type_name(type), NULL) < 0) {
+		if (!check_object_signature(r, repl, buffer, size,
+					    type_name(type), NULL)) {
 			free(buffer);
 			error(_("hash mismatch %s"), oid_to_hex(repl));
 			return NULL;
diff --git a/pack-check.c b/pack-check.c
index 3f418e3a6af..35cca10057c 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -142,8 +142,8 @@ static int verify_packfile(struct repository *r,
 			err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
 				    oid_to_hex(&oid), p->pack_name,
 				    (uintmax_t)entries[i].offset);
-		else if (check_object_signature(r, &oid, data, size,
-						type_name(type), NULL))
+		else if (!check_object_signature(r, &oid, data, size,
+						 type_name(type), NULL))
 			err = error("packed %s from %s is corrupt",
 				    oid_to_hex(&oid), p->pack_name);
 		else if (fn) {
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v2 07/11] object-file API: split up and simplify check_object_signature()
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                     ` (5 preceding siblings ...)
  2022-02-04 13:51   ` [PATCH v2 06/11] object API: make check_object_signature() oideq()-like, move docs Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51   ` Ævar Arnfjörð Bjarmason
  2022-02-04 13:51   ` [PATCH v2 08/11] object API: rename hash_object_file_literally() to write_*() Ævar Arnfjörð Bjarmason
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Split up the check_object_signature() function into that non-streaming
version (it accepts an already filled "buf"), and a new
stream_object_signature() which will retrieve the object from storage,
and hash it on-the-fly.

All of the callers of check_object_signature() were effectively
calling two different functions, if we go by cyclomatic
complexity. I.e. they'd either take the early "if (map)" branch and
return early, or not. This has been the case since the "if (map)"
condition was added in 090ea12671b (parse_object: avoid putting whole
blob in core, 2012-03-07).

We can then further simplify the resulting check_object_signature()
function since only one caller wanted to pass a non-NULL "buf" and a
non-NULL "real_oidp". That "read_loose_object()" codepath used by "git
fsck" can instead use hash_object_file() followed by oideq().

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/fast-export.c |  2 +-
 builtin/index-pack.c  |  2 +-
 builtin/mktag.c       |  2 +-
 cache.h               | 12 ++++++++----
 object-file.c         | 33 +++++++++++++++++++--------------
 object.c              |  4 ++--
 pack-check.c          |  9 ++++++---
 7 files changed, 38 insertions(+), 26 deletions(-)

diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 7a79cb186b1..1878ec34960 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -300,7 +300,7 @@ static void export_blob(const struct object_id *oid)
 		if (!buf)
 			die("could not read blob %s", oid_to_hex(oid));
 		if (!check_object_signature(the_repository, oid, buf, size,
-					    type_name(type), NULL))
+					    type_name(type)))
 			die("oid mismatch in blob %s", oid_to_hex(oid));
 		object = parse_object_buffer(the_repository, oid, type,
 					     size, buf, &eaten);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 6db3e728ff4..eaa7b6698d1 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1413,7 +1413,7 @@ static void fix_unresolved_deltas(struct hashfile *f)
 			continue;
 
 		if (!check_object_signature(the_repository, &d->oid, data,
-					    size, type_name(type), NULL))
+					    size, type_name(type)))
 			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
 
 		/*
diff --git a/builtin/mktag.c b/builtin/mktag.c
index a715bf53cf0..1282e8cd9e2 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -62,7 +62,7 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 
 	repl = lookup_replace_object(the_repository, tagged_oid);
 	ret = !check_object_signature(the_repository, repl, buffer, size,
-				      type_name(*tagged_type), NULL);
+				      type_name(*tagged_type));
 	free(buffer);
 
 	return ret;
diff --git a/cache.h b/cache.h
index 3a156dcb37b..5a13bbfd904 100644
--- a/cache.h
+++ b/cache.h
@@ -1322,15 +1322,19 @@ int parse_loose_header(const char *hdr, struct object_info *oi);
 /**
  * With in-core object data in "buf", rehash it to make sure the
  * object name actually matches "oid" to detect object corruption.
- * With "buf" == NULL, try reading the object named with "oid" using
- * the streaming interface and rehash it to do the same.
  *
  * Treat the return value like oideq() (which is like memcmp()),
  * except that negative values might also indicate a generic error.
  */
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *buf, unsigned long size, const char *type,
-			   struct object_id *real_oidp);
+			   void *buf, unsigned long size, const char *type);
+
+/**
+ * A streaming version of check_object_signature().
+ * Try reading the object named with "oid" using
+ * the streaming interface and rehash it to do the same.
+ */
+int stream_object_signature(struct repository *r, const struct object_id *oid);
 
 int finalize_object_file(const char *tmpfile, const char *filename);
 
diff --git a/object-file.c b/object-file.c
index 4c38ddad5dc..937a107c5ab 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1067,22 +1067,25 @@ int format_object_header(char *str, size_t size, enum object_type type,
 }
 
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *buf, unsigned long size, const char *type,
-			   struct object_id *real_oidp)
+			   void *buf, unsigned long size, const char *type)
 {
-	struct object_id tmp;
-	struct object_id *real_oid = real_oidp ? real_oidp : &tmp;
+	struct object_id real_oid;
+
+	hash_object_file(r->hash_algo, buf, size, type, &real_oid);
+
+	return oideq(oid, &real_oid);
+}
+
+int stream_object_signature(struct repository *r, const struct object_id *oid)
+{
+	struct object_id real_oid;
+	unsigned long size;
 	enum object_type obj_type;
 	struct git_istream *st;
 	git_hash_ctx c;
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen;
 
-	if (buf) {
-		hash_object_file(r->hash_algo, buf, size, type, real_oid);
-		return oideq(oid, real_oid);
-	}
-
 	st = open_istream(r, oid, &obj_type, &size, NULL);
 	if (!st)
 		return -1;
@@ -1105,9 +1108,9 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
 			break;
 		r->hash_algo->update_fn(&c, buf, readlen);
 	}
-	r->hash_algo->final_oid_fn(real_oid, &c);
+	r->hash_algo->final_oid_fn(&real_oid, &c);
 	close_istream(st);
-	return oideq(oid, real_oid);
+	return oideq(oid, &real_oid);
 }
 
 int git_open_cloexec(const char *name, int flags)
@@ -2611,9 +2614,11 @@ int read_loose_object(const char *path,
 			git_inflate_end(&stream);
 			goto out;
 		}
-		if (!check_object_signature(the_repository, expected_oid,
-					    *contents, *size,
-					    oi->type_name->buf, real_oid))
+
+		hash_object_file(the_repository->hash_algo,
+				 *contents, *size, oi->type_name->buf,
+				 real_oid);
+		if (!oideq(expected_oid, real_oid))
 			goto out;
 	}
 
diff --git a/object.c b/object.c
index b778b32407d..b3f9cd5c8cd 100644
--- a/object.c
+++ b/object.c
@@ -279,7 +279,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
 	if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
 	    (!obj && repo_has_object_file(r, oid) &&
 	     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
-		if (!check_object_signature(r, repl, NULL, 0, NULL, NULL)) {
+		if (!stream_object_signature(r, repl)) {
 			error(_("hash mismatch %s"), oid_to_hex(oid));
 			return NULL;
 		}
@@ -290,7 +290,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
 	buffer = repo_read_object_file(r, oid, &type, &size);
 	if (buffer) {
 		if (!check_object_signature(r, repl, buffer, size,
-					    type_name(type), NULL)) {
+					    type_name(type))) {
 			free(buffer);
 			error(_("hash mismatch %s"), oid_to_hex(repl));
 			return NULL;
diff --git a/pack-check.c b/pack-check.c
index 35cca10057c..4a27e77704b 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -127,7 +127,7 @@ static int verify_packfile(struct repository *r,
 
 		if (type == OBJ_BLOB && big_file_threshold <= size) {
 			/*
-			 * Let check_object_signature() check it with
+			 * Let stream_object_signature() check it with
 			 * the streaming interface; no point slurping
 			 * the data in-core only to discard.
 			 */
@@ -142,8 +142,11 @@ static int verify_packfile(struct repository *r,
 			err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
 				    oid_to_hex(&oid), p->pack_name,
 				    (uintmax_t)entries[i].offset);
-		else if (!check_object_signature(r, &oid, data, size,
-						 type_name(type), NULL))
+		else if (data && !check_object_signature(r, &oid, data, size,
+							 type_name(type)))
+			err = error("packed %s from %s is corrupt",
+				    oid_to_hex(&oid), p->pack_name);
+		else if (!data && !stream_object_signature(r, &oid))
 			err = error("packed %s from %s is corrupt",
 				    oid_to_hex(&oid), p->pack_name);
 		else if (fn) {
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v2 08/11] object API: rename hash_object_file_literally() to write_*()
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                     ` (6 preceding siblings ...)
  2022-02-04 13:51   ` [PATCH v2 07/11] object-file API: split up and simplify check_object_signature() Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51   ` Ævar Arnfjörð Bjarmason
  2022-02-04 13:51   ` [PATCH v2 09/11] object-file API: have hash_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Before 0c3db67cc81 (hash-object --literally: fix buffer overrun with
extra-long object type, 2015-05-04) the hash-object code being changed
here called write_sha1_file() to both hash and write a loose
object. Before that we'd use hash_sha1_file() to if "-w" wasn't
provided, and otherwise call write_sha1_file().

Now we'll always call the same function for both writing. Let's rename
it from hash_*_literally() to write_*_literally(). Even though the
write_*() might not actually write if HASH_WRITE_OBJECT isn't in
"flags", having it be more similar to write_object_file_flags() than
hash_object_file(), but carrying a name that would suggest that it's a
variant of the latter is confusing.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/hash-object.c | 2 +-
 object-file.c         | 6 +++---
 object-store.h        | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index c7b3ad74c60..f4cbd9c4ae3 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -25,7 +25,7 @@ static int hash_literally(struct object_id *oid, int fd, const char *type, unsig
 	if (strbuf_read(&buf, fd, 4096) < 0)
 		ret = -1;
 	else
-		ret = hash_object_file_literally(buf.buf, buf.len, type, oid,
+		ret = write_object_file_literally(buf.buf, buf.len, type, oid,
 						 flags);
 	strbuf_release(&buf);
 	return ret;
diff --git a/object-file.c b/object-file.c
index 937a107c5ab..a68af32308e 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2027,9 +2027,9 @@ int write_object_file_flags(const void *buf, unsigned long len,
 	return write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags);
 }
 
-int hash_object_file_literally(const void *buf, unsigned long len,
-			       const char *type, struct object_id *oid,
-			       unsigned flags)
+int write_object_file_literally(const void *buf, unsigned long len,
+				const char *type, struct object_id *oid,
+				unsigned flags)
 {
 	char *header;
 	int hdrlen, status = 0;
diff --git a/object-store.h b/object-store.h
index eab1e2a967e..29169d117f7 100644
--- a/object-store.h
+++ b/object-store.h
@@ -258,9 +258,9 @@ static inline int write_object_file(const void *buf, unsigned long len,
 	return write_object_file_flags(buf, len, type, oid, 0);
 }
 
-int hash_object_file_literally(const void *buf, unsigned long len,
-			       const char *type, struct object_id *oid,
-			       unsigned flags);
+int write_object_file_literally(const void *buf, unsigned long len,
+				const char *type, struct object_id *oid,
+				unsigned flags);
 
 /*
  * Add an object file to the in-memory object store, without writing it
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v2 09/11] object-file API: have hash_object_file() take "enum object_type"
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                     ` (7 preceding siblings ...)
  2022-02-04 13:51   ` [PATCH v2 08/11] object API: rename hash_object_file_literally() to write_*() Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51   ` Ævar Arnfjörð Bjarmason
  2022-02-04 13:51   ` [PATCH v2 10/11] object-file.c: add a literal version of write_object_file_prepare() Ævar Arnfjörð Bjarmason
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the hash_object_file() function to take an "enum
object_type".

Since a preceding commit all of its callers are passing either
"{commit,tree,blob,tag}_type", or the result of a call to type_name(),
the parse_object() caller that would pass NULL is now using
stream_object_signature().

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 apply.c                  |  4 ++--
 builtin/fast-export.c    |  2 +-
 builtin/index-pack.c     |  4 ++--
 builtin/mktag.c          |  2 +-
 builtin/replace.c        |  2 +-
 builtin/unpack-objects.c |  2 +-
 cache-tree.c             |  6 +++---
 cache.h                  |  3 ++-
 convert.c                |  2 +-
 diffcore-rename.c        |  2 +-
 dir.c                    |  2 +-
 log-tree.c               |  2 +-
 object-file.c            | 35 +++++++++++++++++++++--------------
 object-store.h           |  2 +-
 object.c                 |  3 +--
 pack-check.c             |  2 +-
 16 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/apply.c b/apply.c
index e82a7c30f01..8513755e254 100644
--- a/apply.c
+++ b/apply.c
@@ -3157,7 +3157,7 @@ static int apply_binary(struct apply_state *state,
 		 * See if the old one matches what the patch
 		 * applies to.
 		 */
-		hash_object_file(the_hash_algo, img->buf, img->len, blob_type,
+		hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB,
 				 &oid);
 		if (strcmp(oid_to_hex(&oid), patch->old_oid_prefix))
 			return error(_("the patch applies to '%s' (%s), "
@@ -3203,7 +3203,7 @@ static int apply_binary(struct apply_state *state,
 				     name);
 
 		/* verify that the result matches */
-		hash_object_file(the_hash_algo, img->buf, img->len, blob_type,
+		hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB,
 				 &oid);
 		if (strcmp(oid_to_hex(&oid), patch->new_oid_prefix))
 			return error(_("binary patch to '%s' creates incorrect result (expecting %s, got %s)"),
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 1878ec34960..187985666e7 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -300,7 +300,7 @@ static void export_blob(const struct object_id *oid)
 		if (!buf)
 			die("could not read blob %s", oid_to_hex(oid));
 		if (!check_object_signature(the_repository, oid, buf, size,
-					    type_name(type)))
+					    type))
 			die("oid mismatch in blob %s", oid_to_hex(oid));
 		object = parse_object_buffer(the_repository, oid, type,
 					     size, buf, &eaten);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index eaa7b6698d1..1c0d3971074 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -970,7 +970,7 @@ static struct base_data *resolve_delta(struct object_entry *delta_obj,
 	if (!result_data)
 		bad_object(delta_obj->idx.offset, _("failed to apply delta"));
 	hash_object_file(the_hash_algo, result_data, result_size,
-			 type_name(delta_obj->real_type), &delta_obj->idx.oid);
+			 delta_obj->real_type, &delta_obj->idx.oid);
 	sha1_object(result_data, NULL, result_size, delta_obj->real_type,
 		    &delta_obj->idx.oid);
 
@@ -1413,7 +1413,7 @@ static void fix_unresolved_deltas(struct hashfile *f)
 			continue;
 
 		if (!check_object_signature(the_repository, &d->oid, data,
-					    size, type_name(type)))
+					    size, type))
 			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
 
 		/*
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 1282e8cd9e2..bebc88faed0 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -62,7 +62,7 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 
 	repl = lookup_replace_object(the_repository, tagged_oid);
 	ret = !check_object_signature(the_repository, repl, buffer, size,
-				      type_name(*tagged_type));
+				     *tagged_type);
 	free(buffer);
 
 	return ret;
diff --git a/builtin/replace.c b/builtin/replace.c
index 995ca683302..53a3b246570 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -409,7 +409,7 @@ static int check_one_mergetag(struct commit *commit,
 	int i;
 
 	hash_object_file(the_hash_algo, extra->value, extra->len,
-			 type_name(OBJ_TAG), &tag_oid);
+			 OBJ_TAG, &tag_oid);
 	tag = lookup_tag(the_repository, &tag_oid);
 	if (!tag)
 		return error(_("bad mergetag in commit '%s'"), ref);
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 808041551fd..dbeb0680a58 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -266,7 +266,7 @@ static void write_object(unsigned nr, enum object_type type,
 	} else {
 		struct object *obj;
 		int eaten;
-		hash_object_file(the_hash_algo, buf, size, type_name(type),
+		hash_object_file(the_hash_algo, buf, size, type,
 				 &obj_list[nr].oid);
 		added_object(nr, type, buf, size);
 		obj = parse_object_buffer(the_repository, &obj_list[nr].oid,
diff --git a/cache-tree.c b/cache-tree.c
index fdbbd191d22..6752f69d515 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -432,14 +432,14 @@ static int update_one(struct cache_tree *it,
 	if (repair) {
 		struct object_id oid;
 		hash_object_file(the_hash_algo, buffer.buf, buffer.len,
-				 tree_type, &oid);
+				 OBJ_TREE, &oid);
 		if (has_object_file_with_flags(&oid, OBJECT_INFO_SKIP_FETCH_OBJECT))
 			oidcpy(&it->oid, &oid);
 		else
 			to_invalidate = 1;
 	} else if (dryrun) {
 		hash_object_file(the_hash_algo, buffer.buf, buffer.len,
-				 tree_type, &it->oid);
+				 OBJ_TREE, &it->oid);
 	} else if (write_object_file_flags(buffer.buf, buffer.len, OBJ_TREE,
 					   &it->oid, flags & WRITE_TREE_SILENT
 					   ? HASH_SILENT : 0)) {
@@ -948,7 +948,7 @@ static int verify_one(struct repository *r,
 		strbuf_addf(&tree_buf, "%o %.*s%c", mode, entlen, name, '\0');
 		strbuf_add(&tree_buf, oid->hash, r->hash_algo->rawsz);
 	}
-	hash_object_file(r->hash_algo, tree_buf.buf, tree_buf.len, tree_type,
+	hash_object_file(r->hash_algo, tree_buf.buf, tree_buf.len, OBJ_TREE,
 			 &new_oid);
 	if (!oideq(&new_oid, &it->oid))
 		BUG("cache-tree for path %.*s does not match. "
diff --git a/cache.h b/cache.h
index 5a13bbfd904..42761bb12cb 100644
--- a/cache.h
+++ b/cache.h
@@ -1327,7 +1327,8 @@ int parse_loose_header(const char *hdr, struct object_info *oi);
  * except that negative values might also indicate a generic error.
  */
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *buf, unsigned long size, const char *type);
+			   void *map, unsigned long size,
+			   enum object_type type);
 
 /**
  * A streaming version of check_object_signature().
diff --git a/convert.c b/convert.c
index df7186bd813..d88072fe320 100644
--- a/convert.c
+++ b/convert.c
@@ -1159,7 +1159,7 @@ static int ident_to_worktree(const char *src, size_t len,
 	/* are we "faking" in place editing ? */
 	if (src == buf->buf)
 		to_free = strbuf_detach(buf, NULL);
-	hash_object_file(the_hash_algo, src, len, "blob", &oid);
+	hash_object_file(the_hash_algo, src, len, OBJ_BLOB, &oid);
 
 	strbuf_grow(buf, len + cnt * (the_hash_algo->hexsz + 3));
 	for (;;) {
diff --git a/diffcore-rename.c b/diffcore-rename.c
index bebd4ed6a42..c0422d9e709 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -261,7 +261,7 @@ static unsigned int hash_filespec(struct repository *r,
 		if (diff_populate_filespec(r, filespec, NULL))
 			return 0;
 		hash_object_file(r->hash_algo, filespec->data, filespec->size,
-				 "blob", &filespec->oid);
+				 OBJ_BLOB, &filespec->oid);
 	}
 	return oidhash(&filespec->oid);
 }
diff --git a/dir.c b/dir.c
index d91295f2bcd..5674e8a6256 100644
--- a/dir.c
+++ b/dir.c
@@ -1113,7 +1113,7 @@ static int add_patterns(const char *fname, const char *base, int baselen,
 				       &istate->cache[pos]->oid);
 			else
 				hash_object_file(the_hash_algo, buf, size,
-						 "blob", &oid_stat->oid);
+						 OBJ_BLOB, &oid_stat->oid);
 			fill_stat_data(&oid_stat->stat, &st);
 			oid_stat->valid = 1;
 		}
diff --git a/log-tree.c b/log-tree.c
index d3e7a40b648..27a5b0bd61a 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -561,7 +561,7 @@ static int show_one_mergetag(struct commit *commit,
 	struct strbuf signature = STRBUF_INIT;
 
 	hash_object_file(the_hash_algo, extra->value, extra->len,
-			 type_name(OBJ_TAG), &oid);
+			 OBJ_TAG, &oid);
 	tag = lookup_tag(the_repository, &oid);
 	if (!tag)
 		return -1; /* error message already given */
diff --git a/object-file.c b/object-file.c
index a68af32308e..97a3493f5fb 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1067,7 +1067,8 @@ int format_object_header(char *str, size_t size, enum object_type type,
 }
 
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *buf, unsigned long size, const char *type)
+			   void *buf, unsigned long size,
+			   enum object_type type)
 {
 	struct object_id real_oid;
 
@@ -1676,7 +1677,7 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
 {
 	struct cached_object *co;
 
-	hash_object_file(the_hash_algo, buf, len, type_name(type), oid);
+	hash_object_file(the_hash_algo, buf, len, type, oid);
 	if (has_object_file_with_flags(oid, OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT) ||
 	    find_cached_object(oid))
 		return 0;
@@ -1850,15 +1851,23 @@ static int write_buffer(int fd, const void *buf, size_t len)
 	return 0;
 }
 
-void hash_object_file(const struct git_hash_algo *algo, const void *buf,
-		     unsigned long len, const char *type,
-		     struct object_id *oid)
+static void hash_object_file_literally(const struct git_hash_algo *algo,
+				       const void *buf, unsigned long len,
+				       const char *type, struct object_id *oid)
 {
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen = sizeof(hdr);
+
 	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
 }
 
+void hash_object_file(const struct git_hash_algo *algo, const void *buf,
+		      unsigned long len, enum object_type type,
+		      struct object_id *oid)
+{
+	hash_object_file_literally(algo, buf, len, type_name(type), oid);
+}
+
 /* Finalize a file on disk, and close it. */
 static void close_loose_object(int fd)
 {
@@ -2161,9 +2170,7 @@ static int index_mem(struct index_state *istate,
 	if (write_object)
 		ret = write_object_file(buf, size, type, oid);
 	else
-		hash_object_file(the_hash_algo, buf, size, type_name(type),
-				 oid);
-
+		hash_object_file(the_hash_algo, buf, size, type, oid);
 	if (re_allocated)
 		free(buf);
 	return ret;
@@ -2189,8 +2196,8 @@ static int index_stream_convert_blob(struct index_state *istate,
 		ret = write_object_file(sbuf.buf, sbuf.len, OBJ_BLOB,
 					oid);
 	else
-		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
-				 type_name(OBJ_BLOB), oid);
+		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len, OBJ_BLOB,
+				 oid);
 	strbuf_release(&sbuf);
 	return ret;
 }
@@ -2309,7 +2316,7 @@ int index_path(struct index_state *istate, struct object_id *oid,
 			return error_errno("readlink(\"%s\")", path);
 		if (!(flags & HASH_WRITE_OBJECT))
 			hash_object_file(the_hash_algo, sb.buf, sb.len,
-					 blob_type, oid);
+					 OBJ_BLOB, oid);
 		else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid))
 			rc = error(_("%s: failed to insert into database"), path);
 		strbuf_release(&sb);
@@ -2615,9 +2622,9 @@ int read_loose_object(const char *path,
 			goto out;
 		}
 
-		hash_object_file(the_repository->hash_algo,
-				 *contents, *size, oi->type_name->buf,
-				 real_oid);
+		hash_object_file_literally(the_repository->hash_algo,
+					   *contents, *size,
+					   oi->type_name->buf, real_oid);
 		if (!oideq(expected_oid, real_oid))
 			goto out;
 	}
diff --git a/object-store.h b/object-store.h
index 29169d117f7..bd2322ed8ce 100644
--- a/object-store.h
+++ b/object-store.h
@@ -246,7 +246,7 @@ static inline void *repo_read_object_file(struct repository *r,
 int oid_object_info(struct repository *r, const struct object_id *, unsigned long *);
 
 void hash_object_file(const struct git_hash_algo *algo, const void *buf,
-		      unsigned long len, const char *type,
+		      unsigned long len, enum object_type type,
 		      struct object_id *oid);
 
 int write_object_file_flags(const void *buf, unsigned long len,
diff --git a/object.c b/object.c
index b3f9cd5c8cd..2cc9edb7512 100644
--- a/object.c
+++ b/object.c
@@ -289,8 +289,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
 
 	buffer = repo_read_object_file(r, oid, &type, &size);
 	if (buffer) {
-		if (!check_object_signature(r, repl, buffer, size,
-					    type_name(type))) {
+		if (!check_object_signature(r, repl, buffer, size, type)) {
 			free(buffer);
 			error(_("hash mismatch %s"), oid_to_hex(repl));
 			return NULL;
diff --git a/pack-check.c b/pack-check.c
index 4a27e77704b..f1df16ef9a7 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -143,7 +143,7 @@ static int verify_packfile(struct repository *r,
 				    oid_to_hex(&oid), p->pack_name,
 				    (uintmax_t)entries[i].offset);
 		else if (data && !check_object_signature(r, &oid, data, size,
-							 type_name(type)))
+							 type))
 			err = error("packed %s from %s is corrupt",
 				    oid_to_hex(&oid), p->pack_name);
 		else if (!data && !stream_object_signature(r, &oid))
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v2 10/11] object-file.c: add a literal version of write_object_file_prepare()
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                     ` (8 preceding siblings ...)
  2022-02-04 13:51   ` [PATCH v2 09/11] object-file API: have hash_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51   ` Ævar Arnfjörð Bjarmason
  2022-02-04 13:51   ` [PATCH v2 11/11] object-file API: pass an enum to read_object_with_reference() Ævar Arnfjörð Bjarmason
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Split off a *_literally() variant of the write_object_file_prepare()
function. To do this create a new "hash_object_body()" static helper.

We now defer the type_name() call until the very last moment in
format_object_header() for those callers that aren't "hash-object
--literally".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 object-file.c | 39 +++++++++++++++++++++++++++++----------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/object-file.c b/object-file.c
index 97a3493f5fb..cba33b25197 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1784,21 +1784,40 @@ void *read_object_with_reference(struct repository *r,
 	}
 }
 
+static void hash_object_body(const struct git_hash_algo *algo, git_hash_ctx *c,
+			     const void *buf, unsigned long len,
+			     struct object_id *oid,
+			     char *hdr, int *hdrlen)
+{
+	algo->init_fn(c);
+	algo->update_fn(c, hdr, *hdrlen);
+	algo->update_fn(c, buf, len);
+	algo->final_oid_fn(oid, c);
+}
+
 static void write_object_file_prepare(const struct git_hash_algo *algo,
 				      const void *buf, unsigned long len,
-				      const char *type, struct object_id *oid,
+				      enum object_type type, struct object_id *oid,
 				      char *hdr, int *hdrlen)
 {
 	git_hash_ctx c;
 
 	/* Generate the header */
-	*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
+	*hdrlen = format_object_header(hdr, *hdrlen, type, len);
 
 	/* Sha1.. */
-	algo->init_fn(&c);
-	algo->update_fn(&c, hdr, *hdrlen);
-	algo->update_fn(&c, buf, len);
-	algo->final_oid_fn(oid, &c);
+	hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen);
+}
+
+static void write_object_file_prepare_literally(const struct git_hash_algo *algo,
+				      const void *buf, unsigned long len,
+				      const char *type, struct object_id *oid,
+				      char *hdr, int *hdrlen)
+{
+	git_hash_ctx c;
+
+	*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
+	hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen);
 }
 
 /*
@@ -1858,7 +1877,7 @@ static void hash_object_file_literally(const struct git_hash_algo *algo,
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen = sizeof(hdr);
 
-	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
+	write_object_file_prepare_literally(algo, buf, len, type, oid, hdr, &hdrlen);
 }
 
 void hash_object_file(const struct git_hash_algo *algo, const void *buf,
@@ -2029,7 +2048,7 @@ int write_object_file_flags(const void *buf, unsigned long len,
 	/* Normally if we have it in the pack then we do not bother writing
 	 * it out into .git/objects/??/?{38} file.
 	 */
-	write_object_file_prepare(the_hash_algo, buf, len, type_name(type), oid, hdr,
+	write_object_file_prepare(the_hash_algo, buf, len, type, oid, hdr,
 				  &hdrlen);
 	if (freshen_packed_object(oid) || freshen_loose_object(oid))
 		return 0;
@@ -2046,8 +2065,8 @@ int write_object_file_literally(const void *buf, unsigned long len,
 	/* type string, SP, %lu of the length plus NUL must fit this */
 	hdrlen = strlen(type) + MAX_HEADER_LEN;
 	header = xmalloc(hdrlen);
-	write_object_file_prepare(the_hash_algo, buf, len, type, oid, header,
-				  &hdrlen);
+	write_object_file_prepare_literally(the_hash_algo, buf, len, type,
+					    oid, header, &hdrlen);
 
 	if (!(flags & HASH_WRITE_OBJECT))
 		goto cleanup;
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v2 11/11] object-file API: pass an enum to read_object_with_reference()
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                     ` (9 preceding siblings ...)
  2022-02-04 13:51   ` [PATCH v2 10/11] object-file.c: add a literal version of write_object_file_prepare() Ævar Arnfjörð Bjarmason
@ 2022-02-04 13:51   ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 13:51 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the read_object_with_reference() function to take an "enum
object_type". It was not prepared to handle an arbitrary "const
char *type", as it was itself calling type_from_string().

Let's change the only caller that passes in user data to use
type_from_string(), and convert the rest to use e.g. "OBJ_TREE"
instead of "tree_type".

The "cat-file" caller is not on the codepath that
handles"--allow-unknown", so the type_from_string() there is safe. Its
use of type_from_string() doesn't functionally differ from that of the
pre-image.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/cat-file.c     | 11 +++++++----
 builtin/fast-import.c  |  6 +++---
 builtin/grep.c         |  4 ++--
 builtin/pack-objects.c |  2 +-
 cache.h                |  2 +-
 object-file.c          |  5 ++---
 tree-walk.c            |  6 +++---
 7 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index d94050e6c18..3c5bc505e0a 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -154,7 +154,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 		break;
 
 	case 0:
-		if (type_from_string(exp_type) == OBJ_BLOB) {
+	{
+		enum object_type exp_type_id = type_from_string(exp_type);
+
+		if (exp_type_id == OBJ_BLOB) {
 			struct object_id blob_oid;
 			if (oid_object_info(the_repository, &oid, NULL) == OBJ_TAG) {
 				char *buffer = read_object_file(&oid, &type,
@@ -176,10 +179,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 			 * fall-back to the usual case.
 			 */
 		}
-		buf = read_object_with_reference(the_repository,
-						 &oid, exp_type, &size, NULL);
+		buf = read_object_with_reference(the_repository, &oid,
+						 exp_type_id, &size, NULL);
 		break;
-
+	}
 	default:
 		die("git cat-file: unknown option: %s", exp_type);
 	}
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 123df7d9a53..c52e807f56e 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -2483,7 +2483,7 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa
 		unsigned long size;
 		char *buf = read_object_with_reference(the_repository,
 						       &commit_oid,
-						       commit_type, &size,
+						       OBJ_COMMIT, &size,
 						       &commit_oid);
 		if (!buf || size < the_hash_algo->hexsz + 6)
 			die("Not a valid commit: %s", p);
@@ -2555,7 +2555,7 @@ static void parse_from_existing(struct branch *b)
 		char *buf;
 
 		buf = read_object_with_reference(the_repository,
-						 &b->oid, commit_type, &size,
+						 &b->oid, OBJ_COMMIT, &size,
 						 &b->oid);
 		parse_from_commit(b, buf, size);
 		free(buf);
@@ -2651,7 +2651,7 @@ static struct hash_list *parse_merge(unsigned int *count)
 			unsigned long size;
 			char *buf = read_object_with_reference(the_repository,
 							       &n->oid,
-							       commit_type,
+							       OBJ_COMMIT,
 							       &size, &n->oid);
 			if (!buf || size < the_hash_algo->hexsz + 6)
 				die("Not a valid commit: %s", from);
diff --git a/builtin/grep.c b/builtin/grep.c
index 9e34a820ad4..75e07b5623a 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -482,7 +482,7 @@ static int grep_submodule(struct grep_opt *opt,
 		object_type = oid_object_info(subrepo, oid, NULL);
 		obj_read_unlock();
 		data = read_object_with_reference(subrepo,
-						  oid, tree_type,
+						  oid, OBJ_TREE,
 						  &size, NULL);
 		if (!data)
 			die(_("unable to read tree (%s)"), oid_to_hex(oid));
@@ -651,7 +651,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
 		int hit, len;
 
 		data = read_object_with_reference(opt->repo,
-						  &obj->oid, tree_type,
+						  &obj->oid, OBJ_TREE,
 						  &size, NULL);
 		if (!data)
 			die(_("unable to read tree (%s)"), oid_to_hex(&obj->oid));
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index ba2006f2212..c4df3df3141 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1802,7 +1802,7 @@ static void add_preferred_base(struct object_id *oid)
 		return;
 
 	data = read_object_with_reference(the_repository, oid,
-					  tree_type, &size, &tree_oid);
+					  OBJ_TREE, &size, &tree_oid);
 	if (!data)
 		return;
 
diff --git a/cache.h b/cache.h
index 42761bb12cb..357f4cb642f 100644
--- a/cache.h
+++ b/cache.h
@@ -1561,7 +1561,7 @@ int cache_name_stage_compare(const char *name1, int len1, int stage1, const char
 
 void *read_object_with_reference(struct repository *r,
 				 const struct object_id *oid,
-				 const char *required_type,
+				 enum object_type required_type,
 				 unsigned long *size,
 				 struct object_id *oid_ret);
 
diff --git a/object-file.c b/object-file.c
index cba33b25197..5c9525479c2 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1737,16 +1737,15 @@ void *read_object_file_extended(struct repository *r,
 
 void *read_object_with_reference(struct repository *r,
 				 const struct object_id *oid,
-				 const char *required_type_name,
+				 enum object_type required_type,
 				 unsigned long *size,
 				 struct object_id *actual_oid_return)
 {
-	enum object_type type, required_type;
+	enum object_type type;
 	void *buffer;
 	unsigned long isize;
 	struct object_id actual_oid;
 
-	required_type = type_from_string(required_type_name);
 	oidcpy(&actual_oid, oid);
 	while (1) {
 		int ref_length = -1;
diff --git a/tree-walk.c b/tree-walk.c
index 3a94959d64a..506234b4b81 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -89,7 +89,7 @@ void *fill_tree_descriptor(struct repository *r,
 	void *buf = NULL;
 
 	if (oid) {
-		buf = read_object_with_reference(r, oid, tree_type, &size, NULL);
+		buf = read_object_with_reference(r, oid, OBJ_TREE, &size, NULL);
 		if (!buf)
 			die("unable to read tree %s", oid_to_hex(oid));
 	}
@@ -605,7 +605,7 @@ int get_tree_entry(struct repository *r,
 	unsigned long size;
 	struct object_id root;
 
-	tree = read_object_with_reference(r, tree_oid, tree_type, &size, &root);
+	tree = read_object_with_reference(r, tree_oid, OBJ_TREE, &size, &root);
 	if (!tree)
 		return -1;
 
@@ -677,7 +677,7 @@ enum get_oid_result get_tree_entry_follow_symlinks(struct repository *r,
 			unsigned long size;
 			tree = read_object_with_reference(r,
 							  &current_tree_oid,
-							  tree_type, &size,
+							  OBJ_TREE, &size,
 							  &root);
 			if (!tree)
 				goto done;
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 04/11] object-file API: have write_object_file() take "enum object_type"
  2022-02-04 13:51   ` [PATCH v2 04/11] object-file API: have write_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
@ 2022-02-04 20:52     ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2022-02-04 20:52 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Han Xin, Jiang Xin, René Scharfe, Derrick Stolee

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> diff --git a/builtin/notes.c b/builtin/notes.c
> index 05d60483e82..d81acaeaf78 100644
> --- a/builtin/notes.c
> +++ b/builtin/notes.c
> @@ -199,9 +199,8 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
>  
>  static void write_note_data(struct note_data *d, struct object_id *oid)
>  {
> -	if (write_object_file(d->buf.buf, d->buf.len, blob_type, oid)) {
> +	if (write_object_file(d->buf.buf, d->buf.len, OBJ_BLOB, oid)) {
>  		int status = die_message(_("unable to write note object"));
> -
>  		if (d->edit_path)

Unrelated change here.  It would be OK if it were an improvement,
but it is not X-<.

Everything else in this change looked sensible.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 05/11] object API: correct "buf" v.s. "map" mismatch in *.c and *.h
  2022-02-04 13:51   ` [PATCH v2 05/11] object API: correct "buf" v.s. "map" mismatch in *.c and *.h Ævar Arnfjörð Bjarmason
@ 2022-02-04 20:54     ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2022-02-04 20:54 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Han Xin, Jiang Xin, René Scharfe, Derrick Stolee

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change the name of the second argument to check_object_signature() to
> be "buf" in object-file.c, making it consistent with the prototype in
> cache..h

Double dot X-<.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v2 06/11] object API: make check_object_signature() oideq()-like, move docs
  2022-02-04 13:51   ` [PATCH v2 06/11] object API: make check_object_signature() oideq()-like, move docs Ævar Arnfjörð Bjarmason
@ 2022-02-04 21:15     ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2022-02-04 21:15 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Han Xin, Jiang Xin, René Scharfe, Derrick Stolee

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Make the return value of check_object_signature() behave like oideq()
> and memcmp() instead of returning negative values on failure.

First of all, oideq() and memcmp() behave completely oppositely to
each other.  When given two same things, eq() says "true" and cmp()
says 0.  They use the opposite polarity.  Which one do you want?

I am not enthused to see a function that used to signal success with
0 and failure with a negative value to suddenly start returning 1
for "they are identical" and 0 for "they are not the same", without
changing its name or parameters to help compilers catch new call
sites that still expect the old behaviour (hence can use "ret < 0",
and "ret" interchangeably to check for "failure - the given data
does not hash to the object name").

> This reduces the boilerplate required when calling the function, and
> makes the calling code behave the same is if though we'd called
> oideq(), which is basically what we're doing here. We already had some
> callers using "f() < 0", with others using "!f()". Instead of
> declaring the latter a bug let's convert all callers to it.
>
> It is unfortunate that there's also cases where we "return -1" on
> various errors, and we can't tell those apart from the expected OID
> being less than the real OID, but this was the case already.

Well, it is not checking "less than" to begin with, no?  The point
of calling this function is to see if the "object_signature" (aka
"hash") is correct for the object data we have, and yield yes/no (or
success or failure) answer.  If we encountered an error while trying
to compute that answer, well, we failed to ensure that the hash
matches the contents, so it is reasonable to say "no, it does not
match".

> This change is rather dangerous stand-alone as we're changing the
> return semantics, but not changing the prototype.

Yes, if you know it, why do it and have reviewers spend their cycles?

If the function is renamed so that its name ends with "eq" or
"matches" (e.g. object_signature_matches()), such a change may be
justified, though.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface
  2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                     ` (10 preceding siblings ...)
  2022-02-04 13:51   ` [PATCH v2 11/11] object-file API: pass an enum to read_object_with_reference() Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48   ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 01/12] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
                       ` (11 more replies)
  11 siblings, 12 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

See the v2 for a summary and goals:
https://lore.kernel.org/git/cover-v2-00.11-00000000000-20220204T135005Z-avarab@gmail.com/

This early re-roll addresses Junio's comments on it so far, i.e. the
minor whitespace/typos, and then having the interface retain the "if
(f() < 0)" interface.

The reason I'd changed it initially was because the callers used a
mixture of "if (f())" and "if (f() < 0)", but let's just keep it as it
is, with a couple of new patches to fix the existing callers to use
"if (f() < 0)" consistently.

A corresponding re-roll to the topic that depends on this one isn't
needed, as this part of the API wasn't used by it. For that topic see:
https://lore.kernel.org/git/cover-v10-0.6-00000000000-20220204T135538Z-avarab@gmail.com/

Ævar Arnfjörð Bjarmason (12):
  object-file.c: split up declaration of unrelated variables
  object-file API: return "void", not "int" from hash_object_file()
  object-file API: add a format_object_header() function
  object-file API: have write_object_file() take "enum object_type"
  object API: correct "buf" v.s. "map" mismatch in *.c and *.h
  object API docs: move check_object_signature() docs to cache.h
  object API users + docs: check <0, not !0 with
    check_object_signature()
  object-file API: split up and simplify check_object_signature()
  object API: rename hash_object_file_literally() to write_*()
  object-file API: have hash_object_file() take "enum object_type"
  object-file.c: add a literal version of write_object_file_prepare()
  object-file API: pass an enum to read_object_with_reference()

 apply.c                  |  12 ++--
 builtin/cat-file.c       |  11 +--
 builtin/checkout.c       |   2 +-
 builtin/fast-export.c    |   2 +-
 builtin/fast-import.c    |  12 ++--
 builtin/grep.c           |   4 +-
 builtin/hash-object.c    |   2 +-
 builtin/index-pack.c     |  10 ++-
 builtin/mktag.c          |   9 ++-
 builtin/mktree.c         |   2 +-
 builtin/notes.c          |   2 +-
 builtin/pack-objects.c   |   2 +-
 builtin/receive-pack.c   |   2 +-
 builtin/replace.c        |   4 +-
 builtin/tag.c            |   2 +-
 builtin/unpack-objects.c |   8 +--
 bulk-checkin.c           |   4 +-
 cache-tree.c             |   8 +--
 cache.h                  |  20 +++++-
 commit.c                 |   2 +-
 convert.c                |   2 +-
 diffcore-rename.c        |   2 +-
 dir.c                    |   2 +-
 http-push.c              |   2 +-
 log-tree.c               |   2 +-
 match-trees.c            |   2 +-
 merge-ort.c              |   4 +-
 merge-recursive.c        |   2 +-
 notes-cache.c            |   2 +-
 notes.c                  |   8 +--
 object-file.c            | 145 +++++++++++++++++++++++++--------------
 object-store.h           |  24 ++++---
 object.c                 |   5 +-
 pack-check.c             |   9 ++-
 read-cache.c             |   2 +-
 tree-walk.c              |   6 +-
 36 files changed, 202 insertions(+), 137 deletions(-)

Range-diff against v2:
 -:  ----------- >  1:  53334bc970a object-file.c: split up declaration of unrelated variables
 -:  ----------- >  2:  5ba49778ac1 object-file API: return "void", not "int" from hash_object_file()
 -:  ----------- >  3:  92fd020d199 object-file API: add a format_object_header() function
 1:  d259f901114 !  4:  795ac3dea2a object-file API: have write_object_file() take "enum object_type"
    @@ builtin/notes.c: static void prepare_note_data(const struct object_id *object, s
     -	if (write_object_file(d->buf.buf, d->buf.len, blob_type, oid)) {
     +	if (write_object_file(d->buf.buf, d->buf.len, OBJ_BLOB, oid)) {
      		int status = die_message(_("unable to write note object"));
    --
    + 
      		if (d->edit_path)
    - 			die_message(_("the note contents have been left in %s"),
    - 				    d->edit_path);
     
      ## builtin/receive-pack.c ##
     @@ builtin/receive-pack.c: static void prepare_push_cert_sha1(struct child_process *proc)
 2:  207aec4eb64 !  5:  6faf46277b5 object API: correct "buf" v.s. "map" mismatch in *.c and *.h
    @@ Commit message
     
         Change the name of the second argument to check_object_signature() to
         be "buf" in object-file.c, making it consistent with the prototype in
    -    cache..h
    +    cache.h
     
         This fixes an inconsistency that's been with us since 2ade9340262 (Add
         "check_sha1_signature()" helper function, 2005-04-08), and makes a
 3:  636a647ac51 !  6:  bdddaa3648f object API: make check_object_signature() oideq()-like, move docs
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    object API: make check_object_signature() oideq()-like, move docs
    +    object API docs: move check_object_signature() docs to cache.h
     
    -    Make the return value of check_object_signature() behave like oideq()
    -    and memcmp() instead of returning negative values on failure.
    -
    -    This reduces the boilerplate required when calling the function, and
    -    makes the calling code behave the same is if though we'd called
    -    oideq(), which is basically what we're doing here. We already had some
    -    callers using "f() < 0", with others using "!f()". Instead of
    -    declaring the latter a bug let's convert all callers to it.
    -
    -    It is unfortunate that there's also cases where we "return -1" on
    -    various errors, and we can't tell those apart from the expected OID
    -    being less than the real OID, but this was the case already.
    -
    -    This change is rather dangerous stand-alone as we're changing the
    -    return semantics, but not changing the prototype. Therefore any
    -    out-of-tree code rebased on this change would start doing the opposite
    -    of what it was meant to do. In a subsequent commit we'll make that a
    -    non-issue by changing the signature of the function, ensuring that the
    -    compiler will catch any such misuse.
    -
    -    While we're at it let's re-flow some of the callers to wrap at 79
    -    characters, and move the API documentation to cache.h, where the
    -    prototype of this function lives.
    +    Move the API documentation for check_object_signature() to cache.h,
    +    where its prototype is declared. This is in preparation for adding a
    +    companion function.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    - ## builtin/fast-export.c ##
    -@@ builtin/fast-export.c: static void export_blob(const struct object_id *oid)
    - 		buf = read_object_file(oid, &type, &size);
    - 		if (!buf)
    - 			die("could not read blob %s", oid_to_hex(oid));
    --		if (check_object_signature(the_repository, oid, buf, size,
    --					   type_name(type), NULL) < 0)
    -+		if (!check_object_signature(the_repository, oid, buf, size,
    -+					    type_name(type), NULL))
    - 			die("oid mismatch in blob %s", oid_to_hex(oid));
    - 		object = parse_object_buffer(the_repository, oid, type,
    - 					     size, buf, &eaten);
    -
    - ## builtin/index-pack.c ##
    -@@ builtin/index-pack.c: static void fix_unresolved_deltas(struct hashfile *f)
    - 		if (!data)
    - 			continue;
    - 
    --		if (check_object_signature(the_repository, &d->oid,
    --					   data, size,
    --					   type_name(type), NULL))
    -+		if (!check_object_signature(the_repository, &d->oid, data,
    -+					    size, type_name(type), NULL))
    - 			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
    - 
    - 		/*
    -
    - ## builtin/mktag.c ##
    -@@ builtin/mktag.c: static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
    - 		    type_name(*tagged_type), type_name(type));
    - 
    - 	repl = lookup_replace_object(the_repository, tagged_oid);
    --	ret = check_object_signature(the_repository, repl,
    --				     buffer, size, type_name(*tagged_type),
    --				     NULL);
    -+	ret = !check_object_signature(the_repository, repl, buffer, size,
    -+				      type_name(*tagged_type), NULL);
    - 	free(buffer);
    - 
    - 	return ret;
    -
      ## cache.h ##
     @@ cache.h: enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
      struct object_info;
    @@ cache.h: enum unpack_loose_header_result unpack_loose_header(git_zstream *stream
     + * object name actually matches "oid" to detect object corruption.
     + * With "buf" == NULL, try reading the object named with "oid" using
     + * the streaming interface and rehash it to do the same.
    -+ *
    -+ * Treat the return value like oideq() (which is like memcmp()),
    -+ * except that negative values might also indicate a generic error.
     + */
      int check_object_signature(struct repository *r, const struct object_id *oid,
      			   void *buf, unsigned long size, const char *type,
    @@ object-file.c: int format_object_header(char *str, size_t size, enum object_type
      int check_object_signature(struct repository *r, const struct object_id *oid,
      			   void *buf, unsigned long size, const char *type,
      			   struct object_id *real_oidp)
    -@@ object-file.c: int check_object_signature(struct repository *r, const struct object_id *oid,
    - 
    - 	if (buf) {
    - 		hash_object_file(r->hash_algo, buf, size, type, real_oid);
    --		return !oideq(oid, real_oid) ? -1 : 0;
    -+		return oideq(oid, real_oid);
    - 	}
    - 
    - 	st = open_istream(r, oid, &obj_type, &size, NULL);
    -@@ object-file.c: int check_object_signature(struct repository *r, const struct object_id *oid,
    - 	}
    - 	r->hash_algo->final_oid_fn(real_oid, &c);
    - 	close_istream(st);
    --	return !oideq(oid, real_oid) ? -1 : 0;
    -+	return oideq(oid, real_oid);
    - }
    - 
    - int git_open_cloexec(const char *name, int flags)
    -@@ object-file.c: int read_loose_object(const char *path,
    - 			git_inflate_end(&stream);
    - 			goto out;
    - 		}
    --		if (check_object_signature(the_repository, expected_oid,
    --					   *contents, *size,
    --					   oi->type_name->buf, real_oid))
    -+		if (!check_object_signature(the_repository, expected_oid,
    -+					    *contents, *size,
    -+					    oi->type_name->buf, real_oid))
    - 			goto out;
    - 	}
    - 
    -
    - ## object.c ##
    -@@ object.c: struct object *parse_object(struct repository *r, const struct object_id *oid)
    - 	if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
    - 	    (!obj && repo_has_object_file(r, oid) &&
    - 	     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
    --		if (check_object_signature(r, repl, NULL, 0, NULL, NULL) < 0) {
    -+		if (!check_object_signature(r, repl, NULL, 0, NULL, NULL)) {
    - 			error(_("hash mismatch %s"), oid_to_hex(oid));
    - 			return NULL;
    - 		}
    -@@ object.c: struct object *parse_object(struct repository *r, const struct object_id *oid)
    - 
    - 	buffer = repo_read_object_file(r, oid, &type, &size);
    - 	if (buffer) {
    --		if (check_object_signature(r, repl, buffer, size,
    --					   type_name(type), NULL) < 0) {
    -+		if (!check_object_signature(r, repl, buffer, size,
    -+					    type_name(type), NULL)) {
    - 			free(buffer);
    - 			error(_("hash mismatch %s"), oid_to_hex(repl));
    - 			return NULL;
    -
    - ## pack-check.c ##
    -@@ pack-check.c: static int verify_packfile(struct repository *r,
    - 			err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
    - 				    oid_to_hex(&oid), p->pack_name,
    - 				    (uintmax_t)entries[i].offset);
    --		else if (check_object_signature(r, &oid, data, size,
    --						type_name(type), NULL))
    -+		else if (!check_object_signature(r, &oid, data, size,
    -+						 type_name(type), NULL))
    - 			err = error("packed %s from %s is corrupt",
    - 				    oid_to_hex(&oid), p->pack_name);
    - 		else if (fn) {
 -:  ----------- >  7:  75abf75a437 object API users + docs: check <0, not !0 with check_object_signature()
 4:  c38af53e889 !  8:  478d2915731 object-file API: split up and simplify check_object_signature()
    @@ builtin/fast-export.c
     @@ builtin/fast-export.c: static void export_blob(const struct object_id *oid)
      		if (!buf)
      			die("could not read blob %s", oid_to_hex(oid));
    - 		if (!check_object_signature(the_repository, oid, buf, size,
    --					    type_name(type), NULL))
    -+					    type_name(type)))
    + 		if (check_object_signature(the_repository, oid, buf, size,
    +-					   type_name(type), NULL) < 0)
    ++					   type_name(type)) < 0)
      			die("oid mismatch in blob %s", oid_to_hex(oid));
      		object = parse_object_buffer(the_repository, oid, type,
      					     size, buf, &eaten);
    @@ builtin/index-pack.c
     @@ builtin/index-pack.c: static void fix_unresolved_deltas(struct hashfile *f)
      			continue;
      
    - 		if (!check_object_signature(the_repository, &d->oid, data,
    --					    size, type_name(type), NULL))
    -+					    size, type_name(type)))
    + 		if (check_object_signature(the_repository, &d->oid, data, size,
    +-					   type_name(type), NULL) < 0)
    ++					   type_name(type)) < 0)
      			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
      
      		/*
     
      ## builtin/mktag.c ##
     @@ builtin/mktag.c: static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
    + 		    type_name(*tagged_type), type_name(type));
      
      	repl = lookup_replace_object(the_repository, tagged_oid);
    - 	ret = !check_object_signature(the_repository, repl, buffer, size,
    --				      type_name(*tagged_type), NULL);
    -+				      type_name(*tagged_type));
    +-	ret = check_object_signature(the_repository, repl,
    +-				     buffer, size, type_name(*tagged_type),
    +-				     NULL);
    ++	ret = check_object_signature(the_repository, repl, buffer, size,
    ++				     type_name(*tagged_type));
      	free(buffer);
      
      	return ret;
    @@ cache.h: int parse_loose_header(const char *hdr, struct object_info *oi);
     - * With "buf" == NULL, try reading the object named with "oid" using
     - * the streaming interface and rehash it to do the same.
       *
    -  * Treat the return value like oideq() (which is like memcmp()),
    -  * except that negative values might also indicate a generic error.
    +  * A negative value indicates an error, usually that the OID is not
    +  * what we expected, but it might also indicate another error.
       */
      int check_object_signature(struct repository *r, const struct object_id *oid,
     -			   void *buf, unsigned long size, const char *type,
    @@ object-file.c: int format_object_header(char *str, size_t size, enum object_type
     +
     +	hash_object_file(r->hash_algo, buf, size, type, &real_oid);
     +
    -+	return oideq(oid, &real_oid);
    ++	return !oideq(oid, &real_oid) ? -1 : 0;
     +}
     +
     +int stream_object_signature(struct repository *r, const struct object_id *oid)
    @@ object-file.c: int format_object_header(char *str, size_t size, enum object_type
      
     -	if (buf) {
     -		hash_object_file(r->hash_algo, buf, size, type, real_oid);
    --		return oideq(oid, real_oid);
    +-		return !oideq(oid, real_oid) ? -1 : 0;
     -	}
     -
      	st = open_istream(r, oid, &obj_type, &size, NULL);
    @@ object-file.c: int check_object_signature(struct repository *r, const struct obj
     -	r->hash_algo->final_oid_fn(real_oid, &c);
     +	r->hash_algo->final_oid_fn(&real_oid, &c);
      	close_istream(st);
    --	return oideq(oid, real_oid);
    -+	return oideq(oid, &real_oid);
    +-	return !oideq(oid, real_oid) ? -1 : 0;
    ++	return !oideq(oid, &real_oid) ? -1 : 0;
      }
      
      int git_open_cloexec(const char *name, int flags)
    @@ object-file.c: int read_loose_object(const char *path,
      			git_inflate_end(&stream);
      			goto out;
      		}
    --		if (!check_object_signature(the_repository, expected_oid,
    --					    *contents, *size,
    --					    oi->type_name->buf, real_oid))
    -+
    +-		if (check_object_signature(the_repository, expected_oid,
    +-					   *contents, *size,
    +-					   oi->type_name->buf, real_oid) < 0)
     +		hash_object_file(the_repository->hash_algo,
     +				 *contents, *size, oi->type_name->buf,
     +				 real_oid);
    @@ object.c: struct object *parse_object(struct repository *r, const struct object_
      	if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
      	    (!obj && repo_has_object_file(r, oid) &&
      	     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
    --		if (!check_object_signature(r, repl, NULL, 0, NULL, NULL)) {
    -+		if (!stream_object_signature(r, repl)) {
    +-		if (check_object_signature(r, repl, NULL, 0, NULL, NULL) < 0) {
    ++		if (stream_object_signature(r, repl) < 0) {
      			error(_("hash mismatch %s"), oid_to_hex(oid));
      			return NULL;
      		}
     @@ object.c: struct object *parse_object(struct repository *r, const struct object_id *oid)
      	buffer = repo_read_object_file(r, oid, &type, &size);
      	if (buffer) {
    - 		if (!check_object_signature(r, repl, buffer, size,
    --					    type_name(type), NULL)) {
    -+					    type_name(type))) {
    + 		if (check_object_signature(r, repl, buffer, size,
    +-					   type_name(type), NULL) < 0) {
    ++					   type_name(type)) < 0) {
      			free(buffer);
      			error(_("hash mismatch %s"), oid_to_hex(repl));
      			return NULL;
    @@ pack-check.c: static int verify_packfile(struct repository *r,
      			err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
      				    oid_to_hex(&oid), p->pack_name,
      				    (uintmax_t)entries[i].offset);
    --		else if (!check_object_signature(r, &oid, data, size,
    --						 type_name(type), NULL))
    -+		else if (data && !check_object_signature(r, &oid, data, size,
    -+							 type_name(type)))
    +-		else if (check_object_signature(r, &oid, data, size,
    +-						type_name(type), NULL) < 0)
    ++		else if (data && check_object_signature(r, &oid, data, size,
    ++							type_name(type)) < 0)
     +			err = error("packed %s from %s is corrupt",
     +				    oid_to_hex(&oid), p->pack_name);
    -+		else if (!data && !stream_object_signature(r, &oid))
    ++		else if (!data && stream_object_signature(r, &oid) < 0)
      			err = error("packed %s from %s is corrupt",
      				    oid_to_hex(&oid), p->pack_name);
      		else if (fn) {
 5:  a5ebd04d462 =  9:  1276c2d1ed6 object API: rename hash_object_file_literally() to write_*()
 6:  40647be525b ! 10:  2c936c674d4 object-file API: have hash_object_file() take "enum object_type"
    @@ builtin/fast-export.c
     @@ builtin/fast-export.c: static void export_blob(const struct object_id *oid)
      		if (!buf)
      			die("could not read blob %s", oid_to_hex(oid));
    - 		if (!check_object_signature(the_repository, oid, buf, size,
    --					    type_name(type)))
    -+					    type))
    + 		if (check_object_signature(the_repository, oid, buf, size,
    +-					   type_name(type)) < 0)
    ++					   type) < 0)
      			die("oid mismatch in blob %s", oid_to_hex(oid));
      		object = parse_object_buffer(the_repository, oid, type,
      					     size, buf, &eaten);
    @@ builtin/index-pack.c: static struct base_data *resolve_delta(struct object_entry
     @@ builtin/index-pack.c: static void fix_unresolved_deltas(struct hashfile *f)
      			continue;
      
    - 		if (!check_object_signature(the_repository, &d->oid, data,
    --					    size, type_name(type)))
    -+					    size, type))
    + 		if (check_object_signature(the_repository, &d->oid, data, size,
    +-					   type_name(type)) < 0)
    ++					   type) < 0)
      			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
      
      		/*
    @@ builtin/mktag.c
     @@ builtin/mktag.c: static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
      
      	repl = lookup_replace_object(the_repository, tagged_oid);
    - 	ret = !check_object_signature(the_repository, repl, buffer, size,
    --				      type_name(*tagged_type));
    + 	ret = check_object_signature(the_repository, repl, buffer, size,
    +-				     type_name(*tagged_type));
     +				     *tagged_type);
      	free(buffer);
      
    @@ cache-tree.c: static int verify_one(struct repository *r,
     
      ## cache.h ##
     @@ cache.h: int parse_loose_header(const char *hdr, struct object_info *oi);
    -  * except that negative values might also indicate a generic error.
    +  * what we expected, but it might also indicate another error.
       */
      int check_object_signature(struct repository *r, const struct object_id *oid,
     -			   void *buf, unsigned long size, const char *type);
    @@ object-file.c: int index_path(struct index_state *istate, struct object_id *oid,
      			rc = error(_("%s: failed to insert into database"), path);
      		strbuf_release(&sb);
     @@ object-file.c: int read_loose_object(const char *path,
    + 			git_inflate_end(&stream);
      			goto out;
      		}
    - 
     -		hash_object_file(the_repository->hash_algo,
     -				 *contents, *size, oi->type_name->buf,
     -				 real_oid);
    @@ object.c: struct object *parse_object(struct repository *r, const struct object_
      
      	buffer = repo_read_object_file(r, oid, &type, &size);
      	if (buffer) {
    --		if (!check_object_signature(r, repl, buffer, size,
    --					    type_name(type))) {
    -+		if (!check_object_signature(r, repl, buffer, size, type)) {
    +-		if (check_object_signature(r, repl, buffer, size,
    +-					   type_name(type)) < 0) {
    ++		if (check_object_signature(r, repl, buffer, size, type) < 0) {
      			free(buffer);
      			error(_("hash mismatch %s"), oid_to_hex(repl));
      			return NULL;
    @@ pack-check.c
     @@ pack-check.c: static int verify_packfile(struct repository *r,
      				    oid_to_hex(&oid), p->pack_name,
      				    (uintmax_t)entries[i].offset);
    - 		else if (data && !check_object_signature(r, &oid, data, size,
    --							 type_name(type)))
    -+							 type))
    + 		else if (data && check_object_signature(r, &oid, data, size,
    +-							type_name(type)) < 0)
    ++							type) < 0)
      			err = error("packed %s from %s is corrupt",
      				    oid_to_hex(&oid), p->pack_name);
    - 		else if (!data && !stream_object_signature(r, &oid))
    + 		else if (!data && stream_object_signature(r, &oid) < 0)
 7:  e39edfbce05 = 11:  ad1a777f454 object-file.c: add a literal version of write_object_file_prepare()
 8:  f2b1cb861a0 = 12:  d2d355e6bb8 object-file API: pass an enum to read_object_with_reference()
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v3 01/12] object-file.c: split up declaration of unrelated variables
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 02/12] object-file API: return "void", not "int" from hash_object_file() Ævar Arnfjörð Bjarmason
                       ` (10 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Split up the declaration of the "ret" and "re_allocated"
variables. It's not our usual style to group variable declarations
simply because they share a type, we'd only prefer to do so when the
two are closely related (e.g. "int i, j"). This change makes a
subsequent and meaningful change's diff smaller.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 object-file.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/object-file.c b/object-file.c
index 8be57f48de7..ecc77973292 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2118,7 +2118,8 @@ static int index_mem(struct index_state *istate,
 		     enum object_type type,
 		     const char *path, unsigned flags)
 {
-	int ret, re_allocated = 0;
+	int ret;
+	int re_allocated = 0;
 	int write_object = flags & HASH_WRITE_OBJECT;
 
 	if (!type)
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 02/12] object-file API: return "void", not "int" from hash_object_file()
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 01/12] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 03/12] object-file API: add a format_object_header() function Ævar Arnfjörð Bjarmason
                       ` (9 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

The hash_object_file() function added in abdc3fc8421 (Add
hash_sha1_file(), 2006-10-14) did not have a meaningful return value,
and it never has.

One was seemingly added to avoid adding braces to the "ret = "
assignments being modified here. Let's instead assign "0" to the "ret"
variables at the beginning of the relevant functions, and have them
return "void".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 object-file.c  | 16 ++++++++--------
 object-store.h |  6 +++---
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/object-file.c b/object-file.c
index ecc77973292..eeb6814780a 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1836,14 +1836,13 @@ static int write_buffer(int fd, const void *buf, size_t len)
 	return 0;
 }
 
-int hash_object_file(const struct git_hash_algo *algo, const void *buf,
+void hash_object_file(const struct git_hash_algo *algo, const void *buf,
 		     unsigned long len, const char *type,
 		     struct object_id *oid)
 {
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen = sizeof(hdr);
 	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
-	return 0;
 }
 
 /* Finalize a file on disk, and close it. */
@@ -2118,7 +2117,7 @@ static int index_mem(struct index_state *istate,
 		     enum object_type type,
 		     const char *path, unsigned flags)
 {
-	int ret;
+	int ret = 0;
 	int re_allocated = 0;
 	int write_object = flags & HASH_WRITE_OBJECT;
 
@@ -2148,8 +2147,9 @@ static int index_mem(struct index_state *istate,
 	if (write_object)
 		ret = write_object_file(buf, size, type_name(type), oid);
 	else
-		ret = hash_object_file(the_hash_algo, buf, size,
-				       type_name(type), oid);
+		hash_object_file(the_hash_algo, buf, size, type_name(type),
+				 oid);
+
 	if (re_allocated)
 		free(buf);
 	return ret;
@@ -2161,7 +2161,7 @@ static int index_stream_convert_blob(struct index_state *istate,
 				     const char *path,
 				     unsigned flags)
 {
-	int ret;
+	int ret = 0;
 	const int write_object = flags & HASH_WRITE_OBJECT;
 	struct strbuf sbuf = STRBUF_INIT;
 
@@ -2175,8 +2175,8 @@ static int index_stream_convert_blob(struct index_state *istate,
 		ret = write_object_file(sbuf.buf, sbuf.len, type_name(OBJ_BLOB),
 					oid);
 	else
-		ret = hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
-				       type_name(OBJ_BLOB), oid);
+		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
+				 type_name(OBJ_BLOB), oid);
 	strbuf_release(&sbuf);
 	return ret;
 }
diff --git a/object-store.h b/object-store.h
index 6f89482df03..44f6868cc9c 100644
--- a/object-store.h
+++ b/object-store.h
@@ -245,9 +245,9 @@ static inline void *repo_read_object_file(struct repository *r,
 /* Read and unpack an object file into memory, write memory to an object file */
 int oid_object_info(struct repository *r, const struct object_id *, unsigned long *);
 
-int hash_object_file(const struct git_hash_algo *algo, const void *buf,
-		     unsigned long len, const char *type,
-		     struct object_id *oid);
+void hash_object_file(const struct git_hash_algo *algo, const void *buf,
+		      unsigned long len, const char *type,
+		      struct object_id *oid);
 
 int write_object_file_flags(const void *buf, unsigned long len,
 			    const char *type, struct object_id *oid,
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 03/12] object-file API: add a format_object_header() function
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 01/12] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 02/12] object-file API: return "void", not "int" from hash_object_file() Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  2022-02-17  4:59       ` Jiang Xin
  2022-02-04 23:48     ` [PATCH v3 04/12] object-file API: have write_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
                       ` (8 subsequent siblings)
  11 siblings, 1 reply; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

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>
---
 builtin/fast-import.c |  6 +++---
 builtin/index-pack.c  |  3 +--
 bulk-checkin.c        |  4 ++--
 http-push.c           |  2 +-
 object-file.c         | 23 ++++++++++++++++++++---
 object-store.h        |  8 ++++++++
 6 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 2b2e28bad79..123df7d9a53 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -937,8 +937,8 @@ static int store_object(
 	git_hash_ctx c;
 	git_zstream s;
 
-	hdrlen = xsnprintf((char *)hdr, sizeof(hdr), "%s %lu",
-			   type_name(type), (unsigned long)dat->len) + 1;
+	hdrlen = format_object_header((char *)hdr, sizeof(hdr), type,
+				      dat->len);
 	the_hash_algo->init_fn(&c);
 	the_hash_algo->update_fn(&c, hdr, hdrlen);
 	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);
 	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->update_fn(&c, out_buf, hdrlen);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 3c2e6aee3cc..01574378ce2 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -449,8 +449,7 @@ static void *unpack_entry_data(off_t offset, unsigned long size,
 	int hdrlen;
 
 	if (!is_delta_type(type)) {
-		hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX,
-				   type_name(type),(uintmax_t)size) + 1;
+		hdrlen = format_object_header(hdr, sizeof(hdr), type, size);
 		the_hash_algo->init_fn(&c);
 		the_hash_algo->update_fn(&c, hdr, hdrlen);
 	} else
diff --git a/bulk-checkin.c b/bulk-checkin.c
index 8785b2ac806..85b3ebaf971 100644
--- a/bulk-checkin.c
+++ b/bulk-checkin.c
@@ -220,8 +220,8 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
 	if (seekback == (off_t) -1)
 		return error("cannot find the current offset");
 
-	header_len = xsnprintf((char *)obuf, sizeof(obuf), "%s %" PRIuMAX,
-			       type_name(type), (uintmax_t)size) + 1;
+	header_len = format_object_header((char *)obuf, sizeof(obuf),
+					  type, size);
 	the_hash_algo->init_fn(&ctx);
 	the_hash_algo->update_fn(&ctx, obuf, header_len);
 
diff --git a/http-push.c b/http-push.c
index 3309aaf004a..f0c044dcf76 100644
--- a/http-push.c
+++ b/http-push.c
@@ -363,7 +363,7 @@ static void start_put(struct transfer_request *request)
 	git_zstream stream;
 
 	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 */
 	git_deflate_init(&stream, zlib_compression_level);
diff --git a/object-file.c b/object-file.c
index eeb6814780a..3fcd46cf9ed 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1049,6 +1049,23 @@ void *xmmap(void *start, size_t length,
 	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
  * 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;
 
 	/* 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.. */
 	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;
 
 	/* Generate the header */
-	*hdrlen = xsnprintf(hdr, *hdrlen, "%s %"PRIuMAX , type, (uintmax_t)len)+1;
+	*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
 
 	/* Sha1.. */
 	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);
 	if (!buf)
 		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);
 	free(buf);
 
diff --git a/object-store.h b/object-store.h
index 44f6868cc9c..8b4413d0ce7 100644
--- a/object-store.h
+++ b/object-store.h
@@ -331,6 +331,14 @@ int repo_has_object_file_with_flags(struct repository *r,
  */
 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);
 
 /*
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 04/12] object-file API: have write_object_file() take "enum object_type"
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                       ` (2 preceding siblings ...)
  2022-02-04 23:48     ` [PATCH v3 03/12] object-file API: add a format_object_header() function Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 05/12] object API: correct "buf" v.s. "map" mismatch in *.c and *.h Ævar Arnfjörð Bjarmason
                       ` (7 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the write_object_file() function to take an "enum object_type"
instead of a "const char *type". Its callers either passed
{commit,tree,blob,tag}_type and can pass the corresponding OBJ_* type
instead, or were hardcoding strings like "blob".

This avoids the back & forth fragility where the callers of
write_object_file() would have the enum type, and convert it
themselves via type_name(). We do have to now do that conversion
ourselves before calling write_object_file_prepare(), but those
codepaths will be similarly adjusted in subsequent commits.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 apply.c                  |  8 ++++----
 builtin/checkout.c       |  2 +-
 builtin/mktag.c          |  2 +-
 builtin/mktree.c         |  2 +-
 builtin/notes.c          |  2 +-
 builtin/receive-pack.c   |  2 +-
 builtin/replace.c        |  2 +-
 builtin/tag.c            |  2 +-
 builtin/unpack-objects.c |  6 +++---
 cache-tree.c             |  2 +-
 commit.c                 |  2 +-
 match-trees.c            |  2 +-
 merge-ort.c              |  4 ++--
 merge-recursive.c        |  2 +-
 notes-cache.c            |  2 +-
 notes.c                  |  8 ++++----
 object-file.c            | 10 +++++-----
 object-store.h           |  4 ++--
 read-cache.c             |  2 +-
 19 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/apply.c b/apply.c
index 7ffadc3b17a..e82a7c30f01 100644
--- a/apply.c
+++ b/apply.c
@@ -3589,7 +3589,7 @@ static int try_threeway(struct apply_state *state,
 
 	/* Preimage the patch was prepared for */
 	if (patch->is_new)
-		write_object_file("", 0, blob_type, &pre_oid);
+		write_object_file("", 0, OBJ_BLOB, &pre_oid);
 	else if (get_oid(patch->old_oid_prefix, &pre_oid) ||
 		 read_blob_object(&buf, &pre_oid, patch->old_mode))
 		return error(_("repository lacks the necessary blob to perform 3-way merge."));
@@ -3605,7 +3605,7 @@ static int try_threeway(struct apply_state *state,
 		return -1;
 	}
 	/* post_oid is theirs */
-	write_object_file(tmp_image.buf, tmp_image.len, blob_type, &post_oid);
+	write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &post_oid);
 	clear_image(&tmp_image);
 
 	/* our_oid is ours */
@@ -3618,7 +3618,7 @@ static int try_threeway(struct apply_state *state,
 			return error(_("cannot read the current contents of '%s'"),
 				     patch->old_name);
 	}
-	write_object_file(tmp_image.buf, tmp_image.len, blob_type, &our_oid);
+	write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &our_oid);
 	clear_image(&tmp_image);
 
 	/* in-core three-way merge between post and our using pre as base */
@@ -4346,7 +4346,7 @@ static int add_index_file(struct apply_state *state,
 			}
 			fill_stat_cache_info(state->repo->index, ce, &st);
 		}
-		if (write_object_file(buf, size, blob_type, &ce->oid) < 0) {
+		if (write_object_file(buf, size, OBJ_BLOB, &ce->oid) < 0) {
 			discard_cache_entry(ce);
 			return error(_("unable to create backing store "
 				       "for newly created file %s"), path);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index cc804ba8e1e..24cc235939f 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -298,7 +298,7 @@ static int checkout_merged(int pos, const struct checkout *state,
 	 * (it also writes the merge result to the object database even
 	 * when it may contain conflicts).
 	 */
-	if (write_object_file(result_buf.ptr, result_buf.size, blob_type, &oid))
+	if (write_object_file(result_buf.ptr, result_buf.size, OBJ_BLOB, &oid))
 		die(_("Unable to add merge result for '%s'"), path);
 	free(result_buf.ptr);
 	ce = make_transient_cache_entry(mode, &oid, path, 2, ce_mem_pool);
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 3b2dbbb37e6..96a3686af53 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -100,7 +100,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (verify_object_in_tag(&tagged_oid, &tagged_type))
 		die(_("tag on stdin did not refer to a valid object"));
 
-	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
+	if (write_object_file(buf.buf, buf.len, OBJ_TAG, &result) < 0)
 		die(_("unable to write tag file"));
 
 	strbuf_release(&buf);
diff --git a/builtin/mktree.c b/builtin/mktree.c
index ae78ca1c029..a1213aaa961 100644
--- a/builtin/mktree.c
+++ b/builtin/mktree.c
@@ -58,7 +58,7 @@ static void write_tree(struct object_id *oid)
 		strbuf_add(&buf, ent->oid.hash, the_hash_algo->rawsz);
 	}
 
-	write_object_file(buf.buf, buf.len, tree_type, oid);
+	write_object_file(buf.buf, buf.len, OBJ_TREE, oid);
 	strbuf_release(&buf);
 }
 
diff --git a/builtin/notes.c b/builtin/notes.c
index 05d60483e82..4cc84dfa768 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -199,7 +199,7 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
 
 static void write_note_data(struct note_data *d, struct object_id *oid)
 {
-	if (write_object_file(d->buf.buf, d->buf.len, blob_type, oid)) {
+	if (write_object_file(d->buf.buf, d->buf.len, OBJ_BLOB, oid)) {
 		int status = die_message(_("unable to write note object"));
 
 		if (d->edit_path)
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 9f4a0b816cf..231d576927b 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -762,7 +762,7 @@ static void prepare_push_cert_sha1(struct child_process *proc)
 		int bogs /* beginning_of_gpg_sig */;
 
 		already_done = 1;
-		if (write_object_file(push_cert.buf, push_cert.len, "blob",
+		if (write_object_file(push_cert.buf, push_cert.len, OBJ_BLOB,
 				      &push_cert_oid))
 			oidclr(&push_cert_oid);
 
diff --git a/builtin/replace.c b/builtin/replace.c
index 6ff1734d587..995ca683302 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -474,7 +474,7 @@ static int create_graft(int argc, const char **argv, int force, int gentle)
 		return -1;
 	}
 
-	if (write_object_file(buf.buf, buf.len, commit_type, &new_oid)) {
+	if (write_object_file(buf.buf, buf.len, OBJ_COMMIT, &new_oid)) {
 		strbuf_release(&buf);
 		return error(_("could not write replacement commit for: '%s'"),
 			     old_ref);
diff --git a/builtin/tag.c b/builtin/tag.c
index 134b3f1edf0..31e6b155c04 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -238,7 +238,7 @@ static int build_tag_object(struct strbuf *buf, int sign, struct object_id *resu
 {
 	if (sign && do_sign(buf) < 0)
 		return error(_("unable to sign the tag"));
-	if (write_object_file(buf->buf, buf->len, tag_type, result) < 0)
+	if (write_object_file(buf->buf, buf->len, OBJ_TAG, result) < 0)
 		return error(_("unable to write tag file"));
 	return 0;
 }
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 4a9466295ba..808041551fd 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -177,7 +177,7 @@ static void write_cached_object(struct object *obj, struct obj_buffer *obj_buf)
 	struct object_id oid;
 
 	if (write_object_file(obj_buf->buffer, obj_buf->size,
-			      type_name(obj->type), &oid) < 0)
+			      obj->type, &oid) < 0)
 		die("failed to write object %s", oid_to_hex(&obj->oid));
 	obj->flags |= FLAG_WRITTEN;
 }
@@ -243,7 +243,7 @@ static void write_object(unsigned nr, enum object_type type,
 			 void *buf, unsigned long size)
 {
 	if (!strict) {
-		if (write_object_file(buf, size, type_name(type),
+		if (write_object_file(buf, size, type,
 				      &obj_list[nr].oid) < 0)
 			die("failed to write object");
 		added_object(nr, type, buf, size);
@@ -251,7 +251,7 @@ static void write_object(unsigned nr, enum object_type type,
 		obj_list[nr].obj = NULL;
 	} else if (type == OBJ_BLOB) {
 		struct blob *blob;
-		if (write_object_file(buf, size, type_name(type),
+		if (write_object_file(buf, size, type,
 				      &obj_list[nr].oid) < 0)
 			die("failed to write object");
 		added_object(nr, type, buf, size);
diff --git a/cache-tree.c b/cache-tree.c
index 65ca9933613..fdbbd191d22 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -440,7 +440,7 @@ static int update_one(struct cache_tree *it,
 	} else if (dryrun) {
 		hash_object_file(the_hash_algo, buffer.buf, buffer.len,
 				 tree_type, &it->oid);
-	} else if (write_object_file_flags(buffer.buf, buffer.len, tree_type,
+	} else if (write_object_file_flags(buffer.buf, buffer.len, OBJ_TREE,
 					   &it->oid, flags & WRITE_TREE_SILENT
 					   ? HASH_SILENT : 0)) {
 		strbuf_release(&buffer);
diff --git a/commit.c b/commit.c
index a348f085b2b..6cc0ba9c11b 100644
--- a/commit.c
+++ b/commit.c
@@ -1567,7 +1567,7 @@ int commit_tree_extended(const char *msg, size_t msg_len,
 		goto out;
 	}
 
-	result = write_object_file(buffer.buf, buffer.len, commit_type, ret);
+	result = write_object_file(buffer.buf, buffer.len, OBJ_COMMIT, ret);
 out:
 	strbuf_release(&buffer);
 	return result;
diff --git a/match-trees.c b/match-trees.c
index df413989fa8..49398e599fe 100644
--- a/match-trees.c
+++ b/match-trees.c
@@ -235,7 +235,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
 		rewrite_with = oid2;
 	}
 	hashcpy(rewrite_here, rewrite_with->hash);
-	status = write_object_file(buf, sz, tree_type, result);
+	status = write_object_file(buf, sz, OBJ_TREE, result);
 	free(buf);
 	return status;
 }
diff --git a/merge-ort.c b/merge-ort.c
index c3197970219..d4ba2955f11 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -1888,7 +1888,7 @@ static int handle_content_merge(struct merge_options *opt,
 
 		if (!ret &&
 		    write_object_file(result_buf.ptr, result_buf.size,
-				      blob_type, &result->oid))
+				      OBJ_BLOB, &result->oid))
 			ret = err(opt, _("Unable to add %s to database"),
 				  path);
 
@@ -3343,7 +3343,7 @@ static void write_tree(struct object_id *result_oid,
 	}
 
 	/* Write this object file out, and record in result_oid */
-	write_object_file(buf.buf, buf.len, tree_type, result_oid);
+	write_object_file(buf.buf, buf.len, OBJ_TREE, result_oid);
 	strbuf_release(&buf);
 }
 
diff --git a/merge-recursive.c b/merge-recursive.c
index d9457797dbb..e0cbbf2d022 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1373,7 +1373,7 @@ static int merge_mode_and_contents(struct merge_options *opt,
 
 			if (!ret &&
 			    write_object_file(result_buf.ptr, result_buf.size,
-					      blob_type, &result->blob.oid))
+					      OBJ_BLOB, &result->blob.oid))
 				ret = err(opt, _("Unable to add %s to database"),
 					  a->path);
 
diff --git a/notes-cache.c b/notes-cache.c
index 2473314d686..9dfd251a815 100644
--- a/notes-cache.c
+++ b/notes-cache.c
@@ -92,7 +92,7 @@ int notes_cache_put(struct notes_cache *c, struct object_id *key_oid,
 {
 	struct object_id value_oid;
 
-	if (write_object_file(data, size, "blob", &value_oid) < 0)
+	if (write_object_file(data, size, OBJ_BLOB, &value_oid) < 0)
 		return -1;
 	return add_note(&c->tree, key_oid, &value_oid, NULL);
 }
diff --git a/notes.c b/notes.c
index f87dac40684..7452e71cc8d 100644
--- a/notes.c
+++ b/notes.c
@@ -675,7 +675,7 @@ static int tree_write_stack_finish_subtree(struct tree_write_stack *tws)
 		ret = tree_write_stack_finish_subtree(n);
 		if (ret)
 			return ret;
-		ret = write_object_file(n->buf.buf, n->buf.len, tree_type, &s);
+		ret = write_object_file(n->buf.buf, n->buf.len, OBJ_TREE, &s);
 		if (ret)
 			return ret;
 		strbuf_release(&n->buf);
@@ -836,7 +836,7 @@ int combine_notes_concatenate(struct object_id *cur_oid,
 	free(new_msg);
 
 	/* create a new blob object from buf */
-	ret = write_object_file(buf, buf_len, blob_type, cur_oid);
+	ret = write_object_file(buf, buf_len, OBJ_BLOB, cur_oid);
 	free(buf);
 	return ret;
 }
@@ -916,7 +916,7 @@ int combine_notes_cat_sort_uniq(struct object_id *cur_oid,
 				 string_list_join_lines_helper, &buf))
 		goto out;
 
-	ret = write_object_file(buf.buf, buf.len, blob_type, cur_oid);
+	ret = write_object_file(buf.buf, buf.len, OBJ_BLOB, cur_oid);
 
 out:
 	strbuf_release(&buf);
@@ -1192,7 +1192,7 @@ int write_notes_tree(struct notes_tree *t, struct object_id *result)
 	ret = for_each_note(t, flags, write_each_note, &cb_data) ||
 	      write_each_non_note_until(NULL, &cb_data) ||
 	      tree_write_stack_finish_subtree(&root) ||
-	      write_object_file(root.buf.buf, root.buf.len, tree_type, result);
+	      write_object_file(root.buf.buf, root.buf.len, OBJ_TREE, result);
 	strbuf_release(&root.buf);
 	return ret;
 }
diff --git a/object-file.c b/object-file.c
index 3fcd46cf9ed..59eb793e0ac 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2014,7 +2014,7 @@ static int freshen_packed_object(const struct object_id *oid)
 }
 
 int write_object_file_flags(const void *buf, unsigned long len,
-			    const char *type, struct object_id *oid,
+			    enum object_type type, struct object_id *oid,
 			    unsigned flags)
 {
 	char hdr[MAX_HEADER_LEN];
@@ -2023,7 +2023,7 @@ int write_object_file_flags(const void *buf, unsigned long len,
 	/* Normally if we have it in the pack then we do not bother writing
 	 * it out into .git/objects/??/?{38} file.
 	 */
-	write_object_file_prepare(the_hash_algo, buf, len, type, oid, hdr,
+	write_object_file_prepare(the_hash_algo, buf, len, type_name(type), oid, hdr,
 				  &hdrlen);
 	if (freshen_packed_object(oid) || freshen_loose_object(oid))
 		return 0;
@@ -2162,7 +2162,7 @@ static int index_mem(struct index_state *istate,
 	}
 
 	if (write_object)
-		ret = write_object_file(buf, size, type_name(type), oid);
+		ret = write_object_file(buf, size, type, oid);
 	else
 		hash_object_file(the_hash_algo, buf, size, type_name(type),
 				 oid);
@@ -2189,7 +2189,7 @@ static int index_stream_convert_blob(struct index_state *istate,
 				 get_conv_flags(flags));
 
 	if (write_object)
-		ret = write_object_file(sbuf.buf, sbuf.len, type_name(OBJ_BLOB),
+		ret = write_object_file(sbuf.buf, sbuf.len, OBJ_BLOB,
 					oid);
 	else
 		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
@@ -2313,7 +2313,7 @@ int index_path(struct index_state *istate, struct object_id *oid,
 		if (!(flags & HASH_WRITE_OBJECT))
 			hash_object_file(the_hash_algo, sb.buf, sb.len,
 					 blob_type, oid);
-		else if (write_object_file(sb.buf, sb.len, blob_type, oid))
+		else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid))
 			rc = error(_("%s: failed to insert into database"), path);
 		strbuf_release(&sb);
 		break;
diff --git a/object-store.h b/object-store.h
index 8b4413d0ce7..eab1e2a967e 100644
--- a/object-store.h
+++ b/object-store.h
@@ -250,10 +250,10 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf,
 		      struct object_id *oid);
 
 int write_object_file_flags(const void *buf, unsigned long len,
-			    const char *type, struct object_id *oid,
+			    enum object_type type, struct object_id *oid,
 			    unsigned flags);
 static inline int write_object_file(const void *buf, unsigned long len,
-				    const char *type, struct object_id *oid)
+				    enum object_type type, struct object_id *oid)
 {
 	return write_object_file_flags(buf, len, type, oid, 0);
 }
diff --git a/read-cache.c b/read-cache.c
index cbe73f14e5e..b8ae30a0e71 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -735,7 +735,7 @@ static struct cache_entry *create_alias_ce(struct index_state *istate,
 void set_object_name_for_intent_to_add_entry(struct cache_entry *ce)
 {
 	struct object_id oid;
-	if (write_object_file("", 0, blob_type, &oid))
+	if (write_object_file("", 0, OBJ_BLOB, &oid))
 		die(_("cannot create an empty blob in the object database"));
 	oidcpy(&ce->oid, &oid);
 }
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 05/12] object API: correct "buf" v.s. "map" mismatch in *.c and *.h
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                       ` (3 preceding siblings ...)
  2022-02-04 23:48     ` [PATCH v3 04/12] object-file API: have write_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 06/12] object API docs: move check_object_signature() docs to cache.h Ævar Arnfjörð Bjarmason
                       ` (6 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the name of the second argument to check_object_signature() to
be "buf" in object-file.c, making it consistent with the prototype in
cache.h

This fixes an inconsistency that's been with us since 2ade9340262 (Add
"check_sha1_signature()" helper function, 2005-04-08), and makes a
subsequent commit's diff smaller, as we'll move these API docs to
cache.h.

While we're at it fix a small grammar error in the documentation,
dropping an "an" before "in-core object-data".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 object-file.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/object-file.c b/object-file.c
index 59eb793e0ac..271acf4dd15 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1067,13 +1067,13 @@ int format_object_header(char *str, size_t size, enum object_type type,
 }
 
 /*
- * With an in-core object data in "map", rehash it to make sure the
+ * With in-core object data in "buf", rehash it to make sure the
  * object name actually matches "oid" to detect object corruption.
- * With "map" == NULL, try reading the object named with "oid" using
+ * With "buf" == NULL, try reading the object named with "oid" using
  * the streaming interface and rehash it to do the same.
  */
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *map, unsigned long size, const char *type,
+			   void *buf, unsigned long size, const char *type,
 			   struct object_id *real_oidp)
 {
 	struct object_id tmp;
@@ -1084,8 +1084,8 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen;
 
-	if (map) {
-		hash_object_file(r->hash_algo, map, size, type, real_oid);
+	if (buf) {
+		hash_object_file(r->hash_algo, buf, size, type, real_oid);
 		return !oideq(oid, real_oid) ? -1 : 0;
 	}
 
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 06/12] object API docs: move check_object_signature() docs to cache.h
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                       ` (4 preceding siblings ...)
  2022-02-04 23:48     ` [PATCH v3 05/12] object API: correct "buf" v.s. "map" mismatch in *.c and *.h Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 07/12] object API users + docs: check <0, not !0 with check_object_signature() Ævar Arnfjörð Bjarmason
                       ` (5 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Move the API documentation for check_object_signature() to cache.h,
where its prototype is declared. This is in preparation for adding a
companion function.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 cache.h       | 6 ++++++
 object-file.c | 6 ------
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/cache.h b/cache.h
index 281f00ab1b1..98d1ef08579 100644
--- a/cache.h
+++ b/cache.h
@@ -1319,6 +1319,12 @@ enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
 struct object_info;
 int parse_loose_header(const char *hdr, struct object_info *oi);
 
+/**
+ * With in-core object data in "buf", rehash it to make sure the
+ * object name actually matches "oid" to detect object corruption.
+ * With "buf" == NULL, try reading the object named with "oid" using
+ * the streaming interface and rehash it to do the same.
+ */
 int check_object_signature(struct repository *r, const struct object_id *oid,
 			   void *buf, unsigned long size, const char *type,
 			   struct object_id *real_oidp);
diff --git a/object-file.c b/object-file.c
index 271acf4dd15..44e0b32d71a 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1066,12 +1066,6 @@ int format_object_header(char *str, size_t size, enum object_type type,
 	return format_object_header_literally(str, size, name, objsize);
 }
 
-/*
- * With in-core object data in "buf", rehash it to make sure the
- * object name actually matches "oid" to detect object corruption.
- * With "buf" == NULL, try reading the object named with "oid" using
- * the streaming interface and rehash it to do the same.
- */
 int check_object_signature(struct repository *r, const struct object_id *oid,
 			   void *buf, unsigned long size, const char *type,
 			   struct object_id *real_oidp)
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 07/12] object API users + docs: check <0, not !0 with check_object_signature()
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                       ` (5 preceding siblings ...)
  2022-02-04 23:48     ` [PATCH v3 06/12] object API docs: move check_object_signature() docs to cache.h Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 08/12] object-file API: split up and simplify check_object_signature() Ævar Arnfjörð Bjarmason
                       ` (4 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change those users of the object API that misused
check_object_signature() by assuming it returned any non-zero when the
OID didn't match the expected value to check <0 instead. In practice
all of this code worked before, but it wasn't consistent with rest of
the users of the API.

Let's also clarify what the <0 return value means in API docs.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/index-pack.c | 5 ++---
 builtin/mktag.c      | 2 +-
 cache.h              | 3 +++
 object-file.c        | 2 +-
 pack-check.c         | 2 +-
 5 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 01574378ce2..416f60a98c1 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1412,9 +1412,8 @@ static void fix_unresolved_deltas(struct hashfile *f)
 		if (!data)
 			continue;
 
-		if (check_object_signature(the_repository, &d->oid,
-					   data, size,
-					   type_name(type), NULL))
+		if (check_object_signature(the_repository, &d->oid, data, size,
+					   type_name(type), NULL) < 0)
 			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
 
 		/*
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 96a3686af53..98d1e66f327 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -97,7 +97,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 				&tagged_oid, &tagged_type))
 		die(_("tag on stdin did not pass our strict fsck check"));
 
-	if (verify_object_in_tag(&tagged_oid, &tagged_type))
+	if (verify_object_in_tag(&tagged_oid, &tagged_type) < 0)
 		die(_("tag on stdin did not refer to a valid object"));
 
 	if (write_object_file(buf.buf, buf.len, OBJ_TAG, &result) < 0)
diff --git a/cache.h b/cache.h
index 98d1ef08579..5d081952121 100644
--- a/cache.h
+++ b/cache.h
@@ -1324,6 +1324,9 @@ int parse_loose_header(const char *hdr, struct object_info *oi);
  * object name actually matches "oid" to detect object corruption.
  * With "buf" == NULL, try reading the object named with "oid" using
  * the streaming interface and rehash it to do the same.
+ *
+ * A negative value indicates an error, usually that the OID is not
+ * what we expected, but it might also indicate another error.
  */
 int check_object_signature(struct repository *r, const struct object_id *oid,
 			   void *buf, unsigned long size, const char *type,
diff --git a/object-file.c b/object-file.c
index 44e0b32d71a..d628f58c0d2 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2613,7 +2613,7 @@ int read_loose_object(const char *path,
 		}
 		if (check_object_signature(the_repository, expected_oid,
 					   *contents, *size,
-					   oi->type_name->buf, real_oid))
+					   oi->type_name->buf, real_oid) < 0)
 			goto out;
 	}
 
diff --git a/pack-check.c b/pack-check.c
index 3f418e3a6af..48d818ee7b4 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -143,7 +143,7 @@ static int verify_packfile(struct repository *r,
 				    oid_to_hex(&oid), p->pack_name,
 				    (uintmax_t)entries[i].offset);
 		else if (check_object_signature(r, &oid, data, size,
-						type_name(type), NULL))
+						type_name(type), NULL) < 0)
 			err = error("packed %s from %s is corrupt",
 				    oid_to_hex(&oid), p->pack_name);
 		else if (fn) {
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 08/12] object-file API: split up and simplify check_object_signature()
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                       ` (6 preceding siblings ...)
  2022-02-04 23:48     ` [PATCH v3 07/12] object API users + docs: check <0, not !0 with check_object_signature() Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 09/12] object API: rename hash_object_file_literally() to write_*() Ævar Arnfjörð Bjarmason
                       ` (3 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Split up the check_object_signature() function into that non-streaming
version (it accepts an already filled "buf"), and a new
stream_object_signature() which will retrieve the object from storage,
and hash it on-the-fly.

All of the callers of check_object_signature() were effectively
calling two different functions, if we go by cyclomatic
complexity. I.e. they'd either take the early "if (map)" branch and
return early, or not. This has been the case since the "if (map)"
condition was added in 090ea12671b (parse_object: avoid putting whole
blob in core, 2012-03-07).

We can then further simplify the resulting check_object_signature()
function since only one caller wanted to pass a non-NULL "buf" and a
non-NULL "real_oidp". That "read_loose_object()" codepath used by "git
fsck" can instead use hash_object_file() followed by oideq().

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/fast-export.c |  2 +-
 builtin/index-pack.c  |  2 +-
 builtin/mktag.c       |  5 ++---
 cache.h               | 12 ++++++++----
 object-file.c         | 32 ++++++++++++++++++--------------
 object.c              |  4 ++--
 pack-check.c          |  9 ++++++---
 7 files changed, 38 insertions(+), 28 deletions(-)

diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 9f1c730e587..319859db30e 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -300,7 +300,7 @@ static void export_blob(const struct object_id *oid)
 		if (!buf)
 			die("could not read blob %s", oid_to_hex(oid));
 		if (check_object_signature(the_repository, oid, buf, size,
-					   type_name(type), NULL) < 0)
+					   type_name(type)) < 0)
 			die("oid mismatch in blob %s", oid_to_hex(oid));
 		object = parse_object_buffer(the_repository, oid, type,
 					     size, buf, &eaten);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 416f60a98c1..e1927205a7b 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1413,7 +1413,7 @@ static void fix_unresolved_deltas(struct hashfile *f)
 			continue;
 
 		if (check_object_signature(the_repository, &d->oid, data, size,
-					   type_name(type), NULL) < 0)
+					   type_name(type)) < 0)
 			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
 
 		/*
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 98d1e66f327..4d28eceeba6 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -61,9 +61,8 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 		    type_name(*tagged_type), type_name(type));
 
 	repl = lookup_replace_object(the_repository, tagged_oid);
-	ret = check_object_signature(the_repository, repl,
-				     buffer, size, type_name(*tagged_type),
-				     NULL);
+	ret = check_object_signature(the_repository, repl, buffer, size,
+				     type_name(*tagged_type));
 	free(buffer);
 
 	return ret;
diff --git a/cache.h b/cache.h
index 5d081952121..c068f99c793 100644
--- a/cache.h
+++ b/cache.h
@@ -1322,15 +1322,19 @@ int parse_loose_header(const char *hdr, struct object_info *oi);
 /**
  * With in-core object data in "buf", rehash it to make sure the
  * object name actually matches "oid" to detect object corruption.
- * With "buf" == NULL, try reading the object named with "oid" using
- * the streaming interface and rehash it to do the same.
  *
  * A negative value indicates an error, usually that the OID is not
  * what we expected, but it might also indicate another error.
  */
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *buf, unsigned long size, const char *type,
-			   struct object_id *real_oidp);
+			   void *buf, unsigned long size, const char *type);
+
+/**
+ * A streaming version of check_object_signature().
+ * Try reading the object named with "oid" using
+ * the streaming interface and rehash it to do the same.
+ */
+int stream_object_signature(struct repository *r, const struct object_id *oid);
 
 int finalize_object_file(const char *tmpfile, const char *filename);
 
diff --git a/object-file.c b/object-file.c
index d628f58c0d2..f9854922741 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1067,22 +1067,25 @@ int format_object_header(char *str, size_t size, enum object_type type,
 }
 
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *buf, unsigned long size, const char *type,
-			   struct object_id *real_oidp)
+			   void *buf, unsigned long size, const char *type)
 {
-	struct object_id tmp;
-	struct object_id *real_oid = real_oidp ? real_oidp : &tmp;
+	struct object_id real_oid;
+
+	hash_object_file(r->hash_algo, buf, size, type, &real_oid);
+
+	return !oideq(oid, &real_oid) ? -1 : 0;
+}
+
+int stream_object_signature(struct repository *r, const struct object_id *oid)
+{
+	struct object_id real_oid;
+	unsigned long size;
 	enum object_type obj_type;
 	struct git_istream *st;
 	git_hash_ctx c;
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen;
 
-	if (buf) {
-		hash_object_file(r->hash_algo, buf, size, type, real_oid);
-		return !oideq(oid, real_oid) ? -1 : 0;
-	}
-
 	st = open_istream(r, oid, &obj_type, &size, NULL);
 	if (!st)
 		return -1;
@@ -1105,9 +1108,9 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
 			break;
 		r->hash_algo->update_fn(&c, buf, readlen);
 	}
-	r->hash_algo->final_oid_fn(real_oid, &c);
+	r->hash_algo->final_oid_fn(&real_oid, &c);
 	close_istream(st);
-	return !oideq(oid, real_oid) ? -1 : 0;
+	return !oideq(oid, &real_oid) ? -1 : 0;
 }
 
 int git_open_cloexec(const char *name, int flags)
@@ -2611,9 +2614,10 @@ int read_loose_object(const char *path,
 			git_inflate_end(&stream);
 			goto out;
 		}
-		if (check_object_signature(the_repository, expected_oid,
-					   *contents, *size,
-					   oi->type_name->buf, real_oid) < 0)
+		hash_object_file(the_repository->hash_algo,
+				 *contents, *size, oi->type_name->buf,
+				 real_oid);
+		if (!oideq(expected_oid, real_oid))
 			goto out;
 	}
 
diff --git a/object.c b/object.c
index c37501fc120..d07678ef6da 100644
--- a/object.c
+++ b/object.c
@@ -279,7 +279,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
 	if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
 	    (!obj && repo_has_object_file(r, oid) &&
 	     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
-		if (check_object_signature(r, repl, NULL, 0, NULL, NULL) < 0) {
+		if (stream_object_signature(r, repl) < 0) {
 			error(_("hash mismatch %s"), oid_to_hex(oid));
 			return NULL;
 		}
@@ -290,7 +290,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
 	buffer = repo_read_object_file(r, oid, &type, &size);
 	if (buffer) {
 		if (check_object_signature(r, repl, buffer, size,
-					   type_name(type), NULL) < 0) {
+					   type_name(type)) < 0) {
 			free(buffer);
 			error(_("hash mismatch %s"), oid_to_hex(repl));
 			return NULL;
diff --git a/pack-check.c b/pack-check.c
index 48d818ee7b4..d8d8f91de6b 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -127,7 +127,7 @@ static int verify_packfile(struct repository *r,
 
 		if (type == OBJ_BLOB && big_file_threshold <= size) {
 			/*
-			 * Let check_object_signature() check it with
+			 * Let stream_object_signature() check it with
 			 * the streaming interface; no point slurping
 			 * the data in-core only to discard.
 			 */
@@ -142,8 +142,11 @@ static int verify_packfile(struct repository *r,
 			err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
 				    oid_to_hex(&oid), p->pack_name,
 				    (uintmax_t)entries[i].offset);
-		else if (check_object_signature(r, &oid, data, size,
-						type_name(type), NULL) < 0)
+		else if (data && check_object_signature(r, &oid, data, size,
+							type_name(type)) < 0)
+			err = error("packed %s from %s is corrupt",
+				    oid_to_hex(&oid), p->pack_name);
+		else if (!data && stream_object_signature(r, &oid) < 0)
 			err = error("packed %s from %s is corrupt",
 				    oid_to_hex(&oid), p->pack_name);
 		else if (fn) {
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 09/12] object API: rename hash_object_file_literally() to write_*()
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                       ` (7 preceding siblings ...)
  2022-02-04 23:48     ` [PATCH v3 08/12] object-file API: split up and simplify check_object_signature() Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 10/12] object-file API: have hash_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
                       ` (2 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Before 0c3db67cc81 (hash-object --literally: fix buffer overrun with
extra-long object type, 2015-05-04) the hash-object code being changed
here called write_sha1_file() to both hash and write a loose
object. Before that we'd use hash_sha1_file() to if "-w" wasn't
provided, and otherwise call write_sha1_file().

Now we'll always call the same function for both writing. Let's rename
it from hash_*_literally() to write_*_literally(). Even though the
write_*() might not actually write if HASH_WRITE_OBJECT isn't in
"flags", having it be more similar to write_object_file_flags() than
hash_object_file(), but carrying a name that would suggest that it's a
variant of the latter is confusing.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/hash-object.c | 2 +-
 object-file.c         | 6 +++---
 object-store.h        | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index c7b3ad74c60..f4cbd9c4ae3 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -25,7 +25,7 @@ static int hash_literally(struct object_id *oid, int fd, const char *type, unsig
 	if (strbuf_read(&buf, fd, 4096) < 0)
 		ret = -1;
 	else
-		ret = hash_object_file_literally(buf.buf, buf.len, type, oid,
+		ret = write_object_file_literally(buf.buf, buf.len, type, oid,
 						 flags);
 	strbuf_release(&buf);
 	return ret;
diff --git a/object-file.c b/object-file.c
index f9854922741..9e5b849693e 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2027,9 +2027,9 @@ int write_object_file_flags(const void *buf, unsigned long len,
 	return write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags);
 }
 
-int hash_object_file_literally(const void *buf, unsigned long len,
-			       const char *type, struct object_id *oid,
-			       unsigned flags)
+int write_object_file_literally(const void *buf, unsigned long len,
+				const char *type, struct object_id *oid,
+				unsigned flags)
 {
 	char *header;
 	int hdrlen, status = 0;
diff --git a/object-store.h b/object-store.h
index eab1e2a967e..29169d117f7 100644
--- a/object-store.h
+++ b/object-store.h
@@ -258,9 +258,9 @@ static inline int write_object_file(const void *buf, unsigned long len,
 	return write_object_file_flags(buf, len, type, oid, 0);
 }
 
-int hash_object_file_literally(const void *buf, unsigned long len,
-			       const char *type, struct object_id *oid,
-			       unsigned flags);
+int write_object_file_literally(const void *buf, unsigned long len,
+				const char *type, struct object_id *oid,
+				unsigned flags);
 
 /*
  * Add an object file to the in-memory object store, without writing it
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 10/12] object-file API: have hash_object_file() take "enum object_type"
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                       ` (8 preceding siblings ...)
  2022-02-04 23:48     ` [PATCH v3 09/12] object API: rename hash_object_file_literally() to write_*() Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 11/12] object-file.c: add a literal version of write_object_file_prepare() Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 12/12] object-file API: pass an enum to read_object_with_reference() Ævar Arnfjörð Bjarmason
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the hash_object_file() function to take an "enum
object_type".

Since a preceding commit all of its callers are passing either
"{commit,tree,blob,tag}_type", or the result of a call to type_name(),
the parse_object() caller that would pass NULL is now using
stream_object_signature().

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 apply.c                  |  4 ++--
 builtin/fast-export.c    |  2 +-
 builtin/index-pack.c     |  4 ++--
 builtin/mktag.c          |  2 +-
 builtin/replace.c        |  2 +-
 builtin/unpack-objects.c |  2 +-
 cache-tree.c             |  6 +++---
 cache.h                  |  3 ++-
 convert.c                |  2 +-
 diffcore-rename.c        |  2 +-
 dir.c                    |  2 +-
 log-tree.c               |  2 +-
 object-file.c            | 35 +++++++++++++++++++++--------------
 object-store.h           |  2 +-
 object.c                 |  3 +--
 pack-check.c             |  2 +-
 16 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/apply.c b/apply.c
index e82a7c30f01..8513755e254 100644
--- a/apply.c
+++ b/apply.c
@@ -3157,7 +3157,7 @@ static int apply_binary(struct apply_state *state,
 		 * See if the old one matches what the patch
 		 * applies to.
 		 */
-		hash_object_file(the_hash_algo, img->buf, img->len, blob_type,
+		hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB,
 				 &oid);
 		if (strcmp(oid_to_hex(&oid), patch->old_oid_prefix))
 			return error(_("the patch applies to '%s' (%s), "
@@ -3203,7 +3203,7 @@ static int apply_binary(struct apply_state *state,
 				     name);
 
 		/* verify that the result matches */
-		hash_object_file(the_hash_algo, img->buf, img->len, blob_type,
+		hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB,
 				 &oid);
 		if (strcmp(oid_to_hex(&oid), patch->new_oid_prefix))
 			return error(_("binary patch to '%s' creates incorrect result (expecting %s, got %s)"),
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 319859db30e..52aebeb5214 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -300,7 +300,7 @@ static void export_blob(const struct object_id *oid)
 		if (!buf)
 			die("could not read blob %s", oid_to_hex(oid));
 		if (check_object_signature(the_repository, oid, buf, size,
-					   type_name(type)) < 0)
+					   type) < 0)
 			die("oid mismatch in blob %s", oid_to_hex(oid));
 		object = parse_object_buffer(the_repository, oid, type,
 					     size, buf, &eaten);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index e1927205a7b..d0c3e0966b7 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -970,7 +970,7 @@ static struct base_data *resolve_delta(struct object_entry *delta_obj,
 	if (!result_data)
 		bad_object(delta_obj->idx.offset, _("failed to apply delta"));
 	hash_object_file(the_hash_algo, result_data, result_size,
-			 type_name(delta_obj->real_type), &delta_obj->idx.oid);
+			 delta_obj->real_type, &delta_obj->idx.oid);
 	sha1_object(result_data, NULL, result_size, delta_obj->real_type,
 		    &delta_obj->idx.oid);
 
@@ -1413,7 +1413,7 @@ static void fix_unresolved_deltas(struct hashfile *f)
 			continue;
 
 		if (check_object_signature(the_repository, &d->oid, data, size,
-					   type_name(type)) < 0)
+					   type) < 0)
 			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
 
 		/*
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 4d28eceeba6..14b9fe3bc0a 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -62,7 +62,7 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 
 	repl = lookup_replace_object(the_repository, tagged_oid);
 	ret = check_object_signature(the_repository, repl, buffer, size,
-				     type_name(*tagged_type));
+				     *tagged_type);
 	free(buffer);
 
 	return ret;
diff --git a/builtin/replace.c b/builtin/replace.c
index 995ca683302..53a3b246570 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -409,7 +409,7 @@ static int check_one_mergetag(struct commit *commit,
 	int i;
 
 	hash_object_file(the_hash_algo, extra->value, extra->len,
-			 type_name(OBJ_TAG), &tag_oid);
+			 OBJ_TAG, &tag_oid);
 	tag = lookup_tag(the_repository, &tag_oid);
 	if (!tag)
 		return error(_("bad mergetag in commit '%s'"), ref);
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 808041551fd..dbeb0680a58 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -266,7 +266,7 @@ static void write_object(unsigned nr, enum object_type type,
 	} else {
 		struct object *obj;
 		int eaten;
-		hash_object_file(the_hash_algo, buf, size, type_name(type),
+		hash_object_file(the_hash_algo, buf, size, type,
 				 &obj_list[nr].oid);
 		added_object(nr, type, buf, size);
 		obj = parse_object_buffer(the_repository, &obj_list[nr].oid,
diff --git a/cache-tree.c b/cache-tree.c
index fdbbd191d22..6752f69d515 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -432,14 +432,14 @@ static int update_one(struct cache_tree *it,
 	if (repair) {
 		struct object_id oid;
 		hash_object_file(the_hash_algo, buffer.buf, buffer.len,
-				 tree_type, &oid);
+				 OBJ_TREE, &oid);
 		if (has_object_file_with_flags(&oid, OBJECT_INFO_SKIP_FETCH_OBJECT))
 			oidcpy(&it->oid, &oid);
 		else
 			to_invalidate = 1;
 	} else if (dryrun) {
 		hash_object_file(the_hash_algo, buffer.buf, buffer.len,
-				 tree_type, &it->oid);
+				 OBJ_TREE, &it->oid);
 	} else if (write_object_file_flags(buffer.buf, buffer.len, OBJ_TREE,
 					   &it->oid, flags & WRITE_TREE_SILENT
 					   ? HASH_SILENT : 0)) {
@@ -948,7 +948,7 @@ static int verify_one(struct repository *r,
 		strbuf_addf(&tree_buf, "%o %.*s%c", mode, entlen, name, '\0');
 		strbuf_add(&tree_buf, oid->hash, r->hash_algo->rawsz);
 	}
-	hash_object_file(r->hash_algo, tree_buf.buf, tree_buf.len, tree_type,
+	hash_object_file(r->hash_algo, tree_buf.buf, tree_buf.len, OBJ_TREE,
 			 &new_oid);
 	if (!oideq(&new_oid, &it->oid))
 		BUG("cache-tree for path %.*s does not match. "
diff --git a/cache.h b/cache.h
index c068f99c793..2027803c49a 100644
--- a/cache.h
+++ b/cache.h
@@ -1327,7 +1327,8 @@ int parse_loose_header(const char *hdr, struct object_info *oi);
  * what we expected, but it might also indicate another error.
  */
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *buf, unsigned long size, const char *type);
+			   void *map, unsigned long size,
+			   enum object_type type);
 
 /**
  * A streaming version of check_object_signature().
diff --git a/convert.c b/convert.c
index df7186bd813..d88072fe320 100644
--- a/convert.c
+++ b/convert.c
@@ -1159,7 +1159,7 @@ static int ident_to_worktree(const char *src, size_t len,
 	/* are we "faking" in place editing ? */
 	if (src == buf->buf)
 		to_free = strbuf_detach(buf, NULL);
-	hash_object_file(the_hash_algo, src, len, "blob", &oid);
+	hash_object_file(the_hash_algo, src, len, OBJ_BLOB, &oid);
 
 	strbuf_grow(buf, len + cnt * (the_hash_algo->hexsz + 3));
 	for (;;) {
diff --git a/diffcore-rename.c b/diffcore-rename.c
index bebd4ed6a42..c0422d9e709 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -261,7 +261,7 @@ static unsigned int hash_filespec(struct repository *r,
 		if (diff_populate_filespec(r, filespec, NULL))
 			return 0;
 		hash_object_file(r->hash_algo, filespec->data, filespec->size,
-				 "blob", &filespec->oid);
+				 OBJ_BLOB, &filespec->oid);
 	}
 	return oidhash(&filespec->oid);
 }
diff --git a/dir.c b/dir.c
index d91295f2bcd..5674e8a6256 100644
--- a/dir.c
+++ b/dir.c
@@ -1113,7 +1113,7 @@ static int add_patterns(const char *fname, const char *base, int baselen,
 				       &istate->cache[pos]->oid);
 			else
 				hash_object_file(the_hash_algo, buf, size,
-						 "blob", &oid_stat->oid);
+						 OBJ_BLOB, &oid_stat->oid);
 			fill_stat_data(&oid_stat->stat, &st);
 			oid_stat->valid = 1;
 		}
diff --git a/log-tree.c b/log-tree.c
index d3e7a40b648..27a5b0bd61a 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -561,7 +561,7 @@ static int show_one_mergetag(struct commit *commit,
 	struct strbuf signature = STRBUF_INIT;
 
 	hash_object_file(the_hash_algo, extra->value, extra->len,
-			 type_name(OBJ_TAG), &oid);
+			 OBJ_TAG, &oid);
 	tag = lookup_tag(the_repository, &oid);
 	if (!tag)
 		return -1; /* error message already given */
diff --git a/object-file.c b/object-file.c
index 9e5b849693e..b1cb78c4419 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1067,7 +1067,8 @@ int format_object_header(char *str, size_t size, enum object_type type,
 }
 
 int check_object_signature(struct repository *r, const struct object_id *oid,
-			   void *buf, unsigned long size, const char *type)
+			   void *buf, unsigned long size,
+			   enum object_type type)
 {
 	struct object_id real_oid;
 
@@ -1676,7 +1677,7 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
 {
 	struct cached_object *co;
 
-	hash_object_file(the_hash_algo, buf, len, type_name(type), oid);
+	hash_object_file(the_hash_algo, buf, len, type, oid);
 	if (has_object_file_with_flags(oid, OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT) ||
 	    find_cached_object(oid))
 		return 0;
@@ -1850,15 +1851,23 @@ static int write_buffer(int fd, const void *buf, size_t len)
 	return 0;
 }
 
-void hash_object_file(const struct git_hash_algo *algo, const void *buf,
-		     unsigned long len, const char *type,
-		     struct object_id *oid)
+static void hash_object_file_literally(const struct git_hash_algo *algo,
+				       const void *buf, unsigned long len,
+				       const char *type, struct object_id *oid)
 {
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen = sizeof(hdr);
+
 	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
 }
 
+void hash_object_file(const struct git_hash_algo *algo, const void *buf,
+		      unsigned long len, enum object_type type,
+		      struct object_id *oid)
+{
+	hash_object_file_literally(algo, buf, len, type_name(type), oid);
+}
+
 /* Finalize a file on disk, and close it. */
 static void close_loose_object(int fd)
 {
@@ -2161,9 +2170,7 @@ static int index_mem(struct index_state *istate,
 	if (write_object)
 		ret = write_object_file(buf, size, type, oid);
 	else
-		hash_object_file(the_hash_algo, buf, size, type_name(type),
-				 oid);
-
+		hash_object_file(the_hash_algo, buf, size, type, oid);
 	if (re_allocated)
 		free(buf);
 	return ret;
@@ -2189,8 +2196,8 @@ static int index_stream_convert_blob(struct index_state *istate,
 		ret = write_object_file(sbuf.buf, sbuf.len, OBJ_BLOB,
 					oid);
 	else
-		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
-				 type_name(OBJ_BLOB), oid);
+		hash_object_file(the_hash_algo, sbuf.buf, sbuf.len, OBJ_BLOB,
+				 oid);
 	strbuf_release(&sbuf);
 	return ret;
 }
@@ -2309,7 +2316,7 @@ int index_path(struct index_state *istate, struct object_id *oid,
 			return error_errno("readlink(\"%s\")", path);
 		if (!(flags & HASH_WRITE_OBJECT))
 			hash_object_file(the_hash_algo, sb.buf, sb.len,
-					 blob_type, oid);
+					 OBJ_BLOB, oid);
 		else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid))
 			rc = error(_("%s: failed to insert into database"), path);
 		strbuf_release(&sb);
@@ -2614,9 +2621,9 @@ int read_loose_object(const char *path,
 			git_inflate_end(&stream);
 			goto out;
 		}
-		hash_object_file(the_repository->hash_algo,
-				 *contents, *size, oi->type_name->buf,
-				 real_oid);
+		hash_object_file_literally(the_repository->hash_algo,
+					   *contents, *size,
+					   oi->type_name->buf, real_oid);
 		if (!oideq(expected_oid, real_oid))
 			goto out;
 	}
diff --git a/object-store.h b/object-store.h
index 29169d117f7..bd2322ed8ce 100644
--- a/object-store.h
+++ b/object-store.h
@@ -246,7 +246,7 @@ static inline void *repo_read_object_file(struct repository *r,
 int oid_object_info(struct repository *r, const struct object_id *, unsigned long *);
 
 void hash_object_file(const struct git_hash_algo *algo, const void *buf,
-		      unsigned long len, const char *type,
+		      unsigned long len, enum object_type type,
 		      struct object_id *oid);
 
 int write_object_file_flags(const void *buf, unsigned long len,
diff --git a/object.c b/object.c
index d07678ef6da..588b8156f1d 100644
--- a/object.c
+++ b/object.c
@@ -289,8 +289,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
 
 	buffer = repo_read_object_file(r, oid, &type, &size);
 	if (buffer) {
-		if (check_object_signature(r, repl, buffer, size,
-					   type_name(type)) < 0) {
+		if (check_object_signature(r, repl, buffer, size, type) < 0) {
 			free(buffer);
 			error(_("hash mismatch %s"), oid_to_hex(repl));
 			return NULL;
diff --git a/pack-check.c b/pack-check.c
index d8d8f91de6b..bfb593ba726 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -143,7 +143,7 @@ static int verify_packfile(struct repository *r,
 				    oid_to_hex(&oid), p->pack_name,
 				    (uintmax_t)entries[i].offset);
 		else if (data && check_object_signature(r, &oid, data, size,
-							type_name(type)) < 0)
+							type) < 0)
 			err = error("packed %s from %s is corrupt",
 				    oid_to_hex(&oid), p->pack_name);
 		else if (!data && stream_object_signature(r, &oid) < 0)
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 11/12] object-file.c: add a literal version of write_object_file_prepare()
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                       ` (9 preceding siblings ...)
  2022-02-04 23:48     ` [PATCH v3 10/12] object-file API: have hash_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  2022-02-04 23:48     ` [PATCH v3 12/12] object-file API: pass an enum to read_object_with_reference() Ævar Arnfjörð Bjarmason
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Split off a *_literally() variant of the write_object_file_prepare()
function. To do this create a new "hash_object_body()" static helper.

We now defer the type_name() call until the very last moment in
format_object_header() for those callers that aren't "hash-object
--literally".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 object-file.c | 39 +++++++++++++++++++++++++++++----------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/object-file.c b/object-file.c
index b1cb78c4419..c75c12dd0ba 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1784,21 +1784,40 @@ void *read_object_with_reference(struct repository *r,
 	}
 }
 
+static void hash_object_body(const struct git_hash_algo *algo, git_hash_ctx *c,
+			     const void *buf, unsigned long len,
+			     struct object_id *oid,
+			     char *hdr, int *hdrlen)
+{
+	algo->init_fn(c);
+	algo->update_fn(c, hdr, *hdrlen);
+	algo->update_fn(c, buf, len);
+	algo->final_oid_fn(oid, c);
+}
+
 static void write_object_file_prepare(const struct git_hash_algo *algo,
 				      const void *buf, unsigned long len,
-				      const char *type, struct object_id *oid,
+				      enum object_type type, struct object_id *oid,
 				      char *hdr, int *hdrlen)
 {
 	git_hash_ctx c;
 
 	/* Generate the header */
-	*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
+	*hdrlen = format_object_header(hdr, *hdrlen, type, len);
 
 	/* Sha1.. */
-	algo->init_fn(&c);
-	algo->update_fn(&c, hdr, *hdrlen);
-	algo->update_fn(&c, buf, len);
-	algo->final_oid_fn(oid, &c);
+	hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen);
+}
+
+static void write_object_file_prepare_literally(const struct git_hash_algo *algo,
+				      const void *buf, unsigned long len,
+				      const char *type, struct object_id *oid,
+				      char *hdr, int *hdrlen)
+{
+	git_hash_ctx c;
+
+	*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
+	hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen);
 }
 
 /*
@@ -1858,7 +1877,7 @@ static void hash_object_file_literally(const struct git_hash_algo *algo,
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen = sizeof(hdr);
 
-	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
+	write_object_file_prepare_literally(algo, buf, len, type, oid, hdr, &hdrlen);
 }
 
 void hash_object_file(const struct git_hash_algo *algo, const void *buf,
@@ -2029,7 +2048,7 @@ int write_object_file_flags(const void *buf, unsigned long len,
 	/* Normally if we have it in the pack then we do not bother writing
 	 * it out into .git/objects/??/?{38} file.
 	 */
-	write_object_file_prepare(the_hash_algo, buf, len, type_name(type), oid, hdr,
+	write_object_file_prepare(the_hash_algo, buf, len, type, oid, hdr,
 				  &hdrlen);
 	if (freshen_packed_object(oid) || freshen_loose_object(oid))
 		return 0;
@@ -2046,8 +2065,8 @@ int write_object_file_literally(const void *buf, unsigned long len,
 	/* type string, SP, %lu of the length plus NUL must fit this */
 	hdrlen = strlen(type) + MAX_HEADER_LEN;
 	header = xmalloc(hdrlen);
-	write_object_file_prepare(the_hash_algo, buf, len, type, oid, header,
-				  &hdrlen);
+	write_object_file_prepare_literally(the_hash_algo, buf, len, type,
+					    oid, header, &hdrlen);
 
 	if (!(flags & HASH_WRITE_OBJECT))
 		goto cleanup;
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 12/12] object-file API: pass an enum to read_object_with_reference()
  2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
                       ` (10 preceding siblings ...)
  2022-02-04 23:48     ` [PATCH v3 11/12] object-file.c: add a literal version of write_object_file_prepare() Ævar Arnfjörð Bjarmason
@ 2022-02-04 23:48     ` Ævar Arnfjörð Bjarmason
  11 siblings, 0 replies; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-04 23:48 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Han Xin, Jiang Xin, René Scharfe,
	Derrick Stolee, Ævar Arnfjörð Bjarmason

Change the read_object_with_reference() function to take an "enum
object_type". It was not prepared to handle an arbitrary "const
char *type", as it was itself calling type_from_string().

Let's change the only caller that passes in user data to use
type_from_string(), and convert the rest to use e.g. "OBJ_TREE"
instead of "tree_type".

The "cat-file" caller is not on the codepath that
handles"--allow-unknown", so the type_from_string() there is safe. Its
use of type_from_string() doesn't functionally differ from that of the
pre-image.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/cat-file.c     | 11 +++++++----
 builtin/fast-import.c  |  6 +++---
 builtin/grep.c         |  4 ++--
 builtin/pack-objects.c |  2 +-
 cache.h                |  2 +-
 object-file.c          |  5 ++---
 tree-walk.c            |  6 +++---
 7 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index d94050e6c18..3c5bc505e0a 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -154,7 +154,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 		break;
 
 	case 0:
-		if (type_from_string(exp_type) == OBJ_BLOB) {
+	{
+		enum object_type exp_type_id = type_from_string(exp_type);
+
+		if (exp_type_id == OBJ_BLOB) {
 			struct object_id blob_oid;
 			if (oid_object_info(the_repository, &oid, NULL) == OBJ_TAG) {
 				char *buffer = read_object_file(&oid, &type,
@@ -176,10 +179,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 			 * fall-back to the usual case.
 			 */
 		}
-		buf = read_object_with_reference(the_repository,
-						 &oid, exp_type, &size, NULL);
+		buf = read_object_with_reference(the_repository, &oid,
+						 exp_type_id, &size, NULL);
 		break;
-
+	}
 	default:
 		die("git cat-file: unknown option: %s", exp_type);
 	}
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 123df7d9a53..c52e807f56e 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -2483,7 +2483,7 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa
 		unsigned long size;
 		char *buf = read_object_with_reference(the_repository,
 						       &commit_oid,
-						       commit_type, &size,
+						       OBJ_COMMIT, &size,
 						       &commit_oid);
 		if (!buf || size < the_hash_algo->hexsz + 6)
 			die("Not a valid commit: %s", p);
@@ -2555,7 +2555,7 @@ static void parse_from_existing(struct branch *b)
 		char *buf;
 
 		buf = read_object_with_reference(the_repository,
-						 &b->oid, commit_type, &size,
+						 &b->oid, OBJ_COMMIT, &size,
 						 &b->oid);
 		parse_from_commit(b, buf, size);
 		free(buf);
@@ -2651,7 +2651,7 @@ static struct hash_list *parse_merge(unsigned int *count)
 			unsigned long size;
 			char *buf = read_object_with_reference(the_repository,
 							       &n->oid,
-							       commit_type,
+							       OBJ_COMMIT,
 							       &size, &n->oid);
 			if (!buf || size < the_hash_algo->hexsz + 6)
 				die("Not a valid commit: %s", from);
diff --git a/builtin/grep.c b/builtin/grep.c
index 9e34a820ad4..75e07b5623a 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -482,7 +482,7 @@ static int grep_submodule(struct grep_opt *opt,
 		object_type = oid_object_info(subrepo, oid, NULL);
 		obj_read_unlock();
 		data = read_object_with_reference(subrepo,
-						  oid, tree_type,
+						  oid, OBJ_TREE,
 						  &size, NULL);
 		if (!data)
 			die(_("unable to read tree (%s)"), oid_to_hex(oid));
@@ -651,7 +651,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
 		int hit, len;
 
 		data = read_object_with_reference(opt->repo,
-						  &obj->oid, tree_type,
+						  &obj->oid, OBJ_TREE,
 						  &size, NULL);
 		if (!data)
 			die(_("unable to read tree (%s)"), oid_to_hex(&obj->oid));
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index ba2006f2212..c4df3df3141 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1802,7 +1802,7 @@ static void add_preferred_base(struct object_id *oid)
 		return;
 
 	data = read_object_with_reference(the_repository, oid,
-					  tree_type, &size, &tree_oid);
+					  OBJ_TREE, &size, &tree_oid);
 	if (!data)
 		return;
 
diff --git a/cache.h b/cache.h
index 2027803c49a..0e7fc8b7c2f 100644
--- a/cache.h
+++ b/cache.h
@@ -1561,7 +1561,7 @@ int cache_name_stage_compare(const char *name1, int len1, int stage1, const char
 
 void *read_object_with_reference(struct repository *r,
 				 const struct object_id *oid,
-				 const char *required_type,
+				 enum object_type required_type,
 				 unsigned long *size,
 				 struct object_id *oid_ret);
 
diff --git a/object-file.c b/object-file.c
index c75c12dd0ba..6cbdb836cb7 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1737,16 +1737,15 @@ void *read_object_file_extended(struct repository *r,
 
 void *read_object_with_reference(struct repository *r,
 				 const struct object_id *oid,
-				 const char *required_type_name,
+				 enum object_type required_type,
 				 unsigned long *size,
 				 struct object_id *actual_oid_return)
 {
-	enum object_type type, required_type;
+	enum object_type type;
 	void *buffer;
 	unsigned long isize;
 	struct object_id actual_oid;
 
-	required_type = type_from_string(required_type_name);
 	oidcpy(&actual_oid, oid);
 	while (1) {
 		int ref_length = -1;
diff --git a/tree-walk.c b/tree-walk.c
index 3a94959d64a..506234b4b81 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -89,7 +89,7 @@ void *fill_tree_descriptor(struct repository *r,
 	void *buf = NULL;
 
 	if (oid) {
-		buf = read_object_with_reference(r, oid, tree_type, &size, NULL);
+		buf = read_object_with_reference(r, oid, OBJ_TREE, &size, NULL);
 		if (!buf)
 			die("unable to read tree %s", oid_to_hex(oid));
 	}
@@ -605,7 +605,7 @@ int get_tree_entry(struct repository *r,
 	unsigned long size;
 	struct object_id root;
 
-	tree = read_object_with_reference(r, tree_oid, tree_type, &size, &root);
+	tree = read_object_with_reference(r, tree_oid, OBJ_TREE, &size, &root);
 	if (!tree)
 		return -1;
 
@@ -677,7 +677,7 @@ enum get_oid_result get_tree_entry_follow_symlinks(struct repository *r,
 			unsigned long size;
 			tree = read_object_with_reference(r,
 							  &current_tree_oid,
-							  tree_type, &size,
+							  OBJ_TREE, &size,
 							  &root);
 			if (!tree)
 				goto done;
-- 
2.35.1.940.ge7a5b4b05f2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* RE: [PATCH v3 03/12] object-file API: add a format_object_header() function
  2022-02-04 23:48     ` [PATCH v3 03/12] object-file API: add a format_object_header() function Ævar Arnfjörð Bjarmason
@ 2022-02-17  4:59       ` Jiang Xin
  2022-02-17  9:21         ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 46+ messages in thread
From: Jiang Xin @ 2022-02-17  4:59 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Jiang Xin, git, Junio C Hamano, Han Xin, Jiang Xin,
	René Scharfe, Derrick Stolee

From: Jiang Xin <zhiyou.jx@alibaba-inc.com>

On Sat, Feb 5, 2022 Ævar Arnfjörð Bjarmason wrote:

> diff --git a/builtin/fast-import.c b/builtin/fast-import.c
> index 2b2e28bad79..123df7d9a53 100644
> --- a/builtin/fast-import.c
> +++ b/builtin/fast-import.c
> @@ -937,8 +937,8 @@ static int store_object(
>  	git_hash_ctx c;
>  	git_zstream s;
>  
> -	hdrlen = xsnprintf((char *)hdr, sizeof(hdr), "%s %lu",
> -			   type_name(type), (unsigned long)dat->len) + 1;
> +	hdrlen = format_object_header((char *)hdr, sizeof(hdr), type,
> +				      dat->len);

Type casting can be avoid if we use "void *" as the first parameter of
"format_object_header", and do type casting inside the helper function.

> diff --git a/object-file.c b/object-file.c
> index eeb6814780a..3fcd46cf9ed 100644
> --- a/object-file.c
> +++ b/object-file.c
> @@ -1049,6 +1049,23 @@ void *xmmap(void *start, size_t length,
>  	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);
> +

The return value of `type_name(type)` has not been checked for the original
implement, how about write a online inline-function in a header file like this:

	static inline int format_object_header(void *str, size_t size,
					       const char *type_name,
					       size_t objsize)
	{
		return xsnprintf((char *)str, size, "%s %"PRIuMAX, type_name,
				 (uintmax_t)objsize) + 1;
	}
 
> +	return format_object_header_literally(str, size, name, objsize);
> +}


--- >8 ---
From: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Date: Thu, 17 Feb 2022 11:35:27 +0800
Subject: [PATCH] fixup! object-file API: add a format_object_header() function

Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
---
 builtin/fast-import.c |  4 ++--
 builtin/index-pack.c  |  3 ++-
 bulk-checkin.c        |  4 ++--
 http-push.c           |  2 +-
 object-file.c         | 23 +++--------------------
 object-store.h        |  9 +++++++--
 6 files changed, 17 insertions(+), 28 deletions(-)

diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 123df7d9a5..f5ec40fc1b 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -937,7 +937,7 @@ static int store_object(
 	git_hash_ctx c;
 	git_zstream s;
 
-	hdrlen = format_object_header((char *)hdr, sizeof(hdr), type,
+	hdrlen = format_object_header(hdr, sizeof(hdr), type_name(type),
 				      dat->len);
 	the_hash_algo->init_fn(&c);
 	the_hash_algo->update_fn(&c, hdr, hdrlen);
@@ -1091,7 +1091,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
 	hashfile_checkpoint(pack_file, &checkpoint);
 	offset = checkpoint.offset;
 
-	hdrlen = format_object_header((char *)out_buf, out_sz, OBJ_BLOB, len);
+	hdrlen = format_object_header(out_buf, out_sz, "blob", len);
 
 	the_hash_algo->init_fn(&c);
 	the_hash_algo->update_fn(&c, out_buf, hdrlen);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 01574378ce..a37533333e 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -449,7 +449,8 @@ static void *unpack_entry_data(off_t offset, unsigned long size,
 	int hdrlen;
 
 	if (!is_delta_type(type)) {
-		hdrlen = format_object_header(hdr, sizeof(hdr), type, size);
+		hdrlen = format_object_header(hdr, sizeof(hdr), type_name(type),
+					      size);
 		the_hash_algo->init_fn(&c);
 		the_hash_algo->update_fn(&c, hdr, hdrlen);
 	} else
diff --git a/bulk-checkin.c b/bulk-checkin.c
index 85b3ebaf97..58fb59990d 100644
--- a/bulk-checkin.c
+++ b/bulk-checkin.c
@@ -220,8 +220,8 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
 	if (seekback == (off_t) -1)
 		return error("cannot find the current offset");
 
-	header_len = format_object_header((char *)obuf, sizeof(obuf),
-					  type, size);
+	header_len = format_object_header(obuf, sizeof(obuf), type_name(type),
+					  size);
 	the_hash_algo->init_fn(&ctx);
 	the_hash_algo->update_fn(&ctx, obuf, header_len);
 
diff --git a/http-push.c b/http-push.c
index f0c044dcf7..eb2b46b2fc 100644
--- a/http-push.c
+++ b/http-push.c
@@ -363,7 +363,7 @@ static void start_put(struct transfer_request *request)
 	git_zstream stream;
 
 	unpacked = read_object_file(&request->obj->oid, &type, &len);
-	hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
+	hdrlen = format_object_header(hdr, sizeof(hdr), type_name(type), len);
 
 	/* Set it up */
 	git_deflate_init(&stream, zlib_compression_level);
diff --git a/object-file.c b/object-file.c
index 3fcd46cf9e..f396e78909 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1049,23 +1049,6 @@ void *xmmap(void *start, size_t length,
 	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
  * object name actually matches "oid" to detect object corruption.
@@ -1094,7 +1077,7 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
 		return -1;
 
 	/* Generate the header */
-	hdrlen = format_object_header(hdr, sizeof(hdr), obj_type, size);
+	hdrlen = format_object_header(hdr, sizeof(hdr), type_name(obj_type), size);
 
 	/* Sha1.. */
 	r->hash_algo->init_fn(&c);
@@ -1794,7 +1777,7 @@ static void write_object_file_prepare(const struct git_hash_algo *algo,
 	git_hash_ctx c;
 
 	/* Generate the header */
-	*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
+	*hdrlen = format_object_header(hdr, *hdrlen, type, len);
 
 	/* Sha1.. */
 	algo->init_fn(&c);
@@ -2068,7 +2051,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
 	buf = read_object(the_repository, oid, &type, &len);
 	if (!buf)
 		return error(_("cannot read object for %s"), oid_to_hex(oid));
-	hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
+	hdrlen = format_object_header(hdr, sizeof(hdr), type_name(type), len);
 	ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime, 0);
 	free(buf);
 
diff --git a/object-store.h b/object-store.h
index 8b4413d0ce..33b5add7ab 100644
--- a/object-store.h
+++ b/object-store.h
@@ -336,8 +336,13 @@ int has_loose_object_nonlocal(const struct object_id *);
  * 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);
+static inline int format_object_header(void *str, size_t size,
+				       const char *type_name,
+				       size_t objsize)
+{
+	return xsnprintf((char *)str, size, "%s %"PRIuMAX, type_name,
+			 (uintmax_t)objsize) + 1;
+}
 
 void assert_oid_type(const struct object_id *oid, enum object_type expect);
 
-- 
2.35.0.rc2


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 03/12] object-file API: add a format_object_header() function
  2022-02-17  4:59       ` Jiang Xin
@ 2022-02-17  9:21         ` Ævar Arnfjörð Bjarmason
  2022-03-01  3:09           ` Jiang Xin
  0 siblings, 1 reply; 46+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-02-17  9:21 UTC (permalink / raw)
  To: Jiang Xin
  Cc: Jiang Xin, git, Junio C Hamano, Han Xin, René Scharfe,
	Derrick Stolee


On Thu, Feb 17 2022, Jiang Xin wrote:

> From: Jiang Xin <zhiyou.jx@alibaba-inc.com>
>
> On Sat, Feb 5, 2022 Ævar Arnfjörð Bjarmason wrote:
>
>> diff --git a/builtin/fast-import.c b/builtin/fast-import.c
>> index 2b2e28bad79..123df7d9a53 100644
>> --- a/builtin/fast-import.c
>> +++ b/builtin/fast-import.c
>> @@ -937,8 +937,8 @@ static int store_object(
>>  	git_hash_ctx c;
>>  	git_zstream s;
>>  
>> -	hdrlen = xsnprintf((char *)hdr, sizeof(hdr), "%s %lu",
>> -			   type_name(type), (unsigned long)dat->len) + 1;
>> +	hdrlen = format_object_header((char *)hdr, sizeof(hdr), type,
>> +				      dat->len);
>
> Type casting can be avoid if we use "void *" as the first parameter of
> "format_object_header", and do type casting inside the helper function.
> [...]
> The return value of `type_name(type)` has not been checked for the original
> implement, how about write a online inline-function in a header file like this:
>
> 	static inline int format_object_header(void *str, size_t size,
> 					       const char *type_name,
> 					       size_t objsize)
> 	{
> 		return xsnprintf((char *)str, size, "%s %"PRIuMAX, type_name,
> 				 (uintmax_t)objsize) + 1;
> 	}

I don't think the casting in the callers is bad, in that for the callers
that do use "char *" we get the compiler to help us with type checking.

Using a void * is something we really reserve only for callback-type
values, because it mens that now nobody gets any type checking.

I think if we wanted to avoid the casts it would make more sense to add
a trivial ucformat_object_header() wrapper or whatever, which would take
"unsigned chan *" and do the cast, or just tweak the relevant calling
code to change the type (IIRC some of it used unsigned v.s. signed for
no particular reason).

But I think just leaving this part as it is is better here...

> [...]
>> +	if (!name)
>> +		BUG("could not get a type name for 'enum object_type' value %d", type);
>> +
>
> The return value of `type_name(type)` has not been checked for the original
> implement, how about write a online inline-function in a header file like this:

Yes, this part is not a faithful conversion on my part, but I think it
made sense when converting this to a library function.

The alternative is that we'd segfault on some platforms (not glibc,
since it's OK with null %s arguments), just checking it is cheap & I
think a good sanity check...

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 03/12] object-file API: add a format_object_header() function
  2022-02-17  9:21         ` Ævar Arnfjörð Bjarmason
@ 2022-03-01  3:09           ` Jiang Xin
  0 siblings, 0 replies; 46+ messages in thread
From: Jiang Xin @ 2022-03-01  3:09 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Jiang Xin, Git List, Junio C Hamano, Han Xin, René Scharfe,
	Derrick Stolee

On Thu, Feb 17, 2022 at 5:25 PM Ævar Arnfjörð Bjarmason
<avarab@gmail.com> wrote:
>
>
> On Thu, Feb 17 2022, Jiang Xin wrote:
>
> > From: Jiang Xin <zhiyou.jx@alibaba-inc.com>
> >
> > Type casting can be avoid if we use "void *" as the first parameter of
> > "format_object_header", and do type casting inside the helper function.
> > [...]
> > The return value of `type_name(type)` has not been checked for the original
> > implement, how about write a online inline-function in a header file like this:
> >
> >       static inline int format_object_header(void *str, size_t size,
> >                                              const char *type_name,
> >                                              size_t objsize)
> >       {
> >               return xsnprintf((char *)str, size, "%s %"PRIuMAX, type_name,
> >                                (uintmax_t)objsize) + 1;
> >       }
>
> I don't think the casting in the callers is bad, in that for the callers
> that do use "char *" we get the compiler to help us with type checking.
>
> Using a void * is something we really reserve only for callback-type
> values, because it mens that now nobody gets any type checking.
>
> I think if we wanted to avoid the casts it would make more sense to add
> a trivial ucformat_object_header() wrapper or whatever, which would take
> "unsigned chan *" and do the cast, or just tweak the relevant calling
> code to change the type (IIRC some of it used unsigned v.s. signed for
> no particular reason).
>
> But I think just leaving this part as it is is better here...
>
> > [...]
> >> +    if (!name)
> >> +            BUG("could not get a type name for 'enum object_type' value %d", type);
> >> +
> >
> > The return value of `type_name(type)` has not been checked for the original
> > implement, how about write a online inline-function in a header file like this:
>
> Yes, this part is not a faithful conversion on my part, but I think it
> made sense when converting this to a library function.
>
> The alternative is that we'd segfault on some platforms (not glibc,
> since it's OK with null %s arguments), just checking it is cheap & I
> think a good sanity check...

After sending the last email, I was offline for over a week due to an
emergency at home.

According to the rest patches of this series, your implementation of
"format_object_header()" which uses "enum object_type" as the
parameter instead of "char *type" is better.  And adding a validation
for `type_name(type)` is also better than my one-line inline function.
This series of patches LGTM.

--
Jiang Xin

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2022-03-01  3:09 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-01 14:53 [PATCH 00/10] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
2022-02-01 14:53 ` [PATCH 01/10] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
2022-02-01 14:53 ` [PATCH 02/10] object-file API: return "void", not "int" from hash_object_file() Ævar Arnfjörð Bjarmason
2022-02-01 14:53 ` [PATCH 03/10] object-file API: add a format_object_header() function Ævar Arnfjörð Bjarmason
2022-02-01 14:53 ` [PATCH 04/10] object-file API: have write_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
2022-02-01 18:58   ` Junio C Hamano
2022-02-01 14:53 ` [PATCH 05/10] object-file API: provide a hash_object_file_oideq() Ævar Arnfjörð Bjarmason
2022-02-01 19:08   ` Junio C Hamano
2022-02-01 20:56     ` Ævar Arnfjörð Bjarmason
2022-02-01 14:53 ` [PATCH 06/10] object-file API: replace some use of check_object_signature() Ævar Arnfjörð Bjarmason
2022-02-01 19:16   ` Junio C Hamano
2022-02-01 14:53 ` [PATCH 07/10] object-file API: have hash_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
2022-02-01 14:53 ` [PATCH 08/10] object-file API: replace check_object_signature() with stream_* Ævar Arnfjörð Bjarmason
2022-02-01 14:53 ` [PATCH 09/10] object-file.c: add a literal version of write_object_file_prepare() Ævar Arnfjörð Bjarmason
2022-02-01 14:53 ` [PATCH 10/10] object-file API: pass an enum to read_object_with_reference() Ævar Arnfjörð Bjarmason
2022-02-04 13:51 ` [PATCH v2 00/11] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
2022-02-04 13:51   ` [PATCH v2 01/11] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
2022-02-04 13:51   ` [PATCH v2 02/11] object-file API: return "void", not "int" from hash_object_file() Ævar Arnfjörð Bjarmason
2022-02-04 13:51   ` [PATCH v2 03/11] object-file API: add a format_object_header() function Ævar Arnfjörð Bjarmason
2022-02-04 13:51   ` [PATCH v2 04/11] object-file API: have write_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
2022-02-04 20:52     ` Junio C Hamano
2022-02-04 13:51   ` [PATCH v2 05/11] object API: correct "buf" v.s. "map" mismatch in *.c and *.h Ævar Arnfjörð Bjarmason
2022-02-04 20:54     ` Junio C Hamano
2022-02-04 13:51   ` [PATCH v2 06/11] object API: make check_object_signature() oideq()-like, move docs Ævar Arnfjörð Bjarmason
2022-02-04 21:15     ` Junio C Hamano
2022-02-04 13:51   ` [PATCH v2 07/11] object-file API: split up and simplify check_object_signature() Ævar Arnfjörð Bjarmason
2022-02-04 13:51   ` [PATCH v2 08/11] object API: rename hash_object_file_literally() to write_*() Ævar Arnfjörð Bjarmason
2022-02-04 13:51   ` [PATCH v2 09/11] object-file API: have hash_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
2022-02-04 13:51   ` [PATCH v2 10/11] object-file.c: add a literal version of write_object_file_prepare() Ævar Arnfjörð Bjarmason
2022-02-04 13:51   ` [PATCH v2 11/11] object-file API: pass an enum to read_object_with_reference() Ævar Arnfjörð Bjarmason
2022-02-04 23:48   ` [PATCH v3 00/12] object-file API: pass object enums, tidy up streaming interface Ævar Arnfjörð Bjarmason
2022-02-04 23:48     ` [PATCH v3 01/12] object-file.c: split up declaration of unrelated variables Ævar Arnfjörð Bjarmason
2022-02-04 23:48     ` [PATCH v3 02/12] object-file API: return "void", not "int" from hash_object_file() Ævar Arnfjörð Bjarmason
2022-02-04 23:48     ` [PATCH v3 03/12] object-file API: add a format_object_header() function Ævar Arnfjörð Bjarmason
2022-02-17  4:59       ` Jiang Xin
2022-02-17  9:21         ` Ævar Arnfjörð Bjarmason
2022-03-01  3:09           ` Jiang Xin
2022-02-04 23:48     ` [PATCH v3 04/12] object-file API: have write_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
2022-02-04 23:48     ` [PATCH v3 05/12] object API: correct "buf" v.s. "map" mismatch in *.c and *.h Ævar Arnfjörð Bjarmason
2022-02-04 23:48     ` [PATCH v3 06/12] object API docs: move check_object_signature() docs to cache.h Ævar Arnfjörð Bjarmason
2022-02-04 23:48     ` [PATCH v3 07/12] object API users + docs: check <0, not !0 with check_object_signature() Ævar Arnfjörð Bjarmason
2022-02-04 23:48     ` [PATCH v3 08/12] object-file API: split up and simplify check_object_signature() Ævar Arnfjörð Bjarmason
2022-02-04 23:48     ` [PATCH v3 09/12] object API: rename hash_object_file_literally() to write_*() Ævar Arnfjörð Bjarmason
2022-02-04 23:48     ` [PATCH v3 10/12] object-file API: have hash_object_file() take "enum object_type" Ævar Arnfjörð Bjarmason
2022-02-04 23:48     ` [PATCH v3 11/12] object-file.c: add a literal version of write_object_file_prepare() Ævar Arnfjörð Bjarmason
2022-02-04 23:48     ` [PATCH v3 12/12] object-file API: pass an enum to read_object_with_reference() Ævar Arnfjörð Bjarmason

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).