Git development
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Cc: Patrick Steinhardt <ps@pks.im>,
	"brian m. carlson" <sandals@crustytoothpaste.net>,
	Junio C Hamano <gitster@pobox.com>
Subject: [PATCH v2 4/7] hash: make git_hash_discard() idempotent
Date: Tue, 7 Jul 2026 23:52:57 -0400	[thread overview]
Message-ID: <20260708035257.GD41620@coredump.intra.peff.net> (raw)
In-Reply-To: <20260708035235.GA41491@coredump.intra.peff.net>

You must always either finalize or discard a hash context to release any
resources, but you must call only one such function. This creates extra
work for some callers, since their cleanup code paths need to know
whether they got there via their happy path (and the finalization
happened) or due to an error (in which case they need to discard).

Let's add an "active" flag that turns a redundant discard into a noop.
That lets you safely do this:

    git_hash_init(&ctx, algo);
    ...
    if (some_error)
            goto out;
    ...
    git_hash_final(result, &ctx);

  out:
    git_hash_discard(&ctx);

This should avoid future errors, and will also let us simplify a few
existing callers (in future patches).

Signed-off-by: Jeff King <peff@peff.net>
---
 hash.c | 6 ++++++
 hash.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/hash.c b/hash.c
index 55d1d41770..b1296f0018 100644
--- a/hash.c
+++ b/hash.c
@@ -285,6 +285,7 @@ void git_hash_free(struct git_hash_ctx *ctx)
 void git_hash_init(struct git_hash_ctx *ctx, const struct git_hash_algo *algop)
 {
 	algop->init_fn(ctx);
+	ctx->active = true;
 }
 
 void git_hash_clone(struct git_hash_ctx *dst, const struct git_hash_ctx *src)
@@ -300,16 +301,21 @@ void git_hash_update(struct git_hash_ctx *ctx, const void *in, size_t len)
 void git_hash_final(unsigned char *hash, struct git_hash_ctx *ctx)
 {
 	ctx->algop->final_fn(hash, ctx);
+	ctx->active = false;
 }
 
 void git_hash_final_oid(struct object_id *oid, struct git_hash_ctx *ctx)
 {
 	ctx->algop->final_oid_fn(oid, ctx);
+	ctx->active = false;
 }
 
 void git_hash_discard(struct git_hash_ctx *ctx)
 {
+	if (!ctx->active)
+		return;
 	ctx->algop->discard_fn(ctx);
+	ctx->active = false;
 }
 
 uint32_t hash_algo_by_name(const char *name)
diff --git a/hash.h b/hash.h
index 121ecf13aa..cf94ad5700 100644
--- a/hash.h
+++ b/hash.h
@@ -281,6 +281,7 @@ struct git_hash_ctx {
 		git_SHA_CTX_unsafe sha1_unsafe;
 		git_SHA256_CTX sha256;
 	} state;
+	bool active;
 };
 
 typedef void (*git_hash_init_fn)(struct git_hash_ctx *ctx);
-- 
2.55.0.459.g1b256877c9


  parent reply	other threads:[~2026-07-08  3:52 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-07  4:55 [PATCH 0/7] git_hash_*() quality-of-life improvements Jeff King
2026-07-07  5:01 ` [PATCH 1/7] hash: use git_hash_init() consistently Jeff King
2026-07-07 14:39   ` Junio C Hamano
2026-07-07 20:13     ` Jeff King
2026-07-07 20:17       ` Junio C Hamano
2026-07-07 20:25         ` Jeff King
2026-07-07 21:25   ` brian m. carlson
2026-07-08  3:54     ` Jeff King
2026-07-07  5:04 ` [PATCH 2/7] hash: convert remaining direct function calls Jeff King
2026-07-07 16:15   ` Junio C Hamano
2026-07-07  5:05 ` [PATCH 3/7] hash: document function pointers and wrappers Jeff King
2026-07-07 14:26   ` Patrick Steinhardt
2026-07-07 20:05     ` Jeff King
2026-07-07  5:07 ` [PATCH 4/7] hash: make git_hash_discard() idempotent Jeff King
2026-07-07 16:22   ` Junio C Hamano
2026-07-07 20:18     ` Jeff King
2026-07-07 21:41       ` brian m. carlson
2026-07-07 22:25         ` Junio C Hamano
2026-07-07  5:07 ` [PATCH 5/7] csum-file: use idempotent git_hash_discard() Jeff King
2026-07-07  5:08 ` [PATCH 6/7] http: " Jeff King
2026-07-07 16:25   ` Junio C Hamano
2026-07-07  5:09 ` [PATCH 7/7] hash: check ctx->active flag in all wrapper functions Jeff King
2026-07-07 14:26   ` Patrick Steinhardt
2026-07-07 16:33   ` Junio C Hamano
2026-07-07 20:10     ` Jeff King
2026-07-07 14:26 ` [PATCH 0/7] git_hash_*() quality-of-life improvements Patrick Steinhardt
2026-07-08  3:52 ` [PATCH v2 " Jeff King
2026-07-08  3:52   ` [PATCH v2 1/7] hash: use git_hash_init() consistently Jeff King
2026-07-08  3:52   ` [PATCH v2 2/7] hash: convert remaining direct function calls Jeff King
2026-07-08  3:52   ` [PATCH v2 3/7] hash: document function pointers and wrappers Jeff King
2026-07-08  3:52   ` Jeff King [this message]
2026-07-08  3:53   ` [PATCH v2 5/7] csum-file: use idempotent git_hash_discard() Jeff King
2026-07-08  3:53   ` [PATCH v2 6/7] http: " Jeff King
2026-07-08  3:53   ` [PATCH v2 7/7] hash: check ctx->active flag in all wrapper functions Jeff King
2026-07-08  8:05   ` [PATCH v2 0/7] git_hash_*() quality-of-life improvements Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260708035257.GD41620@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=ps@pks.im \
    --cc=sandals@crustytoothpaste.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox