Skip to content

Commit

Permalink
Merge pull request #7929 from dolthub/macneale4/fetch-empty
Browse files Browse the repository at this point in the history
dolt fetch default spec from empty repo should return silently
  • Loading branch information
macneale4 authored May 30, 2024
2 parents 0ca0493 + e3af8eb commit 13cec7d
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 10 deletions.
2 changes: 1 addition & 1 deletion go/libraries/doltcore/env/actions/clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ func shallowCloneDataPull(ctx context.Context, destData env.DbData, srcDB *doltd
return nil, fmt.Errorf("remote %s not found", remoteName)
}

specs, err := env.ParseRefSpecs([]string{branch}, destData.Rsr, remote)
specs, _, err := env.ParseRefSpecs([]string{branch}, destData.Rsr, remote)
if err != nil {
return nil, err
}
Expand Down
27 changes: 25 additions & 2 deletions go/libraries/doltcore/env/actions/remotes.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ func ShallowFetchRefSpec(
return fmt.Errorf("invalid depth: %d", depth)
}

return fetchRefSpecsWithDepth(ctx, dbData, srcDB, []ref.RemoteRefSpec{refSpecs}, remote, ref.ForceUpdate, depth, nil, nil)
return fetchRefSpecsWithDepth(ctx, dbData, srcDB, []ref.RemoteRefSpec{refSpecs}, false, remote, ref.ForceUpdate, depth, nil, nil)
}

// FetchRefSpecs is the common SQL and CLI entrypoint for fetching branches, tags, and heads from a remote.
Expand All @@ -487,19 +487,34 @@ func FetchRefSpecs(
dbData env.DbData,
srcDB *doltdb.DoltDB,
refSpecs []ref.RemoteRefSpec,
defaultRefSpec bool,
remote *env.Remote,
mode ref.UpdateMode,
progStarter ProgStarter,
progStopper ProgStopper,
) error {
return fetchRefSpecsWithDepth(ctx, dbData, srcDB, refSpecs, remote, mode, -1, progStarter, progStopper)
return fetchRefSpecsWithDepth(ctx, dbData, srcDB, refSpecs, defaultRefSpec, remote, mode, -1, progStarter, progStopper)
}

// fetchRefSpecsWithDepth fetches the remote refSpecs from the source database to the destination database. It fetches
// the commits and all underlying data from the source database to the destination database.
// Parameters:
// - ctx: the context
// - dbData: the env.DbData object for handling repoState read and write
// - srcDB: the remote *doltdb.DoltDB object that is used to fetch remote branches from
// - refSpecs: the list of refSpecs to fetch
// - defaultRefSpecs: a boolean that indicates whether the refSpecs are the default refSpecs. False if the user specifies anything.
// - remote: the remote object
// - mode: the ref.UpdateMode object that specifies the update mode (force or not, prune or not)
// - depth: the depth of the fetch. If depth is greater than 0, it is a shallow clone.
// - progStarter: function that starts the progress reporting
// - progStopper: function that stops the progress reporting
func fetchRefSpecsWithDepth(
ctx context.Context,
dbData env.DbData,
srcDB *doltdb.DoltDB,
refSpecs []ref.RemoteRefSpec,
defaultRefSpecs bool,
remote *env.Remote,
mode ref.UpdateMode,
depth int,
Expand All @@ -515,6 +530,14 @@ func fetchRefSpecsWithDepth(
return fmt.Errorf("%w: %s", env.ErrFailedToReadDb, err.Error())
}

if len(branchRefs) == 0 {
if defaultRefSpecs {
// The remote has no branches. Nothing to do. Git exits silently, so we do too.
return nil
}
return fmt.Errorf("no branches found in remote '%s'", remote.Name)
}

// We build up two structures:
// 1) The list of chunk addresses to fetch, representing the remote branch heads.
// 2) A mapping from branch HEAD to the remote tracking ref we're going to update.
Expand Down
11 changes: 7 additions & 4 deletions go/libraries/doltcore/env/remotes.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,12 +416,15 @@ func RemoteForFetchArgs(args []string, rsr RepoStateReader) (Remote, []string, e
}

// ParseRefSpecs returns the ref specs for the string arguments given for the remote provided, or the default ref
// specs for that remote if no arguments are provided.
func ParseRefSpecs(args []string, rsr RepoStateReader, remote Remote) ([]ref.RemoteRefSpec, error) {
// specs for that remote if no arguments are provided. In the event that the default ref specs are returned, the
// returned boolean value will be true.
func ParseRefSpecs(args []string, rsr RepoStateReader, remote Remote) ([]ref.RemoteRefSpec, bool, error) {
if len(args) != 0 {
return ParseRSFromArgs(remote.Name, args)
specs, err := ParseRSFromArgs(remote.Name, args)
return specs, false, err
} else {
return GetRefSpecs(rsr, remote.Name)
specs, err := GetRefSpecs(rsr, remote.Name)
return specs, true, err
}
}

Expand Down
4 changes: 2 additions & 2 deletions go/libraries/doltcore/sqle/dprocedures/dolt_fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func doDoltFetch(ctx *sql.Context, args []string) (int, error) {
return cmdFailure, validationErr
}

refSpecs, err := env.ParseRefSpecs(refSpecArgs, dbData.Rsr, remote)
refSpecs, defaultRefSpec, err := env.ParseRefSpecs(refSpecArgs, dbData.Rsr, remote)
if err != nil {
return cmdFailure, err
}
Expand All @@ -87,7 +87,7 @@ func doDoltFetch(ctx *sql.Context, args []string) (int, error) {

prune := apr.Contains(cli.PruneFlag)
mode := ref.UpdateMode{Force: true, Prune: prune}
err = actions.FetchRefSpecs(ctx, dbData, srcDB, refSpecs, &remote, mode, runProgFuncs, stopProgFuncs)
err = actions.FetchRefSpecs(ctx, dbData, srcDB, refSpecs, defaultRefSpec, &remote, mode, runProgFuncs, stopProgFuncs)
if err != nil {
return cmdFailure, fmt.Errorf("fetch failed: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion go/libraries/doltcore/sqle/dprocedures/dolt_pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func doDoltPull(ctx *sql.Context, args []string) (int, int, string, error) {
}

mode := ref.UpdateMode{Force: true, Prune: false}
err = actions.FetchRefSpecs(ctx, dbData, srcDB, pullSpec.RefSpecs, &pullSpec.Remote, mode, runProgFuncs, stopProgFuncs)
err = actions.FetchRefSpecs(ctx, dbData, srcDB, pullSpec.RefSpecs, false, &pullSpec.Remote, mode, runProgFuncs, stopProgFuncs)
if err != nil {
return noConflictsOrViolations, threeWayMerge, "", fmt.Errorf("fetch failed: %w", err)
}
Expand Down
13 changes: 13 additions & 0 deletions integration-tests/bats/fetch.bats
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,19 @@ teardown() {
[[ "$output" =~ "invalid fetch spec: ''" ]] || false
}

@test "fetch: fetching from empty remote" {
cd repo2
dolt remote add empty file://../empty

setup_remote_server

dolt fetch empty

run dolt fetch empty main
[ "$status" -eq 1 ]
[[ "$output" =~ "no branches found in remote 'empty'" ]] || false
}

@test "fetch: fetch from remote host fails" {
run dolt --host hostedHost --port 3306 --user root --password password fetch origin
[ "$status" -eq 1 ]
Expand Down

0 comments on commit 13cec7d

Please sign in to comment.