]> git.ipfire.org Git - thirdparty/git.git/commitdiff
update-ref: allow creation of multiple transactions
authorPatrick Steinhardt <ps@pks.im>
Fri, 13 Nov 2020 08:12:36 +0000 (09:12 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 16 Nov 2020 21:44:01 +0000 (13:44 -0800)
While git-update-ref has recently grown commands which allow interactive
control of transactions in e48cf33b61 (update-ref: implement interactive
transaction handling, 2020-04-02), it is not yet possible to create
multiple transactions in a single session. To do so, one currently still
needs to invoke the executable multiple times.

This commit addresses this shortcoming by allowing the "start" command
to create a new transaction if the current transaction has already been
either committed or aborted.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-update-ref.txt
builtin/update-ref.c
t/t1400-update-ref.sh

index d401234b03ce85722ff9624acb16c125d3780b27..48b6683071e65be1abf29ece20dc90c5f0579ec3 100644 (file)
@@ -125,7 +125,8 @@ option::
 start::
        Start a transaction. In contrast to a non-transactional session, a
        transaction will automatically abort if the session ends without an
-       explicit commit.
+       explicit commit. This command may create a new empty transaction when
+       the current one has been committed or aborted already.
 
 prepare::
        Prepare to commit the transaction. This will create lock files for all
index 8a2df4459c66389d0fc24fed93dc4e0c1f87efe1..bb65129012dc551236f79ee6ea7ead255b01a56d 100644 (file)
@@ -446,7 +446,18 @@ static void update_refs_stdin(void)
                        state = cmd->state;
                        break;
                case UPDATE_REFS_CLOSED:
-                       die("transaction is closed");
+                       if (cmd->state != UPDATE_REFS_STARTED)
+                               die("transaction is closed");
+
+                       /*
+                        * Open a new transaction if we're currently closed and
+                        * get a "start".
+                        */
+                       state = cmd->state;
+                       transaction = ref_transaction_begin(&err);
+                       if (!transaction)
+                               die("%s", err.buf);
+
                        break;
                }
 
index b782dafff5d2a897d18cccc1579ec2ed168a472d..3144e98b31535c1d817d46c697cadf3885bb50da 100755 (executable)
@@ -1533,4 +1533,54 @@ test_expect_success 'transaction with prepare aborts by default' '
        test_must_fail git show-ref --verify -q $b
 '
 
+test_expect_success 'transaction can commit multiple times' '
+       cat >stdin <<-EOF &&
+       start
+       create refs/heads/branch-1 $A
+       commit
+       start
+       create refs/heads/branch-2 $B
+       commit
+       EOF
+       git update-ref --stdin <stdin >actual &&
+       printf "%s: ok\n" start commit start commit >expect &&
+       test_cmp expect actual &&
+       echo "$A" >expect &&
+       git rev-parse refs/heads/branch-1 >actual &&
+       test_cmp expect actual &&
+       echo "$B" >expect &&
+       git rev-parse refs/heads/branch-2 >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'transaction can create and delete' '
+       cat >stdin <<-EOF &&
+       start
+       create refs/heads/create-and-delete $A
+       commit
+       start
+       delete refs/heads/create-and-delete $A
+       commit
+       EOF
+       git update-ref --stdin <stdin >actual &&
+       printf "%s: ok\n" start commit start commit >expect &&
+       test_must_fail git show-ref --verify refs/heads/create-and-delete
+'
+
+test_expect_success 'transaction can commit after abort' '
+       cat >stdin <<-EOF &&
+       start
+       create refs/heads/abort $A
+       abort
+       start
+       create refs/heads/abort $A
+       commit
+       EOF
+       git update-ref --stdin <stdin >actual &&
+       printf "%s: ok\n" start abort start commit >expect &&
+       echo "$A" >expect &&
+       git rev-parse refs/heads/abort >actual &&
+       test_cmp expect actual
+'
+
 test_done