hash: document function pointers and wrappers

We want people to use the git_hash_*() wrappers rather than the bare function pointers in the git_hash_algo struct. Let's document them rather than the bare pointers, and warn people away from the pointers. Coccinelle will eventually force the use of the wrappers, but it's helpful to lead readers in the right direction from the start. While we're here we can document a few other bits of wisdom I've turned up while working in this area: - You have to initialize the destination of a git_hash_clone(). This is something we may eventually change for efficiency, but we should definitely document the requirement for now. - You must eventually finalize or discard a hash, since some backends may allocate resources during initialization. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Jul 7, 2026 at 23:52 UTC 90a55e3a51525370798d9b484a74a51ad2b3f047
1 file changed +32 -11
hash.h
+32 -11
@@ -309,22 +309,15 @@ struct git_hash_algo {
309 /* The block size of the hash. */
310 size_t blksz;
311
312 - /* The hash initialization function. */
312 + /*
313 + * Low-level implementation hooks. Callers should use the git_hash_*
314 + * wrappers below rather than invoking these directly.
315 + */
316 git_hash_init_fn init_fn;
314 -
315 - /* The hash context cloning function. */
317 git_hash_clone_fn clone_fn;
317 -
318 - /* The hash update function. */
318 git_hash_update_fn update_fn;
320 -
321 - /* The hash finalization function. */
319 git_hash_final_fn final_fn;
323 -
324 - /* The hash finalization function for object IDs. */
320 git_hash_final_oid_fn final_oid_fn;
326 -
327 - /* Discard an initialized hash without finalizing. */
321 git_hash_discard_fn discard_fn;
322
323 /* The OID of the empty tree. */
@@ -341,12 +334,40 @@ struct git_hash_algo {
334 };
335 extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];
336
337 +/*
338 + * Prepare an uninitialized hash context for use. You must eventually release
339 + * the context with git_hash_final() (or final_oid()) or by calling
340 + * git_hash_discard().
341 + */
342 void git_hash_init(struct git_hash_ctx *ctx, const struct git_hash_algo *algop);
343 +
344 +/*
345 + * Clone the state of a hash. Both src and dst must have been initialized with
346 + * git_hash_init().
347 + */
348 void git_hash_clone(struct git_hash_ctx *dst, const struct git_hash_ctx *src);
349 +
350 +/*
351 + * Add more data to an initialized hash context.
352 + */
353 void git_hash_update(struct git_hash_ctx *ctx, const void *in, size_t len);
354 +
355 +/*
356 + * Retrieve the final hash value from a context, releasing any resources.
357 + */
358 void git_hash_final(unsigned char *hash, struct git_hash_ctx *ctx);
359 +
360 +/*
361 + * Like git_hash_final(), but write the result into an object_id.
362 + */
363 void git_hash_final_oid(struct object_id *oid, struct git_hash_ctx *ctx);
364 +
365 +/*
366 + * Discard a hash context without computing the final value, but still
367 + * releasing any resources.
368 + */
369 void git_hash_discard(struct git_hash_ctx *ctx);
370 +
371 const struct git_hash_algo *hash_algo_ptr_by_number(uint32_t algo);
372 struct git_hash_ctx *git_hash_alloc(void);
373 void git_hash_free(struct git_hash_ctx *ctx);