From: Junio C Hamano <gitster@pobox.com>
To: Patrick Steinhardt <ps@pks.im>
Cc: git@vger.kernel.org
Subject: Re: [PATCH] update-ref: fix streaming of status updates
Date: Fri, 03 Sep 2021 11:34:45 -0700 [thread overview]
Message-ID: <xmqqfsulfqyi.fsf@gitster.g> (raw)
In-Reply-To: <1e9e62a2c5f74db91aaded83783076c28b757836.1630659922.git.ps@pks.im> (Patrick Steinhardt's message of "Fri, 3 Sep 2021 11:06:37 +0200")
Patrick Steinhardt <ps@pks.im> writes:
> When executing git-update-ref(1) with the `--stdin` flag, then the user
> can queue updates and, since e48cf33b61 (update-ref: implement
> interactive transaction handling, 2020-04-02), interactively drive the
> transaction's state via a set of transactional verbs. This interactivity
> is somewhat broken though: while the caller can use these verbs to drive
> the transaction's state, the status messages which confirm that a verb
> has been processed is not flushed. The caller may thus be left hanging
> waiting for the acknowledgement.
>
> Fix the bug by flushing stdout after writing the status update. Add a
> test which catches this bug.
Nobody hit by this for more than a year is interesting.
Will queue. Thanks.
>
> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
> builtin/update-ref.c | 14 ++++++++++----
> t/t1400-update-ref.sh | 32 ++++++++++++++++++++++++++++++++
> 2 files changed, 42 insertions(+), 4 deletions(-)
>
> diff --git a/builtin/update-ref.c b/builtin/update-ref.c
> index 6029a80544..a84e7b47a2 100644
> --- a/builtin/update-ref.c
> +++ b/builtin/update-ref.c
> @@ -302,6 +302,12 @@ static void parse_cmd_verify(struct ref_transaction *transaction,
> strbuf_release(&err);
> }
>
> +static void report_ok(const char *command)
> +{
> + fprintf(stdout, "%s: ok\n", command);
> + fflush(stdout);
> +}
> +
> static void parse_cmd_option(struct ref_transaction *transaction,
> const char *next, const char *end)
> {
> @@ -317,7 +323,7 @@ static void parse_cmd_start(struct ref_transaction *transaction,
> {
> if (*next != line_termination)
> die("start: extra input: %s", next);
> - puts("start: ok");
> + report_ok("start");
> }
>
> static void parse_cmd_prepare(struct ref_transaction *transaction,
> @@ -328,7 +334,7 @@ static void parse_cmd_prepare(struct ref_transaction *transaction,
> die("prepare: extra input: %s", next);
> if (ref_transaction_prepare(transaction, &error))
> die("prepare: %s", error.buf);
> - puts("prepare: ok");
> + report_ok("prepare");
> }
>
> static void parse_cmd_abort(struct ref_transaction *transaction,
> @@ -339,7 +345,7 @@ static void parse_cmd_abort(struct ref_transaction *transaction,
> die("abort: extra input: %s", next);
> if (ref_transaction_abort(transaction, &error))
> die("abort: %s", error.buf);
> - puts("abort: ok");
> + report_ok("abort");
> }
>
> static void parse_cmd_commit(struct ref_transaction *transaction,
> @@ -350,7 +356,7 @@ static void parse_cmd_commit(struct ref_transaction *transaction,
> die("commit: extra input: %s", next);
> if (ref_transaction_commit(transaction, &error))
> die("commit: %s", error.buf);
> - puts("commit: ok");
> + report_ok("commit");
> ref_transaction_free(transaction);
> }
>
> diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
> index 4506cd435b..1e754e258f 100755
> --- a/t/t1400-update-ref.sh
> +++ b/t/t1400-update-ref.sh
> @@ -1598,6 +1598,38 @@ test_expect_success 'transaction cannot restart ongoing transaction' '
> test_must_fail git show-ref --verify refs/heads/restart
> '
>
> +test_expect_success PIPE 'transaction flushes status updates' '
> + mkfifo in out &&
> + (git update-ref --stdin <in >out &) &&
> +
> + exec 9>in &&
> + test_when_finished "exec 9>&-" &&
> +
> + echo "start" >&9 &&
> + echo "start: ok" >expected &&
> + read line <out &&
> + echo "$line" >actual &&
> + test_cmp expected actual &&
> +
> + echo "create refs/heads/flush $A" >&9 &&
> +
> + echo prepare >&9 &&
> + echo "prepare: ok" >expected &&
> + read line <out &&
> + echo "$line" >actual &&
> + test_cmp expected actual &&
> +
> + # This must now fail given that we have locked the ref.
> + test_must_fail git update-ref refs/heads/flush $B 2>stderr &&
> + grep "fatal: update_ref failed for ref ${SQ}refs/heads/flush${SQ}: cannot lock ref" stderr &&
> +
> + echo commit >&9 &&
> + echo "commit: ok" >expected &&
> + read line <out &&
> + echo "$line" >actual &&
> + test_cmp expected actual
> +'
> +
> test_expect_success 'directory not created deleting packed ref' '
> git branch d1/d2/r1 HEAD &&
> git pack-refs --all &&
next prev parent reply other threads:[~2021-09-03 18:34 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-03 9:06 [PATCH] update-ref: fix streaming of status updates Patrick Steinhardt
2021-09-03 18:34 ` Junio C Hamano [this message]
2021-09-15 17:13 ` Jeff King
2021-09-15 17:24 ` [PATCH] t1400: avoid SIGPIPE race condition on fifo Jeff King
2021-09-15 20:08 ` Junio C Hamano
2021-09-16 4:39 ` 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=xmqqfsulfqyi.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.