From: Phillip Wood <phillip.wood123@gmail.com>
To: Karthik Nayak <karthik.188@gmail.com>, git@vger.kernel.org
Cc: ps@pks.im, jltobler@gmail.com, phillip.wood123@gmail.com
Subject: Re: [PATCH v2 6/7] refs: implement partial reference transaction support
Date: Tue, 25 Feb 2025 14:57:47 +0000 [thread overview]
Message-ID: <2755fb78-d587-4ad9-b22f-b60dfa752d7a@gmail.com> (raw)
In-Reply-To: <20250225-245-partially-atomic-ref-updates-v2-6-cfa3236895d7@gmail.com>
Hi Karthik
On 25/02/2025 09:29, Karthik Nayak wrote:
> Git's reference transactions are all-or-nothing: either all updates
> succeed, or none do. While this atomic behavior is generally desirable,
> it can be suboptimal especially when using the reftable backend, where
> batching multiple reference updates into a single transaction is more
> efficient than performing them sequentially.
>
> Introduce partial transaction support with a new flag,
> 'REF_TRANSACTION_ALLOW_PARTIAL'. When enabled, this flag allows
> individual reference updates that would typically cause the entire
> transaction to fail due to non-system-related errors to be marked as
> rejected while permitting other updates to proceed. Non-system-related
> errors include issues caused by user-provided input values, whereas
> system-related errors, such as I/O failures or memory issues, continue
> to result in a full transaction failure. This approach enhances
> flexibility while preserving transactional integrity where necessary.
>
> The implementation introduces several key components:
>
> - Add 'rejection_err' field to struct `ref_update` to track failed
> updates with failure reason.
>
> - Modify reference backends (files, packed, reftable) to handle
> partial transactions by using `ref_transaction_set_rejected()`
> instead of failing the entire transaction when
> `REF_TRANSACTION_ALLOW_PARTIAL` is set.
>
> - Add `ref_transaction_for_each_rejected_update()` to let callers
> examine which updates were rejected and why.
I think this is a much better design. I wonder if we want to signal to
the caller of ref_transaction_commit() that there were ignored errors
rather than forcing them to call ref_transaction_for_each_rejected() to
find that out. Another possibility would be to call the callback from
ref_transaction_commit() but that would mean changing the signature of
ref_transaction_begin() to take the callback and user data when
REF_TRANSACTION_ALLOW_PARTIAL is passed.
Best Wishes
Phillip
> This foundational change enables partial transaction support throughout
> the reference subsystem. The next commit will expose this capability to
> users by adding a `--allow-partial` flag to 'git-update-ref(1)',
> providing both a user-facing feature and a testable implementation.
>
> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
> ---
> refs.c | 31 +++++++++++++++++++++++++++++++
> refs.h | 22 ++++++++++++++++++++++
> refs/files-backend.c | 12 +++++++++++-
> refs/packed-backend.c | 30 ++++++++++++++++++++++++++++--
> refs/refs-internal.h | 13 +++++++++++++
> refs/reftable-backend.c | 12 +++++++++++-
> 6 files changed, 116 insertions(+), 4 deletions(-)
>
> diff --git a/refs.c b/refs.c
> index f989a46a5a..243c09c368 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -1211,6 +1211,15 @@ void ref_transaction_free(struct ref_transaction *transaction)
> free(transaction);
> }
>
> +void ref_transaction_set_rejected(struct ref_transaction *transaction,
> + size_t update_idx,
> + enum transaction_error err)
> +{
> + if (update_idx >= transaction->nr)
> + BUG("trying to set rejection on invalid update index");
> + transaction->updates[update_idx]->rejection_err = err;
> +}
> +
> struct ref_update *ref_transaction_add_update(
> struct ref_transaction *transaction,
> const char *refname, unsigned int flags,
> @@ -1236,6 +1245,7 @@ struct ref_update *ref_transaction_add_update(
> transaction->updates[transaction->nr++] = update;
>
> update->flags = flags;
> + update->rejection_err = TRANSACTION_OK;
>
> update->new_target = xstrdup_or_null(new_target);
> update->old_target = xstrdup_or_null(old_target);
> @@ -2726,6 +2736,27 @@ void ref_transaction_for_each_queued_update(struct ref_transaction *transaction,
> }
> }
>
> +void ref_transaction_for_each_rejected_update(struct ref_transaction *transaction,
> + ref_transaction_for_each_rejected_update_fn cb,
> + void *cb_data)
> +{
> + if (!(transaction->flags & REF_TRANSACTION_ALLOW_PARTIAL))
> + return;
> +
> + for (size_t i = 0; i < transaction->nr; i++) {
> + struct ref_update *update = transaction->updates[i];
> +
> + if (!update->rejection_err)
> + continue;
> +
> + cb(update->refname,
> + (update->flags & REF_HAVE_OLD) ? &update->old_oid : NULL,
> + (update->flags & REF_HAVE_NEW) ? &update->new_oid : NULL,
> + update->old_target, update->new_target,
> + update->rejection_err, cb_data);
> + }
> +}
> +
> int refs_delete_refs(struct ref_store *refs, const char *logmsg,
> struct string_list *refnames, unsigned int flags)
> {
> diff --git a/refs.h b/refs.h
> index 8e9ead174c..e4a6a8218f 100644
> --- a/refs.h
> +++ b/refs.h
> @@ -675,6 +675,13 @@ enum ref_transaction_flag {
> * either be absent or null_oid.
> */
> REF_TRANSACTION_FLAG_INITIAL = (1 << 0),
> +
> + /*
> + * The transaction mechanism by default fails all updates if any conflict
> + * is detected. This flag allows transactions to partially apply updates
> + * while rejecting updates which do not match the expected state.
> + */
> + REF_TRANSACTION_ALLOW_PARTIAL = (1 << 1),
> };
>
> /*
> @@ -905,6 +912,21 @@ void ref_transaction_for_each_queued_update(struct ref_transaction *transaction,
> ref_transaction_for_each_queued_update_fn cb,
> void *cb_data);
>
> +/*
> + * Execute the given callback function for each of the reference updates which
> + * have been rejected in the given transaction.
> + */
> +typedef void ref_transaction_for_each_rejected_update_fn(const char *refname,
> + const struct object_id *old_oid,
> + const struct object_id *new_oid,
> + const char *old_target,
> + const char *new_target,
> + enum transaction_error err,
> + void *cb_data);
> +void ref_transaction_for_each_rejected_update(struct ref_transaction *transaction,
> + ref_transaction_for_each_rejected_update_fn cb,
> + void *cb_data);
> +
> /*
> * Free `*transaction` and all associated data.
> */
> diff --git a/refs/files-backend.c b/refs/files-backend.c
> index 3b0adf8bb2..d0a53c9ace 100644
> --- a/refs/files-backend.c
> +++ b/refs/files-backend.c
> @@ -2851,8 +2851,18 @@ static int files_transaction_prepare(struct ref_store *ref_store,
> ret = lock_ref_for_update(refs, update, transaction,
> head_ref, &refnames_to_check,
> err);
> - if (ret)
> + if (ret) {
> + if (transaction->flags & REF_TRANSACTION_ALLOW_PARTIAL &&
> + ret != TRANSACTION_GENERIC_ERROR) {
> + ref_transaction_set_rejected(transaction, i, ret);
> +
> + strbuf_setlen(err, 0);
> + ret = TRANSACTION_OK;
> +
> + continue;
> + }
> goto cleanup;
> + }
>
> if (update->flags & REF_DELETING &&
> !(update->flags & REF_LOG_ONLY) &&
> diff --git a/refs/packed-backend.c b/refs/packed-backend.c
> index 75e1ebf67d..0857204213 100644
> --- a/refs/packed-backend.c
> +++ b/refs/packed-backend.c
> @@ -1324,10 +1324,11 @@ static int packed_ref_store_remove_on_disk(struct ref_store *ref_store,
> * remain locked when it is done.
> */
> static enum transaction_error write_with_updates(struct packed_ref_store *refs,
> - struct string_list *updates,
> + struct ref_transaction *transaction,
> struct strbuf *err)
> {
> enum transaction_error ret = TRANSACTION_GENERIC_ERROR;
> + struct string_list *updates = &transaction->refnames;
> struct ref_iterator *iter = NULL;
> size_t i;
> int ok;
> @@ -1408,6 +1409,14 @@ static enum transaction_error write_with_updates(struct packed_ref_store *refs,
> "reference already exists",
> update->refname);
> ret = TRANSACTION_CREATE_EXISTS;
> +
> + if (transaction->flags & REF_TRANSACTION_ALLOW_PARTIAL) {
> + ref_transaction_set_rejected(transaction, i, ret);
> + strbuf_setlen(err, 0);
> + ret = 0;
> + continue;
> + }
> +
> goto error;
> } else if (!oideq(&update->old_oid, iter->oid)) {
> strbuf_addf(err, "cannot update ref '%s': "
> @@ -1416,6 +1425,14 @@ static enum transaction_error write_with_updates(struct packed_ref_store *refs,
> oid_to_hex(iter->oid),
> oid_to_hex(&update->old_oid));
> ret = TRANSACTION_INCORRECT_OLD_VALUE;
> +
> + if (transaction->flags & REF_TRANSACTION_ALLOW_PARTIAL) {
> + ref_transaction_set_rejected(transaction, i, ret);
> + strbuf_setlen(err, 0);
> + ret = 0;
> + continue;
> + }
> +
> goto error;
> }
> }
> @@ -1453,6 +1470,14 @@ static enum transaction_error write_with_updates(struct packed_ref_store *refs,
> update->refname,
> oid_to_hex(&update->old_oid));
> return TRANSACTION_NONEXISTENT_REF;
> +
> + if (transaction->flags & REF_TRANSACTION_ALLOW_PARTIAL) {
> + ref_transaction_set_rejected(transaction, i, ret);
> + strbuf_setlen(err, 0);
> + ret = 0;
> + continue;
> + }
> +
> goto error;
> }
> }
> @@ -1518,6 +1543,7 @@ static enum transaction_error write_with_updates(struct packed_ref_store *refs,
> write_error:
> strbuf_addf(err, "error writing to %s: %s",
> get_tempfile_path(refs->tempfile), strerror(errno));
> + ret = TRANSACTION_GENERIC_ERROR;
>
> error:
> ref_iterator_free(iter);
> @@ -1676,7 +1702,7 @@ static int packed_transaction_prepare(struct ref_store *ref_store,
> data->own_lock = 1;
> }
>
> - ret = write_with_updates(refs, &transaction->refnames, err);
> + ret = write_with_updates(refs, transaction, err);
> if (ret)
> goto failure;
>
> diff --git a/refs/refs-internal.h b/refs/refs-internal.h
> index c97045fbed..7196f2d880 100644
> --- a/refs/refs-internal.h
> +++ b/refs/refs-internal.h
> @@ -123,6 +123,11 @@ struct ref_update {
> */
> uint64_t index;
>
> + /*
> + * Used in partial transactions to mark if a given update was rejected.
> + */
> + enum transaction_error rejection_err;
> +
> /*
> * If this ref_update was split off of a symref update via
> * split_symref_update(), then this member points at that
> @@ -142,6 +147,14 @@ int refs_read_raw_ref(struct ref_store *ref_store, const char *refname,
> struct object_id *oid, struct strbuf *referent,
> unsigned int *type, int *failure_errno);
>
> +/*
> + * Mark a given update as rejected with a given reason. To be used in conjuction
> + * with the `REF_TRANSACTION_ALLOW_PARTIAL` flag to allow partial transactions.
> + */
> +void ref_transaction_set_rejected(struct ref_transaction *transaction,
> + size_t update_idx,
> + enum transaction_error err);
> +
> /*
> * Add a ref_update with the specified properties to transaction, and
> * return a pointer to the new object. This function does not verify
> diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
> index e1fd9c2de2..83cf8d582b 100644
> --- a/refs/reftable-backend.c
> +++ b/refs/reftable-backend.c
> @@ -1374,8 +1374,18 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store,
> transaction->updates[i],
> &refnames_to_check, head_type,
> &head_referent, &referent, err);
> - if (ret)
> + if (ret) {
> + if (transaction->flags & REF_TRANSACTION_ALLOW_PARTIAL &&
> + ret != TRANSACTION_GENERIC_ERROR) {
> + ref_transaction_set_rejected(transaction, i, ret);
> +
> + strbuf_setlen(err, 0);
> + ret = TRANSACTION_OK;
> +
> + continue;
> + }
> goto done;
> + }
> }
>
> string_list_sort(&refnames_to_check);
>
next prev parent reply other threads:[~2025-02-25 14:57 UTC|newest]
Thread overview: 147+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-07 7:34 [PATCH 0/6] refs: introduce support for partial reference transactions Karthik Nayak
2025-02-07 7:34 ` [PATCH 1/6] refs/files: remove duplicate check in `split_symref_update()` Karthik Nayak
2025-02-07 16:12 ` Patrick Steinhardt
2025-02-11 6:35 ` Karthik Nayak
2025-02-07 7:34 ` [PATCH 2/6] refs: move duplicate refname update check to generic layer Karthik Nayak
2025-02-07 16:12 ` Patrick Steinhardt
2025-02-11 10:33 ` Karthik Nayak
2025-02-07 7:34 ` [PATCH 3/6] refs/files: remove duplicate duplicates check Karthik Nayak
2025-02-07 16:12 ` Patrick Steinhardt
2025-02-07 7:34 ` [PATCH 4/6] refs/reftable: extract code from the transaction preparation Karthik Nayak
2025-02-07 7:34 ` [PATCH 5/6] refs: implement partial reference transaction support Karthik Nayak
2025-02-07 16:12 ` Patrick Steinhardt
2025-02-21 10:33 ` Karthik Nayak
2025-02-07 7:34 ` [PATCH 6/6] update-ref: add --allow-partial flag for stdin mode Karthik Nayak
2025-02-07 16:12 ` Patrick Steinhardt
2025-02-21 11:45 ` Karthik Nayak
2025-02-11 17:03 ` [PATCH 0/6] refs: introduce support for partial reference transactions Phillip Wood
2025-02-11 17:40 ` Phillip Wood
2025-02-12 12:36 ` Karthik Nayak
2025-02-12 12:34 ` Karthik Nayak
2025-02-19 14:34 ` Phillip Wood
2025-02-19 15:10 ` Patrick Steinhardt
2025-02-21 11:50 ` Karthik Nayak
2025-02-25 9:29 ` [PATCH v2 0/7] " Karthik Nayak
2025-02-25 9:29 ` [PATCH v2 1/7] refs/files: remove redundant check in split_symref_update() Karthik Nayak
2025-02-25 9:29 ` [PATCH v2 2/7] refs: move duplicate refname update check to generic layer Karthik Nayak
2025-02-25 9:29 ` [PATCH v2 3/7] refs/files: remove duplicate duplicates check Karthik Nayak
2025-02-25 9:29 ` [PATCH v2 4/7] refs/reftable: extract code from the transaction preparation Karthik Nayak
2025-02-25 9:29 ` [PATCH v2 5/7] refs: introduce enum-based transaction error types Karthik Nayak
2025-02-25 11:08 ` Patrick Steinhardt
2025-03-03 20:12 ` Karthik Nayak
2025-02-25 9:29 ` [PATCH v2 6/7] refs: implement partial reference transaction support Karthik Nayak
2025-02-25 11:07 ` Patrick Steinhardt
2025-03-03 20:17 ` Karthik Nayak
2025-02-25 14:57 ` Phillip Wood [this message]
2025-03-03 20:21 ` Karthik Nayak
2025-03-04 10:31 ` Phillip Wood
2025-03-05 14:20 ` Karthik Nayak
2025-02-25 9:29 ` [PATCH v2 7/7] update-ref: add --allow-partial flag for stdin mode Karthik Nayak
2025-02-25 11:08 ` Patrick Steinhardt
2025-03-03 20:22 ` Karthik Nayak
2025-02-25 14:59 ` Phillip Wood
2025-03-03 20:34 ` Karthik Nayak
2025-03-05 17:38 ` [PATCH v3 0/8] refs: introduce support for partial reference transactions Karthik Nayak
2025-03-05 17:38 ` [PATCH v3 1/8] refs/files: remove redundant check in split_symref_update() Karthik Nayak
2025-03-05 21:20 ` Junio C Hamano
2025-03-06 9:13 ` Karthik Nayak
2025-03-05 17:38 ` [PATCH v3 2/8] refs: move duplicate refname update check to generic layer Karthik Nayak
2025-03-05 21:56 ` Junio C Hamano
2025-03-06 9:46 ` Karthik Nayak
2025-03-05 17:38 ` [PATCH v3 3/8] refs/files: remove duplicate duplicates check Karthik Nayak
2025-03-05 17:38 ` [PATCH v3 4/8] refs/reftable: extract code from the transaction preparation Karthik Nayak
2025-03-05 17:39 ` [PATCH v3 5/8] refs: introduce enum-based transaction error types Karthik Nayak
2025-03-05 17:39 ` [PATCH v3 6/8] refs: implement partial reference transaction support Karthik Nayak
2025-03-07 19:50 ` Jeff King
2025-03-07 20:46 ` Junio C Hamano
2025-03-07 20:48 ` Junio C Hamano
2025-03-07 21:05 ` Karthik Nayak
2025-03-07 22:54 ` [PATCH] config.mak.dev: enable -Wunreachable-code Jeff King
2025-03-07 23:28 ` Junio C Hamano
2025-03-08 3:23 ` Jeff King
2025-03-10 15:40 ` Junio C Hamano
2025-03-10 16:04 ` Jeff King
2025-03-10 18:50 ` Junio C Hamano
2025-03-14 16:10 ` Jeff King
2025-03-14 16:13 ` Jeff King
2025-03-14 17:27 ` Junio C Hamano
2025-03-14 17:40 ` Junio C Hamano
2025-03-14 17:43 ` Patrick Steinhardt
2025-03-14 18:53 ` Jeff King
2025-03-14 19:50 ` Junio C Hamano
2025-03-14 17:15 ` Junio C Hamano
2025-06-03 21:29 ` Mike Hommey
2025-06-03 22:07 ` Junio C Hamano
2025-06-03 22:37 ` Mike Hommey
2025-06-03 23:08 ` Mike Hommey
2025-03-14 21:09 ` [PATCH v2 0/3] -Wunreachable-code Junio C Hamano
2025-03-14 21:09 ` [PATCH v2 1/3] config.mak.dev: enable -Wunreachable-code Junio C Hamano
2025-03-14 21:09 ` [PATCH v2 2/3] run-command: use errno to check for sigfillset() error Junio C Hamano
2025-03-17 21:30 ` Taylor Blau
2025-03-17 23:12 ` Junio C Hamano
2025-03-18 0:36 ` Junio C Hamano
2025-03-14 21:09 ` [PATCH v2 3/3] git-compat-util: add NOT_A_CONST macro and use it in atfork_prepare() Junio C Hamano
2025-03-14 22:29 ` Junio C Hamano
2025-03-17 18:00 ` Jeff King
2025-03-17 23:53 ` [PATCH v3 0/3] -Wunreachable-code Junio C Hamano
2025-03-17 23:53 ` [PATCH v3 1/3] run-command: use errno to check for sigfillset() error Junio C Hamano
2025-03-17 23:53 ` [PATCH v3 2/3] git-compat-util: add NOT_CONSTANT macro and use it in atfork_prepare() Junio C Hamano
2025-03-18 0:20 ` Jeff King
2025-03-18 0:28 ` Junio C Hamano
2025-03-18 22:04 ` Calvin Wan
2025-03-18 22:26 ` Calvin Wan
2025-03-18 23:55 ` Junio C Hamano
2025-03-17 23:53 ` [PATCH v3 3/3] config.mak.dev: enable -Wunreachable-code Junio C Hamano
2025-03-18 0:18 ` [PATCH v3 0/3] -Wunreachable-code Jeff King
2025-03-07 21:02 ` [PATCH v3 6/8] refs: implement partial reference transaction support Karthik Nayak
2025-03-07 19:57 ` Jeff King
2025-03-07 21:07 ` Karthik Nayak
2025-03-05 17:39 ` [PATCH v3 7/8] refs: support partial update rejections during F/D checks Karthik Nayak
2025-03-05 17:39 ` [PATCH v3 8/8] update-ref: add --allow-partial flag for stdin mode Karthik Nayak
2025-03-05 19:28 ` [PATCH v3 0/8] refs: introduce support for partial reference transactions Junio C Hamano
2025-03-06 9:06 ` Karthik Nayak
2025-03-20 11:43 ` [PATCH v4 0/8] refs: introduce support for batched reference updates Karthik Nayak
2025-03-20 11:43 ` [PATCH v4 1/8] refs/files: remove redundant check in split_symref_update() Karthik Nayak
2025-03-20 11:43 ` [PATCH v4 2/8] refs: move duplicate refname update check to generic layer Karthik Nayak
2025-03-20 11:43 ` [PATCH v4 3/8] refs/files: remove duplicate duplicates check Karthik Nayak
2025-03-20 11:43 ` [PATCH v4 4/8] refs/reftable: extract code from the transaction preparation Karthik Nayak
2025-03-20 11:44 ` [PATCH v4 5/8] refs: introduce enum-based transaction error types Karthik Nayak
2025-03-20 20:26 ` Patrick Steinhardt
2025-03-24 14:50 ` Karthik Nayak
2025-03-25 12:31 ` Patrick Steinhardt
2025-03-20 11:44 ` [PATCH v4 6/8] refs: implement batch reference update support Karthik Nayak
2025-03-20 20:26 ` Patrick Steinhardt
2025-03-24 14:54 ` Karthik Nayak
2025-03-20 11:44 ` [PATCH v4 7/8] refs: support rejection in batch updates during F/D checks Karthik Nayak
2025-03-24 13:08 ` Patrick Steinhardt
2025-03-24 17:48 ` Karthik Nayak
2025-03-25 12:31 ` Patrick Steinhardt
2025-03-20 11:44 ` [PATCH v4 8/8] update-ref: add --batch-updates flag for stdin mode Karthik Nayak
2025-03-24 13:08 ` Patrick Steinhardt
2025-03-24 17:51 ` Karthik Nayak
2025-03-27 11:13 ` [PATCH v5 0/8] refs: introduce support for batched reference updates Karthik Nayak
2025-03-27 11:13 ` [PATCH v5 1/8] refs/files: remove redundant check in split_symref_update() Karthik Nayak
2025-03-27 11:13 ` [PATCH v5 2/8] refs: move duplicate refname update check to generic layer Karthik Nayak
2025-03-27 11:13 ` [PATCH v5 3/8] refs/files: remove duplicate duplicates check Karthik Nayak
2025-03-27 11:13 ` [PATCH v5 4/8] refs/reftable: extract code from the transaction preparation Karthik Nayak
2025-03-27 11:13 ` [PATCH v5 5/8] refs: introduce enum-based transaction error types Karthik Nayak
2025-03-27 11:13 ` [PATCH v5 6/8] refs: implement batch reference update support Karthik Nayak
2025-03-27 11:13 ` [PATCH v5 7/8] refs: support rejection in batch updates during F/D checks Karthik Nayak
2025-03-27 11:13 ` [PATCH v5 8/8] update-ref: add --batch-updates flag for stdin mode Karthik Nayak
2025-03-28 13:00 ` Jean-Noël AVILA
2025-03-29 16:36 ` Junio C Hamano
2025-03-29 18:18 ` Karthik Nayak
2025-03-28 9:24 ` [PATCH v5 0/8] refs: introduce support for batched reference updates Patrick Steinhardt
2025-04-08 8:51 ` [PATCH v6 " Karthik Nayak
2025-04-08 8:51 ` [PATCH v6 1/8] refs/files: remove redundant check in split_symref_update() Karthik Nayak
2025-04-08 8:51 ` [PATCH v6 2/8] refs: move duplicate refname update check to generic layer Karthik Nayak
2025-04-08 8:51 ` [PATCH v6 3/8] refs/files: remove duplicate duplicates check Karthik Nayak
2025-04-08 8:51 ` [PATCH v6 4/8] refs/reftable: extract code from the transaction preparation Karthik Nayak
2025-04-08 8:51 ` [PATCH v6 5/8] refs: introduce enum-based transaction error types Karthik Nayak
2025-04-08 8:51 ` [PATCH v6 6/8] refs: implement batch reference update support Karthik Nayak
2025-04-08 8:51 ` [PATCH v6 7/8] refs: support rejection in batch updates during F/D checks Karthik Nayak
2025-04-08 8:51 ` [PATCH v6 8/8] update-ref: add --batch-updates flag for stdin mode Karthik Nayak
2025-04-08 15:02 ` Junio C Hamano
2025-04-08 15:26 ` Karthik Nayak
2025-04-08 17:37 ` Junio C Hamano
2025-04-10 11:23 ` Karthik Nayak
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=2755fb78-d587-4ad9-b22f-b60dfa752d7a@gmail.com \
--to=phillip.wood123@gmail.com \
--cc=git@vger.kernel.org \
--cc=jltobler@gmail.com \
--cc=karthik.188@gmail.com \
--cc=phillip.wood@dunelm.org.uk \
--cc=ps@pks.im \
/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;
as well as URLs for NNTP newsgroup(s).