feat(dolt): auto-commit write commands and set explicit commit authors (#1270)

Adds Dolt auto-commit functionality for write commands and sets explicit commit authors.

Includes fix for race condition in commandDidWrite (converted to atomic.Bool).

Original PR: #1267 by @coffeegoddd
Co-authored-by: Dustin Brown <dustin@dolthub.com>
This commit is contained in:
Steve Yegge
2026-01-22 20:52:20 -08:00
committed by GitHub
parent 1f94b4b363
commit ab61b0956b
18 changed files with 596 additions and 45 deletions

View File

@@ -111,6 +111,11 @@ func Initialize() error {
v.SetDefault("identity", "")
v.SetDefault("remote-sync-interval", "30s")
// Dolt configuration defaults
// Controls whether beads should automatically create Dolt commits after write commands.
// Values: off | on
v.SetDefault("dolt.auto-commit", "on")
// Routing configuration defaults
v.SetDefault("routing.mode", "")
v.SetDefault("routing.default", ".")
@@ -122,16 +127,16 @@ func Initialize() error {
// Sync mode configuration (hq-ew1mbr.3)
// See docs/CONFIG.md for detailed documentation
v.SetDefault("sync.mode", SyncModeGitPortable) // git-portable | realtime | dolt-native | belt-and-suspenders
v.SetDefault("sync.export_on", SyncTriggerPush) // push | change
v.SetDefault("sync.import_on", SyncTriggerPull) // pull | change
v.SetDefault("sync.mode", SyncModeGitPortable) // git-portable | realtime | dolt-native | belt-and-suspenders
v.SetDefault("sync.export_on", SyncTriggerPush) // push | change
v.SetDefault("sync.import_on", SyncTriggerPull) // pull | change
// Conflict resolution configuration
v.SetDefault("conflict.strategy", ConflictStrategyNewest) // newest | ours | theirs | manual
// Federation configuration (optional Dolt remote)
v.SetDefault("federation.remote", "") // e.g., dolthub://org/beads, gs://bucket/beads, s3://bucket/beads
v.SetDefault("federation.sovereignty", "") // T1 | T2 | T3 | T4 (empty = no restriction)
v.SetDefault("federation.remote", "") // e.g., dolthub://org/beads, gs://bucket/beads, s3://bucket/beads
v.SetDefault("federation.sovereignty", "") // T1 | T2 | T3 | T4 (empty = no restriction)
// Push configuration defaults
v.SetDefault("no-push", false)

View File

@@ -36,12 +36,12 @@ import (
// DoltStore implements the Storage interface using Dolt
type DoltStore struct {
db *sql.DB
dbPath string // Path to Dolt database directory
closed atomic.Bool // Tracks whether Close() has been called
connStr string // Connection string for reconnection
mu sync.RWMutex // Protects concurrent access
readOnly bool // True if opened in read-only mode
db *sql.DB
dbPath string // Path to Dolt database directory
closed atomic.Bool // Tracks whether Close() has been called
connStr string // Connection string for reconnection
mu sync.RWMutex // Protects concurrent access
readOnly bool // True if opened in read-only mode
// Version control config
committerName string
@@ -457,9 +457,15 @@ func (s *DoltStore) UnderlyingConn(ctx context.Context) (*sql.Conn, error) {
// Version Control Operations (Dolt-specific extensions)
// =============================================================================
func (s *DoltStore) commitAuthorString() string {
return fmt.Sprintf("%s <%s>", s.committerName, s.committerEmail)
}
// Commit creates a Dolt commit with the given message
func (s *DoltStore) Commit(ctx context.Context, message string) error {
_, err := s.db.ExecContext(ctx, "CALL DOLT_COMMIT('-Am', ?)", message)
// NOTE: In SQL procedure mode, Dolt defaults author to the authenticated SQL user
// (e.g. root@localhost). Always pass an explicit author for deterministic history.
_, err := s.db.ExecContext(ctx, "CALL DOLT_COMMIT('-Am', ?, '--author', ?)", message, s.commitAuthorString())
if err != nil {
return fmt.Errorf("failed to commit: %w", err)
}
@@ -506,7 +512,8 @@ func (s *DoltStore) Checkout(ctx context.Context, branch string) error {
// Merge merges the specified branch into the current branch.
// Returns any merge conflicts if present. Implements storage.VersionedStorage.
func (s *DoltStore) Merge(ctx context.Context, branch string) ([]storage.Conflict, error) {
_, err := s.db.ExecContext(ctx, "CALL DOLT_MERGE(?)", branch)
// DOLT_MERGE may create a merge commit; pass explicit author for determinism.
_, err := s.db.ExecContext(ctx, "CALL DOLT_MERGE('--author', ?, ?)", s.commitAuthorString(), branch)
if err != nil {
// Check if the error is due to conflicts
conflicts, conflictErr := s.GetConflicts(ctx)
@@ -522,7 +529,8 @@ func (s *DoltStore) Merge(ctx context.Context, branch string) ([]storage.Conflic
// This is needed for initial federation sync between independently initialized towns.
// Returns any merge conflicts if present.
func (s *DoltStore) MergeAllowUnrelated(ctx context.Context, branch string) ([]storage.Conflict, error) {
_, err := s.db.ExecContext(ctx, "CALL DOLT_MERGE('--allow-unrelated-histories', ?)", branch)
// DOLT_MERGE may create a merge commit; pass explicit author for determinism.
_, err := s.db.ExecContext(ctx, "CALL DOLT_MERGE('--allow-unrelated-histories', '--author', ?, ?)", s.commitAuthorString(), branch)
if err != nil {
// Check if the error is due to conflicts
conflicts, conflictErr := s.GetConflicts(ctx)