From: Phillip Wood <phillip.wood123@gmail.com>
To: Karthik Nayak <karthik.188@gmail.com>, git@vger.kernel.org
Cc: Jeff King <peff@peff.net>, newren@gmail.com, gitster@pobox.com
Subject: Re: [PATCH v3 6/6] fetch: delay user information post committing of transaction
Date: Wed, 21 Jan 2026 16:21:20 +0000 [thread overview]
Message-ID: <67808128-5f41-4ae5-b224-a76048cd82c8@gmail.com> (raw)
In-Reply-To: <20260120-633-regression-lost-diagnostic-message-when-pushing-non-commit-objects-to-refs-heads-v3-6-e0edb29acbef@gmail.com>
Hi Karthik
On 20/01/2026 09:59, Karthik Nayak wrote:
> +struct ref_update_display_info {
> + bool failed;
> + char success_code;
> + char fail_code;
> + const char *summary;
> + const char *fail_detail;
> + const char *success_detail;
> + const char *ref;
> + const char *remote;
> + struct object_id old_oid;
> + struct object_id new_oid;
> +};
I was expecting that we'd pass around a struct like
struct ref_update_display_info_array {
size_t alloc, nr;
ref_update_display_info *info;
};
rather than passing a pointer, count pair as separate parameters. That
would also allow us to use ALLOC_GROW() rather than reallocating the
array each time we append to it which is rather inefficient.
Thanks
Phillip
> +static struct ref_update_display_info *ref_update_display_info_append(
> + struct ref_update_display_info **list,
> + size_t *count,
> + char success_code,
> + char fail_code,
> + const char *summary,
> + const char *success_detail,
> + const char *fail_detail,
> + const char *ref,
> + const char *remote,
> + const struct object_id *old_oid,
> + const struct object_id *new_oid)
> +{
> + struct ref_update_display_info *info;
> + size_t index = *count;
> +
> + (*count)++;
> + REALLOC_ARRAY(*list, *count);
> +
> + info = &(*list)[index];
> +
> + info->failed = false;
> + info->success_code = success_code;
> + info->fail_code = fail_code;
> + info->summary = xstrdup(summary);
> + info->success_detail = xstrdup_or_null(success_detail);
> + info->fail_detail = xstrdup_or_null(fail_detail);
> + info->remote = xstrdup(remote);
> + info->ref = xstrdup(ref);
> +
> + oidcpy(&info->old_oid, old_oid);
> + oidcpy(&info->new_oid, new_oid);
> +
> + return info;
> +}
> +
> +static void ref_update_display_info_set_failed(struct ref_update_display_info *info)
> +{
> + info->failed = true;
> +}
> +
> +static void ref_update_display_info_free(struct ref_update_display_info *info)
> +{
> + free((char *)info->summary);
> + free((char *)info->success_detail);
> + free((char *)info->fail_detail);
> + free((char *)info->remote);
> + free((char *)info->ref);
> +}
> +
> +static void ref_update_display_info_display(struct ref_update_display_info *info,
> + struct display_state *display_state,
> + int summary_width)
> +{
> + display_ref_update(display_state,
> + info->failed ? info->fail_code : info->success_code,
> + info->summary,
> + info->failed ? info->fail_detail : info->success_detail,
> + info->remote, info->ref, &info->old_oid,
> + &info->new_oid, summary_width);
> +}
> +
> static int update_local_ref(struct ref *ref,
> struct ref_transaction *transaction,
> - struct display_state *display_state,
> const struct ref *remote_ref,
> - int summary_width,
> - const struct fetch_config *config)
> + const struct fetch_config *config,
> + struct ref_update_display_info **display_list,
> + size_t *display_count)
> {
> struct commit *current = NULL, *updated;
> int fast_forward = 0;
> @@ -877,41 +952,56 @@ static int update_local_ref(struct ref *ref,
>
> if (oideq(&ref->old_oid, &ref->new_oid)) {
> if (verbosity > 0)
> - display_ref_update(display_state, '=', _("[up to date]"), NULL,
> - remote_ref->name, ref->name,
> - &ref->old_oid, &ref->new_oid, summary_width);
> + ref_update_display_info_append(display_list, display_count,
> + '=', '=', _("[up to date]"),
> + NULL, NULL, ref->name,
> + remote_ref->name, &ref->old_oid,
> + &ref->new_oid);
> return 0;
> }
>
> if (!update_head_ok &&
> !is_null_oid(&ref->old_oid) &&
> branch_checked_out(ref->name)) {
> + struct ref_update_display_info *info;
> /*
> * If this is the head, and it's not okay to update
> * the head, and the old value of the head isn't empty...
> */
> - display_ref_update(display_state, '!', _("[rejected]"),
> - _("can't fetch into checked-out branch"),
> - remote_ref->name, ref->name,
> - &ref->old_oid, &ref->new_oid, summary_width);
> + info = ref_update_display_info_append(display_list, display_count,
> + '!', '!', _("[rejected]"),
> + NULL, _("can't fetch into checked-out branch"),
> + ref->name, remote_ref->name,
> + &ref->old_oid, &ref->new_oid);
> + ref_update_display_info_set_failed(info);
> return 1;
> }
>
> if (!is_null_oid(&ref->old_oid) &&
> starts_with(ref->name, "refs/tags/")) {
> + struct ref_update_display_info *info;
> +
> if (force || ref->force) {
> int r;
> +
> r = s_update_ref("updating tag", ref, transaction, 0);
> - display_ref_update(display_state, r ? '!' : 't', _("[tag update]"),
> - r ? _("unable to update local ref") : NULL,
> - remote_ref->name, ref->name,
> - &ref->old_oid, &ref->new_oid, summary_width);
> +
> + info = ref_update_display_info_append(display_list, display_count,
> + 't', '!', _("[tag update]"), NULL,
> + _("unable to update local ref"),
> + ref->name, remote_ref->name,
> + &ref->old_oid, &ref->new_oid);
> + if (r)
> + ref_update_display_info_set_failed(info);
> +
> return r;
> } else {
> - display_ref_update(display_state, '!', _("[rejected]"),
> - _("would clobber existing tag"),
> - remote_ref->name, ref->name,
> - &ref->old_oid, &ref->new_oid, summary_width);
> + info = ref_update_display_info_append(display_list, display_count,
> + '!', '!', _("[rejected]"), NULL,
> + _("would clobber existing tag"),
> + ref->name, remote_ref->name,
> + &ref->old_oid, &ref->new_oid);
> + ref_update_display_info_set_failed(info);
> return 1;
> }
> }
> @@ -921,6 +1011,7 @@ static int update_local_ref(struct ref *ref,
> updated = lookup_commit_reference_gently(the_repository,
> &ref->new_oid, 1);
> if (!current || !updated) {
> + struct ref_update_display_info *info;
> const char *msg;
> const char *what;
> int r;
> @@ -941,10 +1032,15 @@ static int update_local_ref(struct ref *ref,
> }
>
> r = s_update_ref(msg, ref, transaction, 0);
> - display_ref_update(display_state, r ? '!' : '*', what,
> - r ? _("unable to update local ref") : NULL,
> - remote_ref->name, ref->name,
> - &ref->old_oid, &ref->new_oid, summary_width);
> +
> + info = ref_update_display_info_append(display_list, display_count,
> + '*', '!', what, NULL,
> + _("unable to update local ref"),
> + ref->name, remote_ref->name,
> + &ref->old_oid, &ref->new_oid);
> + if (r)
> + ref_update_display_info_set_failed(info);
> +
> return r;
> }
>
> @@ -960,6 +1056,7 @@ static int update_local_ref(struct ref *ref,
> }
>
> if (fast_forward) {
> + struct ref_update_display_info *info;
> struct strbuf quickref = STRBUF_INIT;
> int r;
>
> @@ -967,29 +1064,46 @@ static int update_local_ref(struct ref *ref,
> strbuf_addstr(&quickref, "..");
> strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
> r = s_update_ref("fast-forward", ref, transaction, 1);
> - display_ref_update(display_state, r ? '!' : ' ', quickref.buf,
> - r ? _("unable to update local ref") : NULL,
> - remote_ref->name, ref->name,
> - &ref->old_oid, &ref->new_oid, summary_width);
> +
> + info = ref_update_display_info_append(display_list, display_count,
> + ' ', '!', quickref.buf, NULL,
> + _("unable to update local ref"),
> + ref->name, remote_ref->name,
> + &ref->old_oid, &ref->new_oid);
> + if (r)
> + ref_update_display_info_set_failed(info);
> +
> strbuf_release(&quickref);
> return r;
> } else if (force || ref->force) {
> + struct ref_update_display_info *info;
> struct strbuf quickref = STRBUF_INIT;
> int r;
> +
> strbuf_add_unique_abbrev(&quickref, ¤t->object.oid, DEFAULT_ABBREV);
> strbuf_addstr(&quickref, "...");
> strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
> r = s_update_ref("forced-update", ref, transaction, 1);
> - display_ref_update(display_state, r ? '!' : '+', quickref.buf,
> - r ? _("unable to update local ref") : _("forced update"),
> - remote_ref->name, ref->name,
> - &ref->old_oid, &ref->new_oid, summary_width);
> +
> + info = ref_update_display_info_append(display_list, display_count,
> + '+', '!', quickref.buf, _("forced update"),
> + _("unable to update local ref"),
> + ref->name, remote_ref->name,
> + &ref->old_oid, &ref->new_oid);
> +
> + if (r)
> + ref_update_display_info_set_failed(info);
> +
> strbuf_release(&quickref);
> return r;
> } else {
> - display_ref_update(display_state, '!', _("[rejected]"), _("non-fast-forward"),
> - remote_ref->name, ref->name,
> - &ref->old_oid, &ref->new_oid, summary_width);
> + struct ref_update_display_info *info;
> + info = ref_update_display_info_append(display_list, display_count,
> + '!', '!', _("[rejected]"), NULL,
> + _("non-fast-forward"),
> + ref->name, remote_ref->name,
> + &ref->old_oid, &ref->new_oid);
> + ref_update_display_info_set_failed(info);
> return 1;
> }
> }
> @@ -1103,17 +1217,15 @@ static int store_updated_refs(struct display_state *display_state,
> int connectivity_checked,
> struct ref_transaction *transaction, struct ref *ref_map,
> struct fetch_head *fetch_head,
> - const struct fetch_config *config)
> + const struct fetch_config *config,
> + struct ref_update_display_info **display_list,
> + size_t *display_count)
> {
> int rc = 0;
> struct strbuf note = STRBUF_INIT;
> const char *what, *kind;
> struct ref *rm;
> int want_status;
> - int summary_width = 0;
> -
> - if (verbosity >= 0)
> - summary_width = transport_summary_width(ref_map);
>
> if (!connectivity_checked) {
> struct check_connected_options opt = CHECK_CONNECTED_INIT;
> @@ -1218,8 +1330,9 @@ static int store_updated_refs(struct display_state *display_state,
> display_state->url_len);
>
> if (ref) {
> - rc |= update_local_ref(ref, transaction, display_state,
> - rm, summary_width, config);
> + rc |= update_local_ref(ref, transaction, rm,
> + config, display_list,
> + display_count);
> free(ref);
> } else if (write_fetch_head || dry_run) {
> /*
> @@ -1227,12 +1340,11 @@ static int store_updated_refs(struct display_state *display_state,
> * would be written to FETCH_HEAD, if --dry-run
> * is set).
> */
> - display_ref_update(display_state, '*',
> - *kind ? kind : "branch", NULL,
> - rm->name,
> - "FETCH_HEAD",
> - &rm->new_oid, &rm->old_oid,
> - summary_width);
> +
> + ref_update_display_info_append(display_list, display_count,
> + '*', '*', *kind ? kind : "branch",
> + NULL, NULL, "FETCH_HEAD", rm->name,
> + &rm->new_oid, &rm->old_oid);
> }
> }
> }
> @@ -1300,7 +1412,9 @@ static int fetch_and_consume_refs(struct display_state *display_state,
> struct ref_transaction *transaction,
> struct ref *ref_map,
> struct fetch_head *fetch_head,
> - const struct fetch_config *config)
> + const struct fetch_config *config,
> + struct ref_update_display_info **display_list,
> + size_t *display_count)
> {
> int connectivity_checked = 1;
> int ret;
> @@ -1322,7 +1436,8 @@ static int fetch_and_consume_refs(struct display_state *display_state,
>
> trace2_region_enter("fetch", "consume_refs", the_repository);
> ret = store_updated_refs(display_state, connectivity_checked,
> - transaction, ref_map, fetch_head, config);
> + transaction, ref_map, fetch_head, config,
> + display_list, display_count);
> trace2_region_leave("fetch", "consume_refs", the_repository);
>
> out:
> @@ -1493,7 +1608,9 @@ static int backfill_tags(struct display_state *display_state,
> struct ref_transaction *transaction,
> struct ref *ref_map,
> struct fetch_head *fetch_head,
> - const struct fetch_config *config)
> + const struct fetch_config *config,
> + struct ref_update_display_info **display_list,
> + size_t *display_count)
> {
> int retcode, cannot_reuse;
>
> @@ -1515,7 +1632,7 @@ static int backfill_tags(struct display_state *display_state,
> transport_set_option(transport, TRANS_OPT_DEPTH, "0");
> transport_set_option(transport, TRANS_OPT_DEEPEN_RELATIVE, NULL);
> retcode = fetch_and_consume_refs(display_state, transport, transaction, ref_map,
> - fetch_head, config);
> + fetch_head, config, display_list, display_count);
>
> if (gsecondary) {
> transport_disconnect(gsecondary);
> @@ -1641,6 +1758,7 @@ struct ref_rejection_data {
> bool conflict_msg_shown;
> bool case_sensitive_msg_shown;
> const char *remote_name;
> + struct strmap *rejected_refs;
> };
>
> static void ref_transaction_rejection_handler(const char *refname,
> @@ -1681,6 +1799,7 @@ static void ref_transaction_rejection_handler(const char *refname,
> refname, ref_transaction_error_msg(err));
> }
>
> + strmap_put(data->rejected_refs, refname, NULL);
> *data->retcode = 1;
> }
>
> @@ -1690,6 +1809,7 @@ static void ref_transaction_rejection_handler(const char *refname,
> */
> static int commit_ref_transaction(struct ref_transaction **transaction,
> bool is_atomic, const char *remote_name,
> + struct strmap *rejected_refs,
> struct strbuf *err)
> {
> int retcode = ref_transaction_commit(*transaction, err);
> @@ -1701,6 +1821,7 @@ static int commit_ref_transaction(struct ref_transaction **transaction,
> .conflict_msg_shown = 0,
> .remote_name = remote_name,
> .retcode = &retcode,
> + .rejected_refs = rejected_refs,
> };
>
> ref_transaction_for_each_rejected_update(*transaction,
> @@ -1729,6 +1850,10 @@ static int do_fetch(struct transport *transport,
> struct fetch_head fetch_head = { 0 };
> struct strbuf err = STRBUF_INIT;
> int do_set_head = 0;
> + struct ref_update_display_info *display_list = NULL;
> + struct strmap rejected_refs = STRMAP_INIT;
> + size_t display_count = 0;
> + int summary_width = 0;
>
> if (tags == TAGS_DEFAULT) {
> if (transport->remote->fetch_tags == 2)
> @@ -1853,7 +1978,7 @@ static int do_fetch(struct transport *transport,
> }
>
> if (fetch_and_consume_refs(&display_state, transport, transaction, ref_map,
> - &fetch_head, config)) {
> + &fetch_head, config, &display_list, &display_count)) {
> retcode = 1;
> goto cleanup;
> }
> @@ -1876,7 +2001,7 @@ static int do_fetch(struct transport *transport,
> * the transaction and don't commit anything.
> */
> if (backfill_tags(&display_state, transport, transaction, tags_ref_map,
> - &fetch_head, config))
> + &fetch_head, config, &display_list, &display_count))
> retcode = 1;
> }
>
> @@ -1886,8 +2011,12 @@ static int do_fetch(struct transport *transport,
> if (retcode)
> goto cleanup;
>
> + if (verbosity >= 0)
> + summary_width = transport_summary_width(ref_map);
> +
> retcode = commit_ref_transaction(&transaction, atomic_fetch,
> - transport->remote->name, &err);
> + transport->remote->name,
> + &rejected_refs, &err);
> /*
> * With '--atomic', bail out if the transaction fails. Without '--atomic',
> * continue to fetch head and perform other post-fetch operations.
> @@ -1965,7 +2094,17 @@ static int do_fetch(struct transport *transport,
> */
> if (retcode && !atomic_fetch && transaction)
> commit_ref_transaction(&transaction, false,
> - transport->remote->name, &err);
> + transport->remote->name,
> + &rejected_refs, &err);
> +
> + for (size_t i = 0; i < display_count; i++) {
> + struct ref_update_display_info *info = &display_list[i];
> +
> + if (!info->failed && strmap_contains(&rejected_refs, info->ref))
> + ref_update_display_info_set_failed(info);
> + ref_update_display_info_display(info, &display_state, summary_width);
> + ref_update_display_info_free(info);
> + }
>
> if (retcode) {
> if (err.len) {
> @@ -1980,6 +2119,9 @@ static int do_fetch(struct transport *transport,
>
> if (transaction)
> ref_transaction_free(transaction);
> +
> + free(display_list);
> + strmap_clear(&rejected_refs, 0);
> display_state_release(&display_state);
> close_fetch_head(&fetch_head);
> strbuf_release(&err);
> diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
> index 45595991c8..29e2f17608 100755
> --- a/t/t5516-fetch-push.sh
> +++ b/t/t5516-fetch-push.sh
> @@ -1893,6 +1893,7 @@ test_expect_success 'pushing non-commit objects should report error' '
>
> tagsha=$(git rev-parse test^{tag}) &&
> test_must_fail git push ../dest "$tagsha:refs/heads/branch" 2>err &&
> + test_grep "! \[remote rejected\] $tagsha -> branch (invalid new value provided)" err &&
> test_grep "trying to write non-commit object $tagsha to branch ${SQ}refs/heads/branch${SQ}" err
> )
> '
>
next prev parent reply other threads:[~2026-01-21 16:21 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-14 15:40 [PATCH 0/6] refs: provide detailed error messages when using batched update Karthik Nayak
2026-01-14 15:40 ` [PATCH 1/6] refs: remove unused header Karthik Nayak
2026-01-14 17:08 ` Junio C Hamano
2026-01-15 9:50 ` Karthik Nayak
2026-01-14 15:40 ` [PATCH 2/6] refs: attach rejection details to updates Karthik Nayak
2026-01-14 17:43 ` Jeff King
2026-01-15 10:02 ` Karthik Nayak
2026-01-15 20:29 ` Jeff King
2026-01-16 17:56 ` Karthik Nayak
2026-01-14 15:40 ` [PATCH 3/6] refs: add rejection detail to the callback function Karthik Nayak
2026-01-14 17:44 ` Jeff King
2026-01-15 10:10 ` Karthik Nayak
2026-01-14 15:40 ` [PATCH 4/6] update-ref: utilize rejected error details if available Karthik Nayak
2026-01-14 17:27 ` Junio C Hamano
2026-01-14 17:55 ` Jeff King
2026-01-15 11:08 ` Karthik Nayak
2026-01-14 15:40 ` [PATCH 5/6] fetch: utilize rejected ref error details Karthik Nayak
2026-01-14 17:33 ` Junio C Hamano
2026-01-15 10:54 ` Karthik Nayak
2026-01-14 18:00 ` Jeff King
2026-01-15 15:20 ` Karthik Nayak
2026-01-14 15:40 ` [PATCH 6/6] receive-pack: " Karthik Nayak
2026-01-14 18:03 ` Jeff King
2026-01-15 15:21 ` Karthik Nayak
2026-01-14 16:45 ` [PATCH 0/6] refs: provide detailed error messages when using batched update Junio C Hamano
2026-01-16 21:27 ` [PATCH v2 0/7] " Karthik Nayak
2026-01-16 21:27 ` [PATCH v2 1/7] refs: drop unnecessary header includes Karthik Nayak
2026-01-18 12:07 ` SZEDER Gábor
2026-01-19 8:53 ` Karthik Nayak
2026-01-16 21:27 ` [PATCH v2 2/7] refs: skip to next ref when current ref is rejected Karthik Nayak
2026-01-16 21:27 ` [PATCH v2 3/7] refs: add rejection detail to the callback function Karthik Nayak
2026-01-16 21:27 ` [PATCH v2 4/7] update-ref: utilize rejected error details if available Karthik Nayak
2026-01-16 21:27 ` [PATCH v2 5/7] fetch: utilize rejected ref error details Karthik Nayak
2026-01-16 21:27 ` [PATCH v2 6/7] receive-pack: " Karthik Nayak
2026-01-16 21:27 ` [PATCH v2 7/7] fetch: delay user information post committing of transaction Karthik Nayak
2026-01-17 13:56 ` Phillip Wood
2026-01-19 16:11 ` Karthik Nayak
2026-01-20 9:59 ` [PATCH v3 0/6] refs: provide detailed error messages when using batched update Karthik Nayak
2026-01-20 9:59 ` [PATCH v3 1/6] refs: skip to next ref when current ref is rejected Karthik Nayak
2026-01-20 9:59 ` [PATCH v3 2/6] refs: add rejection detail to the callback function Karthik Nayak
2026-01-20 9:59 ` [PATCH v3 3/6] update-ref: utilize rejected error details if available Karthik Nayak
2026-01-20 9:59 ` [PATCH v3 4/6] fetch: utilize rejected ref error details Karthik Nayak
2026-01-20 9:59 ` [PATCH v3 5/6] receive-pack: " Karthik Nayak
2026-01-20 9:59 ` [PATCH v3 6/6] fetch: delay user information post committing of transaction Karthik Nayak
2026-01-21 16:21 ` Phillip Wood [this message]
2026-01-21 18:43 ` Junio C Hamano
2026-01-22 9:05 ` Karthik Nayak
2026-01-21 18:12 ` [PATCH v3 0/6] refs: provide detailed error messages when using batched update Junio C Hamano
2026-01-22 12:04 ` [PATCH v4 " Karthik Nayak
2026-01-22 12:04 ` [PATCH v4 1/6] refs: skip to next ref when current ref is rejected Karthik Nayak
2026-01-22 12:04 ` [PATCH v4 2/6] refs: add rejection detail to the callback function Karthik Nayak
2026-01-22 12:04 ` [PATCH v4 3/6] update-ref: utilize rejected error details if available Karthik Nayak
2026-01-22 12:04 ` [PATCH v4 4/6] fetch: utilize rejected ref error details Karthik Nayak
2026-01-22 12:04 ` [PATCH v4 5/6] receive-pack: " Karthik Nayak
2026-01-22 12:05 ` [PATCH v4 6/6] fetch: delay user information post committing of transaction Karthik Nayak
2026-01-22 20:10 ` Junio C Hamano
2026-01-23 14:49 ` Karthik Nayak
2026-01-23 17:57 ` Junio C Hamano
2026-01-25 18:47 ` Karthik Nayak
2026-01-23 14:41 ` Phillip Wood
2026-01-23 14:50 ` Karthik Nayak
2026-01-25 22:52 ` [PATCH v5 0/6] refs: provide detailed error messages when using batched update Karthik Nayak
2026-01-25 22:52 ` [PATCH v5 1/6] refs: skip to next ref when current ref is rejected Karthik Nayak
2026-01-25 22:52 ` [PATCH v5 2/6] refs: add rejection detail to the callback function Karthik Nayak
2026-01-25 22:52 ` [PATCH v5 3/6] update-ref: utilize rejected error details if available Karthik Nayak
2026-01-25 22:52 ` [PATCH v5 4/6] fetch: utilize rejected ref error details Karthik Nayak
2026-01-25 22:52 ` [PATCH v5 5/6] receive-pack: " Karthik Nayak
2026-01-25 22:52 ` [PATCH v5 6/6] fetch: delay user information post committing of transaction 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=67808128-5f41-4ae5-b224-a76048cd82c8@gmail.com \
--to=phillip.wood123@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=karthik.188@gmail.com \
--cc=newren@gmail.com \
--cc=peff@peff.net \
--cc=phillip.wood@dunelm.org.uk \
/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