shithub: furgit

Download patch

ref: e99bfdd873f2e083b5c5b53fdecaec35c90a70fe
parent: 784ad6c9e01da13e6f22cd58dae30aff2f1249d2
author: Runxi Yu <me@runxiyu.org>
date: Sat Mar 7 09:34:59 EST 2026

refstore: Add TransactionalStore

--- a/refstore/refstore.go
+++ b/refstore/refstore.go
@@ -4,6 +4,7 @@
 import (
 	"errors"
 
+	"codeberg.org/lindenii/furgit/objectid"
 	"codeberg.org/lindenii/furgit/ref"
 )
 
@@ -41,4 +42,54 @@
 	Shorten(name string) (string, error)
 	// Close releases resources associated with the store.
 	Close() error
+}
+
+// TransactionalStore begins atomic reference transactions.
+//
+// Not every readable reference store is writable. Implementations should only
+// satisfy TransactionalStore when they can stage and commit reference updates
+// atomically within that backend.
+type TransactionalStore interface {
+	// BeginTransaction creates one new mutable transaction.
+	BeginTransaction() (Transaction, error)
+}
+
+// Transaction stages reference updates for one atomic commit.
+//
+// Ordinary methods operate in dereference mode if name resolves to
+// a symbolic ref, the operation applies to the final referent rather
+// than to the symbolic ref itself.
+//
+// Symbolic methods operate on the named reference directly, without
+// dereferencing symbolic refs.
+type Transaction interface {
+	// Create creates one detached reference, requiring that the logical
+	// reference does not already exist.
+	Create(name string, newID objectid.ObjectID) error
+	// Update updates one detached reference, requiring that the current logical
+	// reference value matches oldID.
+	Update(name string, newID, oldID objectid.ObjectID) error
+	// Delete deletes one detached reference, requiring that the current logical
+	// reference value matches oldID.
+	Delete(name string, oldID objectid.ObjectID) error
+	// Verify verifies that the current logical reference value matches oldID.
+	Verify(name string, oldID objectid.ObjectID) error
+
+	// CreateSymbolic creates one symbolic reference, requiring that the named
+	// reference does not already exist.
+	CreateSymbolic(name, newTarget string) error
+	// UpdateSymbolic updates one symbolic reference directly, requiring that its
+	// current target matches oldTarget.
+	UpdateSymbolic(name, newTarget, oldTarget string) error
+	// DeleteSymbolic deletes one symbolic reference directly, requiring that its
+	// current target matches oldTarget.
+	DeleteSymbolic(name, oldTarget string) error
+	// VerifySymbolic verifies that the named symbolic reference currently points
+	// at oldTarget.
+	VerifySymbolic(name, oldTarget string) error
+
+	// Commit validates and applies all queued operations atomically.
+	Commit() error
+	// Abort abandons the transaction and releases any resources it holds.
+	Abort() error
 }
--