@@ -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
@@ -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;
}
@@ -1532,4 +1532,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
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> --- Documentation/git-update-ref.txt | 3 +- builtin/update-ref.c | 13 ++++++++- t/t1400-update-ref.sh | 50 ++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-)