Allow multiple refs for dolt log

This commit is contained in:
Taylor Bantle
2022-11-01 09:24:02 -07:00
parent 885f9f3416
commit 50d3ff23fd
12 changed files with 228 additions and 262 deletions

View File

@@ -40,7 +40,7 @@ import (
)
var commitDocs = cli.CommandDocumentationContent{
ShortDesc: "Record changes to the repository",
ShortDesc: "Record changes to the database",
LongDesc: `
Stores the current contents of the staged tables in a new commit along with a log message from the user describing the changes.

View File

@@ -36,14 +36,14 @@ import (
)
type logOpts struct {
numLines int
showParents bool
minParents int
decoration string
oneLine bool
excludingCommitSpec *doltdb.CommitSpec
commitSpec *doltdb.CommitSpec
tableName string
numLines int
showParents bool
minParents int
decoration string
oneLine bool
excludingCommitSpecs []*doltdb.CommitSpec
commitSpecs []*doltdb.CommitSpec
tableName string
}
type logNode struct {
@@ -114,17 +114,12 @@ func (cmd LogCmd) logWithLoggerFunc(ctx context.Context, commandStr string, args
help, usage := cli.HelpAndUsagePrinters(cli.CommandDocsForCommandString(commandStr, logDocs, ap))
apr := cli.ParseArgsOrDie(ap, args, help)
if apr.NArg() > 2 {
usage()
return 1
}
opts, err := parseLogArgs(ctx, dEnv, apr)
if err != nil {
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
}
if opts.commitSpec == nil {
opts.commitSpec = dEnv.RepoStateReader().CWBHeadSpec()
if len(opts.commitSpecs) == 0 {
opts.commitSpecs = append(opts.commitSpecs, dEnv.RepoStateReader().CWBHeadSpec())
}
if len(opts.tableName) > 0 {
return handleErrAndExit(logTableCommits(ctx, dEnv, opts))
@@ -152,146 +147,95 @@ func parseLogArgs(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPars
oneLine: apr.Contains(cli.OneLineFlag),
decoration: decorateOption,
}
cs, notCs, tableName, err := parseRefsAndTable(ctx, apr, dEnv)
err := opts.parseRefsAndTable(ctx, apr, dEnv)
if err != nil {
return nil, err
}
opts.commitSpec = cs
opts.excludingCommitSpec = notCs
opts.tableName = tableName
excludingRef, ok := apr.GetValue(cli.NotFlag)
if ok {
if opts.excludingCommitSpec != nil {
if len(opts.excludingCommitSpecs) > 0 {
return nil, fmt.Errorf("cannot use --not argument with two dots or ref with ^")
}
if len(opts.tableName) > 0 {
return nil, fmt.Errorf("cannot use --not argument with table")
}
cs, err := doltdb.NewCommitSpec(excludingRef)
notCs, err := doltdb.NewCommitSpec(excludingRef)
if err != nil {
return nil, fmt.Errorf("invalid commit %s\n", excludingRef)
}
opts.excludingCommitSpec = cs
opts.excludingCommitSpecs = append(opts.excludingCommitSpecs, notCs)
}
return opts, nil
}
func parseRefsAndTable(ctx context.Context, apr *argparser.ArgParseResults, dEnv *env.DoltEnv) (*doltdb.CommitSpec, *doltdb.CommitSpec, string, error) {
switch apr.NArg() {
// dolt log
case 0:
return nil, nil, "", nil
// dolt log <ref/^ref/revision-range/table>
case 1:
return getCommitOrTableFromString(ctx, apr.Arg(0), dEnv, true)
// dolt log <ref/^ref> <ref/^ref/table>
case 2:
firstCs, firstExNotCs, _, err := getCommitOrTableFromString(ctx, apr.Arg(0), dEnv, false)
if err != nil {
return nil, nil, "", err
}
secondCs, secondExNotCs, tableName, err := getCommitOrTableFromString(ctx, apr.Arg(1), dEnv, false)
if err != nil {
return nil, nil, "", err
}
if len(tableName) > 0 {
if firstExNotCs != nil {
return nil, nil, "", fmt.Errorf("Providing tableName for two dot log not yet supported")
}
// dolt log <ref> <table>
return firstCs, nil, tableName, nil
}
if firstCs != nil && secondCs != nil {
commit, err := dEnv.DoltDB.Resolve(ctx, firstCs, dEnv.RepoStateReader().CWBHeadRef())
if err != nil {
return nil, nil, "", err
}
// Handles table name matching branch name (dolt log <ref> <table>)
exists, err := tableExists(ctx, commit, apr.Arg(1))
if err != nil {
return nil, nil, "", err
}
if exists {
return firstCs, nil, apr.Arg(1), nil
}
return nil, nil, "", fmt.Errorf("Cannot provide two commit refs") // dolt log <ref> <ref>
}
if firstExNotCs != nil && secondExNotCs != nil {
return nil, nil, "", fmt.Errorf("Cannot exclude two commit refs") // dolt log ^<ref> ^<ref>
}
// dolt log ^<ref> <ref>
if firstExNotCs != nil && secondCs != nil {
return secondCs, firstExNotCs, "", nil
}
// dolt log <ref> ^<ref>
if firstCs != nil && secondExNotCs != nil {
return firstCs, secondExNotCs, "", nil
}
return nil, nil, "", nil
default:
return nil, nil, "", fmt.Errorf("Cannot provide more than 3 arguments")
}
}
func getCommitOrTableFromString(ctx context.Context, str string, dEnv *env.DoltEnv, canDot bool) (*doltdb.CommitSpec, *doltdb.CommitSpec, string, error) {
// <ref>...<ref>
if strings.Contains(str, "...") {
return nil, nil, "", fmt.Errorf("Three dot dolt log not supported")
func (opts *logOpts) parseRefsAndTable(ctx context.Context, apr *argparser.ArgParseResults, dEnv *env.DoltEnv) error {
// `dolt log`
if apr.NArg() == 0 {
return nil
}
// <ref>..<ref>
if strings.Contains(str, "..") {
if !canDot {
return nil, nil, "", fmt.Errorf("Cannot use two dot when 2 arguments provided")
// `dolt log <ref>..<ref>`
if strings.Contains(apr.Arg(0), "..") {
if strings.Contains(apr.Arg(0), "...") {
return fmt.Errorf("three dot log not yet supported")
}
refs := strings.Split(str, "..")
if apr.NArg() > 1 {
return fmt.Errorf("Cannot use two dot when 2 or more arguments provided")
}
refs := strings.Split(apr.Arg(0), "..")
notCs, err := getCommitSpec(refs[0])
if err != nil {
return nil, nil, "", err
return err
}
cs, err := getCommitSpec(refs[1])
if err != nil {
return nil, nil, "", err
return err
}
return cs, notCs, "", nil
opts.commitSpecs = append(opts.commitSpecs, cs)
opts.excludingCommitSpecs = append(opts.excludingCommitSpecs, notCs)
return nil
}
// ^<ref>
if strings.HasPrefix(str, "^") {
commit := strings.TrimPrefix(str, "^")
notCs, err := getCommitSpec(commit)
if err != nil {
return nil, nil, "", err
seenRefs := make(map[string]bool)
for _, arg := range apr.Args {
// ^<ref>
if strings.HasPrefix(arg, "^") {
commit := strings.TrimPrefix(arg, "^")
notCs, err := getCommitSpec(commit)
if err != nil {
return err
}
opts.excludingCommitSpecs = append(opts.excludingCommitSpecs, notCs)
} else {
argIsRef := actions.ValidateIsRef(ctx, arg, dEnv.DoltDB, dEnv.RepoStateReader())
// <ref>
if argIsRef && !seenRefs[arg] {
cs, err := getCommitSpec(arg)
if err != nil {
return err
}
seenRefs[arg] = true
opts.commitSpecs = append(opts.commitSpecs, cs)
} else {
// <table>
opts.tableName = arg
}
}
return nil, notCs, "", err
}
argIsRef := actions.ValidateIsRef(ctx, str, dEnv.DoltDB, dEnv.RepoStateReader())
// <ref>
if argIsRef {
cs, err := getCommitSpec(str)
if err != nil {
return nil, nil, "", err
}
return cs, nil, "", nil
if len(opts.tableName) > 0 && len(opts.excludingCommitSpecs) > 0 {
return fmt.Errorf("Cannot provide table name with excluding refs")
}
// <table>
return nil, nil, str, nil
return nil
}
func getCommitSpec(commit string) (*doltdb.CommitSpec, error) {
@@ -303,10 +247,22 @@ func getCommitSpec(commit string) (*doltdb.CommitSpec, error) {
}
func logCommits(ctx context.Context, dEnv *env.DoltEnv, opts *logOpts) int {
commit, err := dEnv.DoltDB.Resolve(ctx, opts.commitSpec, dEnv.RepoStateReader().CWBHeadRef())
if err != nil {
cli.PrintErrln(color.HiRedString("Fatal error: cannot get HEAD commit for current branch."))
return 1
hashes := make([]hash.Hash, len(opts.commitSpecs))
for i, cs := range opts.commitSpecs {
commit, err := dEnv.DoltDB.Resolve(ctx, cs, dEnv.RepoStateReader().CWBHeadRef())
if err != nil {
cli.PrintErrln(color.HiRedString("Fatal error: cannot get HEAD commit for current branch."))
return 1
}
h, err := commit.HashOf()
if err != nil {
cli.PrintErrln(color.HiRedString("Fatal error: failed to get commit hash"))
return 1
}
hashes[i] = h
}
cHashToRefs := map[hash.Hash][]string{}
@@ -356,39 +312,37 @@ func logCommits(ctx context.Context, dEnv *env.DoltEnv, opts *logOpts) int {
cHashToRefs[t.Hash] = append(cHashToRefs[t.Hash], tagName)
}
h, err := commit.HashOf()
if err != nil {
cli.PrintErrln(color.HiRedString("Fatal error: failed to get commit hash"))
return 1
}
matchFunc := func(commit *doltdb.Commit) (bool, error) {
return commit.NumParents() >= opts.minParents, nil
matchFunc := func(c *doltdb.Commit) (bool, error) {
return c.NumParents() >= opts.minParents, nil
}
var commits []*doltdb.Commit
if opts.excludingCommitSpec == nil {
commits, err = commitwalk.GetTopNTopoOrderedCommitsMatching(ctx, dEnv.DoltDB, h, opts.numLines, matchFunc)
if len(opts.excludingCommitSpecs) == 0 {
commits, err = commitwalk.GetTopNTopoOrderedCommitsMatching(ctx, dEnv.DoltDB, hashes, opts.numLines, matchFunc)
} else {
excludingCommit, err := dEnv.DoltDB.Resolve(ctx, opts.excludingCommitSpec, dEnv.RepoStateReader().CWBHeadRef())
if err != nil {
cli.PrintErrln(color.HiRedString("Fatal error: cannot get excluding commit for current branch."))
return 1
excludingHashes := make([]hash.Hash, len(opts.excludingCommitSpecs))
for i, excludingSpec := range opts.excludingCommitSpecs {
excludingCommit, err := dEnv.DoltDB.Resolve(ctx, excludingSpec, dEnv.RepoStateReader().CWBHeadRef())
if err != nil {
cli.PrintErrln(color.HiRedString("Fatal error: cannot get excluding commit for current branch."))
return 1
}
excludingHash, err := excludingCommit.HashOf()
if err != nil {
cli.PrintErrln(color.HiRedString("Fatal error: failed to get commit hash"))
return 1
}
excludingHashes[i] = excludingHash
}
excludingHash, err := excludingCommit.HashOf()
if err != nil {
cli.PrintErrln(color.HiRedString("Fatal error: failed to get commit hash"))
return 1
}
commits, err = commitwalk.GetDotDotRevisions(ctx, dEnv.DoltDB, h, dEnv.DoltDB, excludingHash, opts.numLines)
commits, err = commitwalk.GetDotDotRevisions(ctx, dEnv.DoltDB, hashes, dEnv.DoltDB, excludingHashes, opts.numLines)
}
if err != nil {
cli.PrintErrln("Error retrieving commit.")
cli.PrintErrln(err)
return 1
}
@@ -417,7 +371,7 @@ func logCommits(ctx context.Context, dEnv *env.DoltEnv, opts *logOpts) int {
commitHash: cmHash,
parentHashes: pHashes,
branchNames: cHashToRefs[cmHash],
isHead: cmHash == h})
isHead: hashIsHead(cmHash, hashes)})
}
logToStdOut(opts, commitsInfo)
@@ -425,6 +379,13 @@ func logCommits(ctx context.Context, dEnv *env.DoltEnv, opts *logOpts) int {
return 0
}
func hashIsHead(cmHash hash.Hash, hashes []hash.Hash) bool {
if len(hashes) > 1 || len(hashes) == 0 {
return false
}
return cmHash == hashes[0]
}
func tableExists(ctx context.Context, commit *doltdb.Commit, tableName string) (bool, error) {
rv, err := commit.GetRootValue(ctx)
if err != nil {
@@ -440,31 +401,37 @@ func tableExists(ctx context.Context, commit *doltdb.Commit, tableName string) (
}
func logTableCommits(ctx context.Context, dEnv *env.DoltEnv, opts *logOpts) error {
commit, err := dEnv.DoltDB.Resolve(ctx, opts.commitSpec, dEnv.RepoStateReader().CWBHeadRef())
if err != nil {
return err
}
hashes := make([]hash.Hash, len(opts.commitSpecs))
// Check that the table exists in the head commit
exists, err := tableExists(ctx, commit, opts.tableName)
if err != nil {
return err
}
for i, cs := range opts.commitSpecs {
commit, err := dEnv.DoltDB.Resolve(ctx, cs, dEnv.RepoStateReader().CWBHeadRef())
if err != nil {
return err
}
if !exists {
return fmt.Errorf("error: table %s does not exist", opts.tableName)
}
h, err := commit.HashOf()
if err != nil {
return err
}
h, err := commit.HashOf()
if err != nil {
return err
// Check that the table exists in the head commits
exists, err := tableExists(ctx, commit, opts.tableName)
if err != nil {
return err
}
if !exists {
return fmt.Errorf("error: table %s does not exist", opts.tableName)
}
hashes[i] = h
}
matchFunc := func(commit *doltdb.Commit) (bool, error) {
return commit.NumParents() >= opts.minParents, nil
}
itr, err := commitwalk.GetTopologicalOrderIterator(ctx, dEnv.DoltDB, h, matchFunc)
itr, err := commitwalk.GetTopologicalOrderIterator(ctx, dEnv.DoltDB, hashes, matchFunc)
if err != nil && err != io.EOF {
return err
}

View File

@@ -86,6 +86,7 @@ func (cmd MergeBaseCmd) Exec(ctx context.Context, commandStr string, args []stri
}
cli.Println(mergeBaseStr)
return 0
}

View File

@@ -219,7 +219,7 @@ func printRemoteRefTrackingInfo(ctx context.Context, dEnv *env.DoltEnv) error {
// countCommitsInRange returns the number of commits between the given starting point to trace back to the given target point.
// The starting commit must be a descendant of the target commit. Target commit must be a common ancestor commit.
func countCommitsInRange(ctx context.Context, ddb *doltdb.DoltDB, startCommitHash, targetCommitHash hash.Hash) (int, error) {
itr, iErr := commitwalk.GetTopologicalOrderIterator(ctx, ddb, startCommitHash, nil)
itr, iErr := commitwalk.GetTopologicalOrderIterator(ctx, ddb, []hash.Hash{startCommitHash}, nil)
if iErr != nil {
return 0, iErr
}

View File

@@ -158,71 +158,54 @@ func newQueue() *q {
// ties are broken by timestamp; newer commits appear first.
//
// Roughly mimics `git log main..feature`.
func GetDotDotRevisions(ctx context.Context, includedDB *doltdb.DoltDB, includedHead hash.Hash, excludedDB *doltdb.DoltDB, excludedHead hash.Hash, num int) ([]*doltdb.Commit, error) {
func GetDotDotRevisions(ctx context.Context, includedDB *doltdb.DoltDB, includedHeads []hash.Hash, excludedDB *doltdb.DoltDB, excludedHeads []hash.Hash, num int) ([]*doltdb.Commit, error) {
itr, err := GetDotDotRevisionsIterator(ctx, includedDB, includedHeads, excludedDB, excludedHeads, nil)
if err != nil {
return nil, err
}
var commitList []*doltdb.Commit
q := newQueue()
if err := q.SetInvisible(ctx, excludedDB, excludedHead); err != nil {
return nil, err
}
if err := q.AddPendingIfUnseen(ctx, excludedDB, excludedHead); err != nil {
return nil, err
}
if err := q.AddPendingIfUnseen(ctx, includedDB, includedHead); err != nil {
return nil, err
}
for q.NumVisiblePending() > 0 {
nextC := q.PopPending()
parents, err := nextC.commit.ParentHashes(ctx)
if err != nil {
for num < 0 || len(commitList) < num {
_, commit, err := itr.Next(ctx)
if err == io.EOF {
break
} else if err != nil {
return nil, err
}
for _, parentID := range parents {
if nextC.invisible {
if err := q.SetInvisible(ctx, nextC.ddb, parentID); err != nil {
return nil, err
}
}
if err := q.AddPendingIfUnseen(ctx, nextC.ddb, parentID); err != nil {
return nil, err
}
}
if !nextC.invisible {
commitList = append(commitList, nextC.commit)
if len(commitList) == num {
return commitList, nil
}
}
commitList = append(commitList, commit)
}
return commitList, nil
}
// GetTopologicalOrderCommits returns the commits reachable from the commit at hash `startCommitHash`
// GetTopologicalOrderCommits returns the commits reachable from the commits in `startCommitHashes`
// in reverse topological order, with tiebreaking done by the height of the commit graph -- higher commits
// appear first. Remaining ties are broken by timestamp; newer commits appear first.
func GetTopologicalOrderCommits(ctx context.Context, ddb *doltdb.DoltDB, startCommitHash hash.Hash) ([]*doltdb.Commit, error) {
return GetTopNTopoOrderedCommitsMatching(ctx, ddb, startCommitHash, -1, nil)
func GetTopologicalOrderCommits(ctx context.Context, ddb *doltdb.DoltDB, startCommitHashes []hash.Hash) ([]*doltdb.Commit, error) {
return GetTopNTopoOrderedCommitsMatching(ctx, ddb, startCommitHashes, -1, nil)
}
// GetTopologicalOrderCommitIterator returns an iterator for commits generated with the same semantics as
// GetTopologicalOrderCommits
func GetTopologicalOrderIterator(ctx context.Context, ddb *doltdb.DoltDB, startCommitHash hash.Hash, matchFn func(*doltdb.Commit) (bool, error)) (doltdb.CommitItr, error) {
return newCommiterator(ctx, ddb, startCommitHash, matchFn)
func GetTopologicalOrderIterator(ctx context.Context, ddb *doltdb.DoltDB, startCommitHashes []hash.Hash, matchFn func(*doltdb.Commit) (bool, error)) (doltdb.CommitItr, error) {
return newCommiterator(ctx, ddb, startCommitHashes, matchFn)
}
type commiterator struct {
ddb *doltdb.DoltDB
startCommitHash hash.Hash
matchFn func(*doltdb.Commit) (bool, error)
q *q
ddb *doltdb.DoltDB
startCommitHashes []hash.Hash
matchFn func(*doltdb.Commit) (bool, error)
q *q
}
var _ doltdb.CommitItr = (*commiterator)(nil)
func newCommiterator(ctx context.Context, ddb *doltdb.DoltDB, startCommitHash hash.Hash, matchFn func(*doltdb.Commit) (bool, error)) (*commiterator, error) {
func newCommiterator(ctx context.Context, ddb *doltdb.DoltDB, startCommitHashes []hash.Hash, matchFn func(*doltdb.Commit) (bool, error)) (*commiterator, error) {
itr := &commiterator{
ddb: ddb,
startCommitHash: startCommitHash,
matchFn: matchFn,
ddb: ddb,
startCommitHashes: startCommitHashes,
matchFn: matchFn,
}
err := itr.Reset(ctx)
@@ -270,17 +253,19 @@ func (i *commiterator) Next(ctx context.Context) (hash.Hash, *doltdb.Commit, err
// Reset implements doltdb.CommitItr
func (i *commiterator) Reset(ctx context.Context) error {
i.q = newQueue()
if err := i.q.AddPendingIfUnseen(ctx, i.ddb, i.startCommitHash); err != nil {
return err
for _, startCommitHash := range i.startCommitHashes {
if err := i.q.AddPendingIfUnseen(ctx, i.ddb, startCommitHash); err != nil {
return err
}
}
return nil
}
// GetTopNTopoOrderedCommitsMatching returns the first N commits (If N <= 0 then all commits) reachable from the commit at hash
// `startCommitHash` in reverse topological order, with tiebreaking done by the height of the commit graph -- higher
// GetTopNTopoOrderedCommitsMatching returns the first N commits (If N <= 0 then all commits) reachable from the commits in
// `startCommitHashes` in reverse topological order, with tiebreaking done by the height of the commit graph -- higher
// commits appear first. Remaining ties are broken by timestamp; newer commits appear first.
func GetTopNTopoOrderedCommitsMatching(ctx context.Context, ddb *doltdb.DoltDB, startCommitHash hash.Hash, n int, matchFn func(*doltdb.Commit) (bool, error)) ([]*doltdb.Commit, error) {
itr, err := GetTopologicalOrderIterator(ctx, ddb, startCommitHash, matchFn)
func GetTopNTopoOrderedCommitsMatching(ctx context.Context, ddb *doltdb.DoltDB, startCommitHashes []hash.Hash, n int, matchFn func(*doltdb.Commit) (bool, error)) ([]*doltdb.Commit, error) {
itr, err := GetTopologicalOrderIterator(ctx, ddb, startCommitHashes, matchFn)
if err != nil {
return nil, err
}
@@ -302,26 +287,28 @@ func GetTopNTopoOrderedCommitsMatching(ctx context.Context, ddb *doltdb.DoltDB,
// GetDotDotRevisionsIterator returns an iterator for commits generated with the same semantics as
// GetDotDotRevisions
func GetDotDotRevisionsIterator(ctx context.Context, ddb *doltdb.DoltDB, startCommitHash, excludingCommitHash hash.Hash, matchFn func(*doltdb.Commit) (bool, error)) (doltdb.CommitItr, error) {
return newDotDotCommiterator(ctx, ddb, startCommitHash, excludingCommitHash, matchFn)
func GetDotDotRevisionsIterator(ctx context.Context, includedDdb *doltdb.DoltDB, startCommitHashes []hash.Hash, excludedDdb *doltdb.DoltDB, excludingCommitHashes []hash.Hash, matchFn func(*doltdb.Commit) (bool, error)) (doltdb.CommitItr, error) {
return newDotDotCommiterator(ctx, includedDdb, startCommitHashes, excludedDdb, excludingCommitHashes, matchFn)
}
type dotDotCommiterator struct {
ddb *doltdb.DoltDB
startCommitHash hash.Hash
excludingCommitHash hash.Hash
matchFn func(*doltdb.Commit) (bool, error)
q *q
includedDdb *doltdb.DoltDB
excludedDdb *doltdb.DoltDB
startCommitHashes []hash.Hash
excludingCommitHashes []hash.Hash
matchFn func(*doltdb.Commit) (bool, error)
q *q
}
var _ doltdb.CommitItr = (*dotDotCommiterator)(nil)
func newDotDotCommiterator(ctx context.Context, ddb *doltdb.DoltDB, startCommitHash, excludingCommitHash hash.Hash, matchFn func(*doltdb.Commit) (bool, error)) (*dotDotCommiterator, error) {
func newDotDotCommiterator(ctx context.Context, includedDdb *doltdb.DoltDB, startCommitHashes []hash.Hash, excludedDdb *doltdb.DoltDB, excludingCommitHashes []hash.Hash, matchFn func(*doltdb.Commit) (bool, error)) (*dotDotCommiterator, error) {
itr := &dotDotCommiterator{
ddb: ddb,
startCommitHash: startCommitHash,
excludingCommitHash: excludingCommitHash,
matchFn: matchFn,
includedDdb: includedDdb,
excludedDdb: excludedDdb,
startCommitHashes: startCommitHashes,
excludingCommitHashes: excludingCommitHashes,
matchFn: matchFn,
}
err := itr.Reset(ctx)
@@ -373,14 +360,18 @@ func (i *dotDotCommiterator) Next(ctx context.Context) (hash.Hash, *doltdb.Commi
// Reset implements doltdb.CommitItr
func (i *dotDotCommiterator) Reset(ctx context.Context) error {
i.q = newQueue()
if err := i.q.SetInvisible(ctx, i.ddb, i.excludingCommitHash); err != nil {
return err
for _, excludingCommitHash := range i.excludingCommitHashes {
if err := i.q.SetInvisible(ctx, i.excludedDdb, excludingCommitHash); err != nil {
return err
}
if err := i.q.AddPendingIfUnseen(ctx, i.excludedDdb, excludingCommitHash); err != nil {
return err
}
}
if err := i.q.AddPendingIfUnseen(ctx, i.ddb, i.excludingCommitHash); err != nil {
return err
}
if err := i.q.AddPendingIfUnseen(ctx, i.ddb, i.startCommitHash); err != nil {
return err
for _, startCommitHash := range i.startCommitHashes {
if err := i.q.AddPendingIfUnseen(ctx, i.includedDdb, startCommitHash); err != nil {
return err
}
}
return nil
}

View File

@@ -121,7 +121,7 @@ func TestGetDotDotRevisions(t *testing.T) {
mainHash := mustGetHash(t, mainCommits[6])
featurePreMergeHash := mustGetHash(t, featureCommits[3])
res, err := GetDotDotRevisions(context.Background(), dEnv.DoltDB, featureHash, dEnv.DoltDB, mainHash, 100)
res, err := GetDotDotRevisions(context.Background(), dEnv.DoltDB, []hash.Hash{featureHash}, dEnv.DoltDB, []hash.Hash{mainHash}, 100)
require.NoError(t, err)
assert.Len(t, res, 7)
@@ -133,25 +133,25 @@ func TestGetDotDotRevisions(t *testing.T) {
assertEqualHashes(t, featureCommits[2], res[5])
assertEqualHashes(t, featureCommits[1], res[6])
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, mainHash, dEnv.DoltDB, featureHash, 100)
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, []hash.Hash{mainHash}, dEnv.DoltDB, []hash.Hash{featureHash}, 100)
require.NoError(t, err)
assert.Len(t, res, 0)
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, featureHash, dEnv.DoltDB, mainHash, 3)
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, []hash.Hash{featureHash}, dEnv.DoltDB, []hash.Hash{mainHash}, 3)
require.NoError(t, err)
assert.Len(t, res, 3)
assertEqualHashes(t, featureCommits[7], res[0])
assertEqualHashes(t, featureCommits[6], res[1])
assertEqualHashes(t, featureCommits[5], res[2])
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, featurePreMergeHash, dEnv.DoltDB, mainHash, 3)
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, []hash.Hash{featurePreMergeHash}, dEnv.DoltDB, []hash.Hash{mainHash}, 3)
require.NoError(t, err)
assert.Len(t, res, 3)
assertEqualHashes(t, featureCommits[3], res[0])
assertEqualHashes(t, featureCommits[2], res[1])
assertEqualHashes(t, featureCommits[1], res[2])
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, featurePreMergeHash, dEnv.DoltDB, mainHash, 3)
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, []hash.Hash{featurePreMergeHash}, dEnv.DoltDB, []hash.Hash{mainHash}, 3)
require.NoError(t, err)
assert.Len(t, res, 3)
assertEqualHashes(t, featureCommits[3], res[0])
@@ -170,9 +170,9 @@ func TestGetDotDotRevisions(t *testing.T) {
mainHash = mustGetHash(t, mainCommits[6])
featurePreMergeHash = mustGetHash(t, featureCommits[3])
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, featureHash, dEnv.DoltDB, mainHash, 100)
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, []hash.Hash{featureHash}, dEnv.DoltDB, []hash.Hash{mainHash}, 100)
require.Error(t, err)
res, err = GetDotDotRevisions(context.Background(), forkEnv.DoltDB, featureHash, dEnv.DoltDB, mainHash, 100)
res, err = GetDotDotRevisions(context.Background(), forkEnv.DoltDB, []hash.Hash{featureHash}, dEnv.DoltDB, []hash.Hash{mainHash}, 100)
require.NoError(t, err)
assert.Len(t, res, 7)
assertEqualHashes(t, featureCommits[7], res[0])
@@ -183,27 +183,27 @@ func TestGetDotDotRevisions(t *testing.T) {
assertEqualHashes(t, featureCommits[2], res[5])
assertEqualHashes(t, featureCommits[1], res[6])
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, mainHash, dEnv.DoltDB, featureHash, 100)
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, []hash.Hash{mainHash}, dEnv.DoltDB, []hash.Hash{featureHash}, 100)
require.Error(t, err)
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, mainHash, forkEnv.DoltDB, featureHash, 100)
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, []hash.Hash{mainHash}, forkEnv.DoltDB, []hash.Hash{featureHash}, 100)
require.NoError(t, err)
assert.Len(t, res, 0)
res, err = GetDotDotRevisions(context.Background(), forkEnv.DoltDB, featureHash, dEnv.DoltDB, mainHash, 3)
res, err = GetDotDotRevisions(context.Background(), forkEnv.DoltDB, []hash.Hash{featureHash}, dEnv.DoltDB, []hash.Hash{mainHash}, 3)
require.NoError(t, err)
assert.Len(t, res, 3)
assertEqualHashes(t, featureCommits[7], res[0])
assertEqualHashes(t, featureCommits[6], res[1])
assertEqualHashes(t, featureCommits[5], res[2])
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, featurePreMergeHash, dEnv.DoltDB, mainHash, 3)
res, err = GetDotDotRevisions(context.Background(), dEnv.DoltDB, []hash.Hash{featurePreMergeHash}, dEnv.DoltDB, []hash.Hash{mainHash}, 3)
require.NoError(t, err)
assert.Len(t, res, 3)
assertEqualHashes(t, featureCommits[3], res[0])
assertEqualHashes(t, featureCommits[2], res[1])
assertEqualHashes(t, featureCommits[1], res[2])
res, err = GetDotDotRevisions(context.Background(), forkEnv.DoltDB, featurePreMergeHash, dEnv.DoltDB, mainHash, 3)
res, err = GetDotDotRevisions(context.Background(), forkEnv.DoltDB, []hash.Hash{featurePreMergeHash}, dEnv.DoltDB, []hash.Hash{mainHash}, 3)
require.NoError(t, err)
assert.Len(t, res, 3)
assertEqualHashes(t, featureCommits[3], res[0])

View File

@@ -37,6 +37,7 @@ import (
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/globalstate"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil"
"github.com/dolthub/dolt/go/libraries/doltcore/table/editor"
"github.com/dolthub/dolt/go/store/hash"
)
var ErrInvalidTableName = errors.NewKind("Invalid table name %s. Table names must match the regular expression " + doltdb.TableNameRegexStr)
@@ -511,12 +512,12 @@ func resolveAsOfTime(ctx *sql.Context, ddb *doltdb.DoltDB, head ref.DoltRef, asO
return nil, nil, err
}
hash, err := cm.HashOf()
h, err := cm.HashOf()
if err != nil {
return nil, nil, err
}
cmItr, err := commitwalk.GetTopologicalOrderIterator(ctx, ddb, hash, nil)
cmItr, err := commitwalk.GetTopologicalOrderIterator(ctx, ddb, []hash.Hash{h}, nil)
if err != nil {
return nil, nil, err
}

View File

@@ -547,12 +547,12 @@ type logTableFunctionRowIter struct {
}
func (ltf *LogTableFunction) NewLogTableFunctionRowIter(ctx *sql.Context, ddb *doltdb.DoltDB, commit *doltdb.Commit, matchFn func(*doltdb.Commit) (bool, error), cHashToRefs map[hash.Hash][]string) (*logTableFunctionRowIter, error) {
hash, err := commit.HashOf()
h, err := commit.HashOf()
if err != nil {
return nil, err
}
child, err := commitwalk.GetTopologicalOrderIterator(ctx, ddb, hash, matchFn)
child, err := commitwalk.GetTopologicalOrderIterator(ctx, ddb, []hash.Hash{h}, matchFn)
if err != nil {
return nil, err
}
@@ -562,12 +562,12 @@ func (ltf *LogTableFunction) NewLogTableFunctionRowIter(ctx *sql.Context, ddb *d
showParents: ltf.showParents,
decoration: ltf.decoration,
cHashToRefs: cHashToRefs,
headHash: hash,
headHash: h,
}, nil
}
func (ltf *LogTableFunction) NewDotDotLogTableFunctionRowIter(ctx *sql.Context, ddb *doltdb.DoltDB, commit, excludingCommit *doltdb.Commit, matchFn func(*doltdb.Commit) (bool, error), cHashToRefs map[hash.Hash][]string) (*logTableFunctionRowIter, error) {
hash, err := commit.HashOf()
h, err := commit.HashOf()
if err != nil {
return nil, err
}
@@ -577,7 +577,7 @@ func (ltf *LogTableFunction) NewDotDotLogTableFunctionRowIter(ctx *sql.Context,
return nil, err
}
child, err := commitwalk.GetDotDotRevisionsIterator(ctx, ddb, hash, exHash, matchFn)
child, err := commitwalk.GetDotDotRevisionsIterator(ctx, ddb, []hash.Hash{h}, ddb, []hash.Hash{exHash}, matchFn)
if err != nil {
return nil, err
}
@@ -587,7 +587,7 @@ func (ltf *LogTableFunction) NewDotDotLogTableFunctionRowIter(ctx *sql.Context,
showParents: ltf.showParents,
decoration: ltf.decoration,
cHashToRefs: cHashToRefs,
headHash: hash,
headHash: h,
}, nil
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/dolt/go/libraries/doltcore/env/actions/commitwalk"
"github.com/dolthub/dolt/go/store/hash"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/index"
@@ -81,12 +82,12 @@ type LogItr struct {
// NewLogItr creates a LogItr from the current environment.
func NewLogItr(ctx *sql.Context, ddb *doltdb.DoltDB, head *doltdb.Commit) (*LogItr, error) {
hash, err := head.HashOf()
h, err := head.HashOf()
if err != nil {
return nil, err
}
child, err := commitwalk.GetTopologicalOrderIterator(ctx, ddb, hash, nil)
child, err := commitwalk.GetTopologicalOrderIterator(ctx, ddb, []hash.Hash{h}, nil)
if err != nil {
return nil, err
}

View File

@@ -363,7 +363,7 @@ func findCommonAncestorUsingParentsList(ctx context.Context, c1, c2 *Commit, vr1
// FindCommonAncestor returns the most recent common ancestor of c1 and c2, if
// one exists, setting ok to true. If there is no common ancestor, ok is set
// to false. Refs of |c1| are dereferenced through |vr1|, while refs of |c2|
// are dereference through |vr2|.
// are dereferenced through |vr2|.
//
// This implementation makes use of the parents_closure field on the commit
// struct. If the commit does not have a materialized parents_closure, this

View File

@@ -105,6 +105,13 @@ teardown() {
[[ ! "$output" =~ "MAIN" ]] || false
[[ ! "$output" =~ "AFTER" ]] || false
[[ "$output" =~ "BRANCH1" ]] || false
run dolt log ^main ^branch1
[ $status -eq 0 ]
run dolt log main branch1
[ $status -eq 0 ]
[[ "$output" =~ "MAIN" ]] || false
[[ "$output" =~ "AFTER" ]] || false
[[ "$output" =~ "BRANCH1" ]] || false
# Invalid two dot
run dolt log main..branch1 testtable
@@ -119,12 +126,10 @@ teardown() {
[ $status -eq 1 ]
run dolt log main main..branch1
[ $status -eq 1 ]
run dolt log ^main ^branch1
[ $status -eq 1 ]
run dolt log main branch1
[ $status -eq 1 ]
run dolt log ^main testtable
[ $status -eq 1 ]
run dolt log testtable ^main
[ $status -eq 1 ]
run dolt log ^branch1 --not main
[ $status -eq 1 ]
run dolt log main..branch1 --not main

View File

@@ -27,7 +27,7 @@ setup() {
# / #
# / <-- (one) #
# / / #
# (init) -- (A) -- (B) -- (C) <-- (main) #
# (init) -- (A) -- (B) -- (C) <-- (main) #
# \ #
# -- (D) <-- (two) #
# #