summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2020-11-13 08:12:36 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-11-16 21:44:01 (GMT)
commit262a4d28feb26aff89705b3254cdfc015eaa3ef9 (patch)
tree302223444885516c3e3a834f808a146b9d8d8f82
parentc0e172612754db0ed4c83d82b44fbc61f766ad6f (diff)
downloadgit-262a4d28feb26aff89705b3254cdfc015eaa3ef9.zip
git-262a4d28feb26aff89705b3254cdfc015eaa3ef9.tar.gz
git-262a4d28feb26aff89705b3254cdfc015eaa3ef9.tar.bz2
update-ref: allow creation of multiple transactions
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>
-rw-r--r--Documentation/git-update-ref.txt3
-rw-r--r--builtin/update-ref.c13
-rwxr-xr-xt/t1400-update-ref.sh50
3 files changed, 64 insertions, 2 deletions
diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt
index d401234..48b6683 100644
--- a/Documentation/git-update-ref.txt
+++ b/Documentation/git-update-ref.txt
@@ -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
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 8a2df44..bb65129 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -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;
}
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index b782daf..3144e98 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -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