mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-28 20:49:43 -05:00
Be more selective in our remote references when cloning another repo
This commit is contained in:
@@ -1254,6 +1254,27 @@ func (ddb *DoltDB) deleteRef(ctx context.Context, dref ref.DoltRef, replicationS
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteAllRefs Very destructive, use with caution. Not only does this drop all data, Dolt assume there is always
|
||||
// a reference in the DB, so do not call this and walk away. The only use case for this method is the
|
||||
// `dolt clone` command which strip everything from the remote's root object - dolt_clone stored procedure doesn't currently
|
||||
// use this code path (TODO).
|
||||
func (ddb *DoltDB) DeleteAllRefs(ctx context.Context) error {
|
||||
dss, err := ddb.db.Datasets(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = dss.IterAll(ctx, func(key string, addr hash.Hash) error {
|
||||
ds, e := ddb.db.GetDataset(ctx, key)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
_, e = ddb.db.Delete(ctx, ds, "")
|
||||
return e
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// NewTagAtCommit create a new tag at the commit given.
|
||||
func (ddb *DoltDB) NewTagAtCommit(ctx context.Context, tagRef ref.DoltRef, c *Commit, meta *datas.TagMeta) error {
|
||||
if !IsValidTagRef(tagRef) {
|
||||
|
||||
+38
-25
@@ -47,10 +47,10 @@ var ErrNoDataAtRemote = errors.New("remote at that url contains no Dolt data")
|
||||
var ErrFailedToListBranches = errors.New("failed to list branches")
|
||||
var ErrFailedToGetBranch = errors.New("could not get branch")
|
||||
var ErrFailedToGetRootValue = errors.New("could not find root value")
|
||||
var ErrFailedToResolveBranchRef = errors.New("could not resole branch ref")
|
||||
var ErrFailedToCreateRemoteRef = errors.New("could not create remote ref")
|
||||
var ErrFailedToCreateTagRef = errors.New("could not create tag ref")
|
||||
var ErrFailedToCreateLocalBranch = errors.New("could not create local branch")
|
||||
var ErrFailedToDeleteBranch = errors.New("could not delete local branch after clone")
|
||||
var ErrFailedToUpdateDocs = errors.New("failed to update docs on the filesystem")
|
||||
var ErrUserNotFound = errors.New("could not determine user name. run dolt config --global --add user.name")
|
||||
var ErrEmailNotFound = errors.New("could not determine email. run dolt config --global --add user.email")
|
||||
var ErrCloneFailed = errors.New("clone failed")
|
||||
@@ -179,11 +179,20 @@ func CloneRemote(ctx context.Context, srcDB *doltdb.DoltDB, remoteName, branch s
|
||||
return fmt.Errorf("%w; %s", ErrCloneFailed, err.Error())
|
||||
}
|
||||
|
||||
branches, err := dEnv.DoltDB.GetBranches(ctx)
|
||||
// Get all the refs from the remote. These branch remotes will be translated to remote branches, tags will
|
||||
// be preserved, and all other refs will be ignored.
|
||||
remoteRefHashes, err := dEnv.DoltDB.GetRefsWithHashes(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w; %s", ErrFailedToListBranches, err.Error())
|
||||
return fmt.Errorf("%w; %s", ErrCloneFailed, err.Error())
|
||||
}
|
||||
|
||||
branches := make([]ref.DoltRef, 0, len(remoteRefHashes))
|
||||
for _, refHash := range remoteRefHashes {
|
||||
if refHash.Ref.GetType() == ref.BranchRefType {
|
||||
br := refHash.Ref.(ref.BranchRef)
|
||||
branches = append(branches, br)
|
||||
}
|
||||
}
|
||||
if branch == "" {
|
||||
branch = env.GetDefaultBranch(dEnv, branches)
|
||||
}
|
||||
@@ -210,31 +219,35 @@ func CloneRemote(ctx context.Context, srcDB *doltdb.DoltDB, remoteName, branch s
|
||||
return fmt.Errorf("%w: %s; %s", ErrFailedToGetRootValue, branch, err.Error())
|
||||
}
|
||||
|
||||
// After actions.Clone, we have repository with a local branch for
|
||||
// every branch in the remote. What we want is a remote branch ref for
|
||||
// every branch in the remote. We iterate through local branches and
|
||||
// create remote refs corresponding to each of them. We delete all of
|
||||
// the local branches except for the one corresponding to |branch|.
|
||||
for _, br := range branches {
|
||||
if !singleBranch || br.GetPath() == branch {
|
||||
cs, _ := doltdb.NewCommitSpec(br.GetPath())
|
||||
cm, err := dEnv.DoltDB.Resolve(ctx, cs, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %s; %s", ErrFailedToResolveBranchRef, br.String(), err.Error())
|
||||
err = dEnv.DoltDB.DeleteAllRefs(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Preserve only branch and tag references from the remote. Branches are translated into remote branches, tags are preserved.
|
||||
for _, refHash := range remoteRefHashes {
|
||||
if refHash.Ref.GetType() == ref.BranchRefType {
|
||||
br := refHash.Ref.(ref.BranchRef)
|
||||
if !singleBranch || br.GetPath() == branch {
|
||||
remoteRef := ref.NewRemoteRef(remoteName, br.GetPath())
|
||||
err = dEnv.DoltDB.SetHead(ctx, remoteRef, refHash.Hash)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %s; %s", ErrFailedToCreateRemoteRef, remoteRef.String(), err.Error())
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
remoteRef := ref.NewRemoteRef(remoteName, br.GetPath())
|
||||
err = dEnv.DoltDB.SetHeadToCommit(ctx, remoteRef, cm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %s; %s", ErrFailedToCreateRemoteRef, remoteRef.String(), err.Error())
|
||||
|
||||
if br.GetPath() == branch {
|
||||
// This is the only local branch after the clone is complete.
|
||||
err = dEnv.DoltDB.SetHead(ctx, br, refHash.Hash)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %s; %s", ErrFailedToCreateLocalBranch, br.String(), err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
if br.GetPath() != branch {
|
||||
err := dEnv.DoltDB.DeleteBranch(ctx, br, nil)
|
||||
} else if refHash.Ref.GetType() == ref.TagRefType {
|
||||
tr := refHash.Ref.(ref.TagRef)
|
||||
err = dEnv.DoltDB.SetHead(ctx, tr, refHash.Hash)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %s; %s", ErrFailedToDeleteBranch, br.String(), err.Error())
|
||||
return fmt.Errorf("%w: %s; %s", ErrFailedToCreateTagRef, tr.String(), err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user