github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/doltdb/stash.go (about)

     1  // Copyright 2023 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 doltdb
    16  
    17  import (
    18  	"context"
    19  	"errors"
    20  	"fmt"
    21  
    22  	"github.com/dolthub/dolt/go/store/datas"
    23  	"github.com/dolthub/dolt/go/store/hash"
    24  	"github.com/dolthub/dolt/go/store/prolly/tree"
    25  	"github.com/dolthub/dolt/go/store/types"
    26  )
    27  
    28  type Stash struct {
    29  	Name        string
    30  	BranchName  string
    31  	Description string
    32  	HeadCommit  *Commit
    33  }
    34  
    35  // getStashList returns array of Stash objects containing all stash entries in the stash list map.
    36  func getStashList(ctx context.Context, ds datas.Dataset, vrw types.ValueReadWriter, ns tree.NodeStore) ([]*Stash, error) {
    37  	v, ok := ds.MaybeHead()
    38  	if !ok {
    39  		return nil, errors.New("stashes not found")
    40  	}
    41  
    42  	stashHashes, err := datas.GetHashListFromStashList(ctx, ns, v)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	var sl = make([]*Stash, len(stashHashes))
    48  	for i, stashHash := range stashHashes {
    49  		var s Stash
    50  		s.Name = fmt.Sprintf("stash@{%v}", i)
    51  		stashVal, err := vrw.ReadValue(ctx, stashHash)
    52  		if err != nil {
    53  			return nil, err
    54  		}
    55  
    56  		_, headCommitAddr, meta, err := datas.GetStashData(stashVal)
    57  		if err != nil {
    58  			return nil, err
    59  		}
    60  
    61  		hc, err := datas.LoadCommitAddr(ctx, vrw, headCommitAddr)
    62  		if err != nil {
    63  			return nil, err
    64  		}
    65  
    66  		if hc.IsGhost() {
    67  			return nil, ErrGhostCommitEncountered
    68  		}
    69  
    70  		headCommit, err := NewCommit(ctx, vrw, ns, hc)
    71  		if err != nil {
    72  			return nil, err
    73  		}
    74  
    75  		s.HeadCommit = headCommit
    76  		s.BranchName = meta.BranchName
    77  		s.Description = meta.Description
    78  
    79  		sl[i] = &s
    80  	}
    81  
    82  	return sl, nil
    83  }
    84  
    85  // getStashHashAtIdx returns hash address only of the stash at given index.
    86  func getStashHashAtIdx(ctx context.Context, ds datas.Dataset, ns tree.NodeStore, idx int) (hash.Hash, error) {
    87  	v, ok := ds.MaybeHead()
    88  	if !ok {
    89  		return hash.Hash{}, errors.New("stashes not found")
    90  	}
    91  
    92  	return datas.GetStashAtIdx(ctx, ns, v, idx)
    93  }
    94  
    95  // getStashAtIdx returns stash root value and head commit of a stash entry at given index.
    96  func getStashAtIdx(ctx context.Context, ds datas.Dataset, vrw types.ValueReadWriter, ns tree.NodeStore, idx int) (RootValue, *Commit, *datas.StashMeta, error) {
    97  	v, ok := ds.MaybeHead()
    98  	if !ok {
    99  		return nil, nil, nil, errors.New("stashes not found")
   100  	}
   101  
   102  	stashHash, err := datas.GetStashAtIdx(ctx, ns, v, idx)
   103  	if err != nil {
   104  		return nil, nil, nil, err
   105  	}
   106  	stashVal, err := vrw.ReadValue(ctx, stashHash)
   107  	if err != nil {
   108  		return nil, nil, nil, err
   109  	}
   110  
   111  	stashRootAddr, headCommitAddr, meta, err := datas.GetStashData(stashVal)
   112  	if err != nil {
   113  		return nil, nil, nil, err
   114  	}
   115  
   116  	hc, err := datas.LoadCommitAddr(ctx, vrw, headCommitAddr)
   117  	if err != nil {
   118  		return nil, nil, nil, err
   119  	}
   120  
   121  	if hc.IsGhost() {
   122  		return nil, nil, nil, ErrGhostCommitEncountered
   123  	}
   124  
   125  	headCommit, err := NewCommit(ctx, vrw, ns, hc)
   126  	if err != nil {
   127  		return nil, nil, nil, err
   128  	}
   129  
   130  	stashRootVal, err := vrw.ReadValue(ctx, stashRootAddr)
   131  	if err != nil {
   132  		return nil, nil, nil, err
   133  	}
   134  	stashRoot, err := NewRootValue(ctx, vrw, ns, stashRootVal)
   135  	if err != nil {
   136  		return nil, nil, nil, err
   137  	}
   138  
   139  	return stashRoot, headCommit, meta, nil
   140  }