github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/cmd/noms/noms_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  // This file incorporates work covered by the following copyright and
    16  // permission notice:
    17  //
    18  // Copyright 2016 Attic Labs, Inc. All rights reserved.
    19  // Licensed under the Apache License, version 2.0:
    20  // http://www.apache.org/licenses/LICENSE-2.0
    21  
    22  package main
    23  
    24  import (
    25  	"bufio"
    26  	"context"
    27  	"errors"
    28  	"fmt"
    29  	"os"
    30  
    31  	flag "github.com/juju/gnuflag"
    32  
    33  	"github.com/dolthub/dolt/go/store/cmd/noms/util"
    34  	"github.com/dolthub/dolt/go/store/config"
    35  	"github.com/dolthub/dolt/go/store/d"
    36  	"github.com/dolthub/dolt/go/store/datas"
    37  	"github.com/dolthub/dolt/go/store/spec"
    38  	"github.com/dolthub/dolt/go/store/util/verbose"
    39  )
    40  
    41  var allowDupe bool
    42  
    43  var nomsCommit = &util.Command{
    44  	Run:       runCommit,
    45  	UsageLine: "commit [options] [absolute-path] <dataset>",
    46  	Short:     "Commits a specified value as head of the dataset",
    47  	Long:      "If absolute-path is not provided, then it is read from stdin. See Spelling Objects at https://github.com/attic-labs/noms/blob/master/doc/spelling.md for details on the dataset and absolute-path arguments.",
    48  	Flags:     setupCommitFlags,
    49  	Nargs:     1, // if absolute-path not present we read it from stdin
    50  }
    51  
    52  func setupCommitFlags() *flag.FlagSet {
    53  	commitFlagSet := flag.NewFlagSet("commit", flag.ExitOnError)
    54  	commitFlagSet.BoolVar(&allowDupe, "allow-dupe", false, "creates a new commit, even if it would be identical (modulo metadata and parents) to the existing HEAD.")
    55  	spec.RegisterCommitMetaFlags(commitFlagSet)
    56  	verbose.RegisterVerboseFlags(commitFlagSet)
    57  	return commitFlagSet
    58  }
    59  
    60  func runCommit(ctx context.Context, args []string) int {
    61  	cfg := config.NewResolver()
    62  	db, ds, err := cfg.GetDataset(ctx, args[len(args)-1])
    63  	util.CheckError(err)
    64  	defer db.Close()
    65  
    66  	var path string
    67  	if len(args) == 2 {
    68  		path = args[0]
    69  	} else {
    70  		readPath, _, err := bufio.NewReader(os.Stdin).ReadLine()
    71  		util.CheckError(err)
    72  		path = string(readPath)
    73  	}
    74  	absPath, err := spec.NewAbsolutePath(path)
    75  	util.CheckError(err)
    76  
    77  	value := absPath.Resolve(ctx, db)
    78  	if value == nil {
    79  		util.CheckErrorNoUsage(errors.New(fmt.Sprintf("Error resolving value: %s", path)))
    80  	}
    81  
    82  	oldCommitRef, oldCommitExists, err := ds.MaybeHeadRef()
    83  	d.PanicIfError(err)
    84  
    85  	if oldCommitExists {
    86  		head, ok, err := ds.MaybeHeadValue()
    87  		d.PanicIfError(err)
    88  
    89  		if !ok {
    90  			fmt.Fprintln(os.Stdout, "Commit has no head value.")
    91  			return 1
    92  		}
    93  
    94  		hh, err := head.Hash(db.Format())
    95  		d.PanicIfError(err)
    96  		vh, err := value.Hash(db.Format())
    97  		d.PanicIfError(err)
    98  
    99  		if hh == vh && !allowDupe {
   100  			fmt.Fprintf(os.Stdout, "Commit aborted - allow-dupe is set to off and this commit would create a duplicate\n")
   101  			return 0
   102  		}
   103  	}
   104  
   105  	meta, err := spec.CreateCommitMetaStruct(ctx, db, "", "", nil, nil)
   106  	util.CheckErrorNoUsage(err)
   107  
   108  	ds, err = db.Commit(ctx, ds, value, datas.CommitOptions{Meta: meta})
   109  	util.CheckErrorNoUsage(err)
   110  
   111  	headRef, ok, err := ds.MaybeHeadRef()
   112  
   113  	d.PanicIfError(err)
   114  
   115  	if !ok {
   116  		panic("commit succeeded, but dataset has no head ref")
   117  	}
   118  
   119  	if oldCommitExists {
   120  
   121  		if ok {
   122  			fmt.Fprintf(os.Stdout, "New head #%v (was #%v)\n", headRef.TargetHash().String(), oldCommitRef.TargetHash().String())
   123  		}
   124  	} else {
   125  		fmt.Fprintf(os.Stdout, "New head #%v\n", headRef.TargetHash().String())
   126  	}
   127  	return 0
   128  }