diff options
Diffstat (limited to '_support')
-rw-r--r-- | _support/git-patches/0015-update-ref-fix-streaming-of-status-updates.patch | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/_support/git-patches/0015-update-ref-fix-streaming-of-status-updates.patch b/_support/git-patches/0015-update-ref-fix-streaming-of-status-updates.patch new file mode 100644 index 000000000..ecdca4675 --- /dev/null +++ b/_support/git-patches/0015-update-ref-fix-streaming-of-status-updates.patch @@ -0,0 +1,124 @@ +From efa3d64ce86a600563c8bf909c46dd0985ee6c11 Mon Sep 17 00:00:00 2001 +Message-Id: <efa3d64ce86a600563c8bf909c46dd0985ee6c11.1631522930.git.ps@pks.im> +From: Patrick Steinhardt <ps@pks.im> +Date: Fri, 3 Sep 2021 11:06:37 +0200 +Subject: [PATCH] update-ref: fix streaming of status updates + +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. + +Signed-off-by: Patrick Steinhardt <ps@pks.im> +Signed-off-by: Junio C Hamano <gitster@pobox.com> +--- + 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 && +-- +2.33.0 + |