github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/env/actions/commit.go (about)

     1  // Copyright 2019 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package actions
    16  
    17  import (
    18  	"context"
    19  	"time"
    20  
    21  	"github.com/dolthub/dolt/go/libraries/doltcore/diff"
    22  	"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
    23  	"github.com/dolthub/dolt/go/store/datas"
    24  )
    25  
    26  type CommitStagedProps struct {
    27  	Message    string
    28  	Date       time.Time
    29  	AllowEmpty bool
    30  	SkipEmpty  bool
    31  	Amend      bool
    32  	Force      bool
    33  	Name       string
    34  	Email      string
    35  }
    36  
    37  // GetCommitStaged returns a new pending commit with the roots and commit properties given.
    38  func GetCommitStaged(
    39  	ctx context.Context,
    40  	roots doltdb.Roots,
    41  	ws *doltdb.WorkingSet,
    42  	mergeParents []*doltdb.Commit,
    43  	db *doltdb.DoltDB,
    44  	props CommitStagedProps,
    45  ) (*doltdb.PendingCommit, error) {
    46  	if props.Message == "" {
    47  		return nil, datas.ErrEmptyCommitMessage
    48  	}
    49  
    50  	staged, notStaged, err := diff.GetStagedUnstagedTableDeltas(ctx, roots)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	var stagedTblNames []string
    56  	for _, td := range staged {
    57  		n := td.ToName
    58  		if td.IsDrop() {
    59  			n = td.FromName
    60  		}
    61  		stagedTblNames = append(stagedTblNames, n)
    62  	}
    63  
    64  	isEmpty := len(staged) == 0
    65  	allowEmpty := ws.MergeActive() || props.AllowEmpty || props.Amend
    66  
    67  	if isEmpty && props.SkipEmpty {
    68  		return nil, nil
    69  	}
    70  	if isEmpty && !allowEmpty {
    71  		return nil, NothingStaged{notStaged}
    72  	}
    73  
    74  	if !props.Force {
    75  		inConflict, err := doltdb.TablesWithDataConflicts(ctx, roots.Working)
    76  		if err != nil {
    77  			return nil, err
    78  		}
    79  		if len(inConflict) > 0 {
    80  			return nil, NewTblInConflictError(inConflict)
    81  		}
    82  		violatesConstraints, err := doltdb.TablesWithConstraintViolations(ctx, roots.Working)
    83  		if err != nil {
    84  			return nil, err
    85  		}
    86  		if len(violatesConstraints) > 0 {
    87  			return nil, NewTblHasConstraintViolations(violatesConstraints)
    88  		}
    89  
    90  		if ws.MergeActive() {
    91  			schConflicts := ws.MergeState().TablesWithSchemaConflicts()
    92  			if len(schConflicts) > 0 {
    93  				return nil, NewTblSchemaConflictError(schConflicts)
    94  			}
    95  		}
    96  	}
    97  
    98  	if !props.Force {
    99  		roots.Staged, err = doltdb.ValidateForeignKeysOnSchemas(ctx, roots.Staged)
   100  		if err != nil {
   101  			return nil, err
   102  		}
   103  	}
   104  
   105  	meta, err := datas.NewCommitMetaWithUserTS(props.Name, props.Email, props.Message, props.Date)
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  
   110  	return db.NewPendingCommit(ctx, roots, mergeParents, meta)
   111  }