[gitiles] Tweaks needed for GitSync
Change-Id: Ieb548a8571383dd14980f9eadf32ec802a96b0db
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/235537
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Commit-Queue: Eric Boren <borenet@google.com>
diff --git a/autoroll/go/autoroll-google3/google3_test.go b/autoroll/go/autoroll-google3/google3_test.go
index f50d12a..7b1c2c7 100644
--- a/autoroll/go/autoroll-google3/google3_test.go
+++ b/autoroll/go/autoroll-google3/google3_test.go
@@ -100,7 +100,7 @@
commits = append(commits, gb.CommitGen(ctx, "a.txt"))
mockChild.MockGetCommit(ctx, "master")
- mockChild.MockLog(ctx, commits[0], commits[1])
+ mockChild.MockLog(ctx, git.LogFromTo(commits[0], commits[1]))
assert.NoError(t, a.UpdateStatus(ctx, "", true))
status := a.status.Get()
assert.Equal(t, 0, status.NumFailedRolls)
@@ -128,7 +128,7 @@
recent := []*autoroll.AutoRollIssue{issue4, issue3, issue2, issue1}
mockChild.MockGetCommit(ctx, "master")
- mockChild.MockLog(ctx, commits[0], commits[2])
+ mockChild.MockLog(ctx, git.LogFromTo(commits[0], commits[2]))
assert.NoError(t, a.UpdateStatus(ctx, "error message", false))
status = a.status.Get()
assert.Equal(t, 2, status.NumFailedRolls)
@@ -141,7 +141,7 @@
// Test preserving error.
mockChild.MockGetCommit(ctx, "master")
- mockChild.MockLog(ctx, commits[0], commits[2])
+ mockChild.MockLog(ctx, git.LogFromTo(commits[0], commits[2]))
assert.NoError(t, a.UpdateStatus(ctx, "", true))
status = a.status.Get()
assert.Equal(t, "error message", status.Error)
@@ -160,7 +160,7 @@
recent = append([]*autoroll.AutoRollIssue{issueI}, recent...)
}
mockChild.MockGetCommit(ctx, "master")
- mockChild.MockLog(ctx, commits[0], commits[2])
+ mockChild.MockLog(ctx, git.LogFromTo(commits[0], commits[2]))
assert.NoError(t, a.UpdateStatus(ctx, "error message", false))
status = a.status.Get()
assert.Equal(t, recent_rolls.RECENT_ROLLS_LENGTH+1, status.NumFailedRolls)
@@ -188,7 +188,7 @@
closeIssue(issue2, autoroll.ROLL_RESULT_SUCCESS)
assert.NoError(t, a.AddOrUpdateIssue(ctx, issue2, http.MethodPut))
mockChild.MockGetCommit(ctx, "master")
- mockChild.MockLog(ctx, commits[1], commits[2])
+ mockChild.MockLog(ctx, git.LogFromTo(commits[1], commits[2]))
assert.NoError(t, a.UpdateStatus(ctx, "", true))
deepequal.AssertDeepEqual(t, []*autoroll.AutoRollIssue{issue2, issue1}, a.status.Get().Recent)
@@ -198,7 +198,7 @@
issue4 := makeIssue(4, commits[2])
assert.NoError(t, a.AddOrUpdateIssue(ctx, issue4, http.MethodPost))
mockChild.MockGetCommit(ctx, "master")
- mockChild.MockLog(ctx, commits[1], commits[2])
+ mockChild.MockLog(ctx, git.LogFromTo(commits[1], commits[2]))
assert.NoError(t, a.UpdateStatus(ctx, "", true))
issue3.Closed = true
issue3.Result = autoroll.ROLL_RESULT_FAILURE
@@ -209,7 +209,7 @@
closeIssue(issue5, autoroll.ROLL_RESULT_SUCCESS)
assert.NoError(t, a.AddOrUpdateIssue(ctx, issue5, http.MethodPut))
mockChild.MockGetCommit(ctx, "master")
- mockChild.MockLog(ctx, commits[2], commits[2])
+ mockChild.MockLog(ctx, git.LogFromTo(commits[2], commits[2]))
assert.NoError(t, a.UpdateStatus(ctx, "", true))
issue4.Closed = true
issue4.Result = autoroll.ROLL_RESULT_FAILURE
diff --git a/autoroll/go/repo_manager/android_repo_manager.go b/autoroll/go/repo_manager/android_repo_manager.go
index 1937f49..28fc1d2 100644
--- a/autoroll/go/repo_manager/android_repo_manager.go
+++ b/autoroll/go/repo_manager/android_repo_manager.go
@@ -18,6 +18,7 @@
"go.skia.org/infra/go/common"
"go.skia.org/infra/go/exec"
"go.skia.org/infra/go/gerrit"
+ "go.skia.org/infra/go/git"
"go.skia.org/infra/go/sklog"
"go.skia.org/infra/go/util"
"go.skia.org/infra/go/vcsinfo"
@@ -281,7 +282,7 @@
// Create the roll CL.
cr := r.childRepo
- commits, err := cr.RevList(ctx, fmt.Sprintf("%s..%s", from.Id, to.Id))
+ commits, err := cr.RevList(ctx, git.LogFromTo(from.Id, to.Id))
if err != nil {
return 0, fmt.Errorf("Failed to list revisions: %s", err)
}
@@ -508,7 +509,7 @@
return []*revision.Revision{}, nil
}
// Only consider commits on the "main" branch as roll candidates.
- commits, err := r.childRepo.RevList(ctx, "--ancestry-path", "--first-parent", fmt.Sprintf("%s..%s", lastRollRev.Id, head))
+ commits, err := r.childRepo.RevList(ctx, "--ancestry-path", "--first-parent", git.LogFromTo(lastRollRev.Id, head))
if err != nil {
return nil, err
}
diff --git a/autoroll/go/repo_manager/copy_repo_manager.go b/autoroll/go/repo_manager/copy_repo_manager.go
index 174daf2..2cfcf7f 100644
--- a/autoroll/go/repo_manager/copy_repo_manager.go
+++ b/autoroll/go/repo_manager/copy_repo_manager.go
@@ -163,7 +163,7 @@
}()
// List the revisions in the roll.
- commits, err := rm.childRepo.RevList(ctx, fmt.Sprintf("%s..%s", from.Id, to.Id))
+ commits, err := rm.childRepo.RevList(ctx, git.LogFromTo(from.Id, to.Id))
if err != nil {
return 0, fmt.Errorf("Failed to list revisions: %s", err)
}
diff --git a/autoroll/go/repo_manager/deps_repo_manager.go b/autoroll/go/repo_manager/deps_repo_manager.go
index 9fd8a04..9f8d22f 100644
--- a/autoroll/go/repo_manager/deps_repo_manager.go
+++ b/autoroll/go/repo_manager/deps_repo_manager.go
@@ -15,6 +15,7 @@
"go.skia.org/infra/autoroll/go/revision"
"go.skia.org/infra/go/exec"
"go.skia.org/infra/go/gerrit"
+ "go.skia.org/infra/go/git"
"go.skia.org/infra/go/issues"
"go.skia.org/infra/go/sklog"
"go.skia.org/infra/go/util"
@@ -162,7 +163,7 @@
// Create the roll CL.
cr := dr.childRepo
- commits, err := cr.RevList(ctx, fmt.Sprintf("%s..%s", from.Id, to.Id))
+ commits, err := cr.RevList(ctx, git.LogFromTo(from.Id, to.Id))
if err != nil {
return 0, fmt.Errorf("Failed to list revisions: %s", err)
}
diff --git a/autoroll/go/repo_manager/freetype_repo_manager.go b/autoroll/go/repo_manager/freetype_repo_manager.go
index 038f4b5..eb038b1 100644
--- a/autoroll/go/repo_manager/freetype_repo_manager.go
+++ b/autoroll/go/repo_manager/freetype_repo_manager.go
@@ -182,7 +182,7 @@
}
// Check modules.cfg. Give up if it has changed.
- diff, err := rm.localChildRepo.Git(ctx, "diff", "--name-only", fmt.Sprintf("%s..%s", from.Id, to.Id))
+ diff, err := rm.localChildRepo.Git(ctx, "diff", "--name-only", git.LogFromTo(from.Id, to.Id))
if err != nil {
return "", nil, err
}
diff --git a/autoroll/go/repo_manager/freetype_repo_manager_test.go b/autoroll/go/repo_manager/freetype_repo_manager_test.go
index 4fbd3c5..5bb6e67 100644
--- a/autoroll/go/repo_manager/freetype_repo_manager_test.go
+++ b/autoroll/go/repo_manager/freetype_repo_manager_test.go
@@ -110,7 +110,7 @@
parentMaster, err := git.GitDir(parent.Dir()).RevParse(ctx, "HEAD")
assert.NoError(t, err)
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
rm, err := NewFreeTypeRepoManager(ctx, cfg, wd, g, recipesCfg, "fake.server.com", "", urlmock.Client(), gerritCR(t, g), false)
@@ -135,7 +135,7 @@
parentMaster, err := git.GitDir(parentRepo.Dir()).RevParse(ctx, "HEAD")
assert.NoError(t, err)
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
nextRollRev := childCommits[len(childCommits)-1]
assert.NoError(t, rm.Update(ctx))
@@ -154,7 +154,7 @@
rev, err := rm.GetRevision(ctx, c)
assert.NoError(t, err)
assert.Equal(t, c, rev.Id)
- mockChild.MockLog(ctx, c, childCommits[0])
+ mockChild.MockLog(ctx, git.LogFromTo(c, childCommits[0]))
rp, err := rm.RolledPast(ctx, rev)
assert.NoError(t, err)
assert.False(t, rp)
@@ -169,7 +169,7 @@
parentMaster, err := git.GitDir(parentRepo.Dir()).RevParse(ctx, "HEAD")
assert.NoError(t, err)
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
nextRollRev := childCommits[1]
assert.NoError(t, rm.Update(ctx))
@@ -179,7 +179,7 @@
assert.NoError(t, SetStrategy(ctx, rm, strategy.ROLL_STRATEGY_BATCH))
mockParent.MockGetCommit(ctx, "master")
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
assert.NoError(t, rm.Update(ctx))
assert.Equal(t, childCommits[len(childCommits)-1], rm.NextRollRev().Id)
@@ -187,7 +187,7 @@
assert.NoError(t, SetStrategy(ctx, rm, strategy.ROLL_STRATEGY_SINGLE))
mockParent.MockGetCommit(ctx, "master")
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
assert.NoError(t, rm.Update(ctx))
assert.Equal(t, childCommits[1], rm.NextRollRev().Id)
@@ -201,7 +201,7 @@
parentMaster, err := git.GitDir(parentRepo.Dir()).RevParse(ctx, "HEAD")
assert.NoError(t, err)
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
nextRollRev := childCommits[len(childCommits)-1]
assert.NoError(t, rm.Update(ctx))
@@ -224,7 +224,7 @@
// Mock the initial change creation.
logStr := ""
childGitRepo := git.GitDir(childRepo.Dir())
- commitsToRoll, err := childGitRepo.RevList(ctx, fmt.Sprintf("%s..%s", lastRollRev, nextRollRev))
+ commitsToRoll, err := childGitRepo.RevList(ctx, git.LogFromTo(lastRollRev, nextRollRev))
assert.NoError(t, err)
for _, c := range commitsToRoll {
mockChild.MockGetCommit(ctx, c)
diff --git a/autoroll/go/repo_manager/github_deps_repo_manager.go b/autoroll/go/repo_manager/github_deps_repo_manager.go
index 6ada471..ee6c244 100644
--- a/autoroll/go/repo_manager/github_deps_repo_manager.go
+++ b/autoroll/go/repo_manager/github_deps_repo_manager.go
@@ -304,7 +304,7 @@
// Build the commit message.
user, repo := GetUserAndRepo(rm.childRepoUrl)
- commits, err := rm.childRepo.RevList(ctx, "--no-merges", fmt.Sprintf("%s..%s", from.Id, to.Id))
+ commits, err := rm.childRepo.RevList(ctx, "--no-merges", git.LogFromTo(from.Id, to.Id))
if err != nil {
return 0, fmt.Errorf("Failed to list revisions: %s", err)
}
diff --git a/autoroll/go/repo_manager/github_repo_manager.go b/autoroll/go/repo_manager/github_repo_manager.go
index 6db3d39..263b9bf 100644
--- a/autoroll/go/repo_manager/github_repo_manager.go
+++ b/autoroll/go/repo_manager/github_repo_manager.go
@@ -301,7 +301,7 @@
// Build the commit message.
user, repo := GetUserAndRepo(rm.childRepoURL)
- commits, err := rm.childRepo.RevList(ctx, "--no-merges", fmt.Sprintf("%s..%s", from.Id, to.Id))
+ commits, err := rm.childRepo.RevList(ctx, "--no-merges", git.LogFromTo(from.Id, to.Id))
if err != nil {
return 0, fmt.Errorf("Failed to list revisions: %s", err)
}
diff --git a/autoroll/go/repo_manager/no_checkout_deps_repo_manager.go b/autoroll/go/repo_manager/no_checkout_deps_repo_manager.go
index 7b95630..14f4651 100644
--- a/autoroll/go/repo_manager/no_checkout_deps_repo_manager.go
+++ b/autoroll/go/repo_manager/no_checkout_deps_repo_manager.go
@@ -17,6 +17,7 @@
"go.skia.org/infra/go/depot_tools"
"go.skia.org/infra/go/exec"
"go.skia.org/infra/go/gerrit"
+ "go.skia.org/infra/go/git"
"go.skia.org/infra/go/gitiles"
"go.skia.org/infra/go/issues"
"go.skia.org/infra/go/sklog"
@@ -267,7 +268,7 @@
if rev.Id == rm.lastRollRev.Id {
return true, nil
}
- commits, err := rm.childRepo.Log(ctx, rev.Id, rm.lastRollRev.Id)
+ commits, err := rm.childRepo.Log(ctx, git.LogFromTo(rev.Id, rm.lastRollRev.Id))
if err != nil {
return false, err
}
diff --git a/autoroll/go/repo_manager/no_checkout_deps_repo_manager_test.go b/autoroll/go/repo_manager/no_checkout_deps_repo_manager_test.go
index 48ece00..0a18186 100644
--- a/autoroll/go/repo_manager/no_checkout_deps_repo_manager_test.go
+++ b/autoroll/go/repo_manager/no_checkout_deps_repo_manager_test.go
@@ -79,7 +79,7 @@
parentMaster, err := git.GitDir(parent.Dir()).RevParse(ctx, "HEAD")
assert.NoError(t, err)
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
rm, err := NewNoCheckoutDEPSRepoManager(ctx, cfg, wd, g, recipesCfg, "fake.server.com", "", urlmock.Client(), gerritCR(t, g), false)
@@ -118,7 +118,7 @@
parentMaster, err := git.GitDir(parentRepo.Dir()).RevParse(ctx, "HEAD")
assert.NoError(t, err)
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
nextRollRev := childCommits[len(childCommits)-1]
assert.NoError(t, rm.Update(ctx))
@@ -139,7 +139,7 @@
rev, err := rm.GetRevision(ctx, c)
assert.NoError(t, err)
assert.Equal(t, c, rev.Id)
- mockChild.MockLog(ctx, c, childCommits[0])
+ mockChild.MockLog(ctx, git.LogFromTo(c, childCommits[0]))
rp, err := rm.RolledPast(ctx, rev)
assert.NoError(t, err)
assert.False(t, rp)
@@ -155,7 +155,7 @@
parentMaster, err := git.GitDir(parentRepo.Dir()).RevParse(ctx, "HEAD")
assert.NoError(t, err)
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
nextRollRev := childCommits[1]
assert.NoError(t, rm.Update(ctx))
@@ -165,7 +165,7 @@
assert.NoError(t, SetStrategy(ctx, rm, strategy.ROLL_STRATEGY_BATCH))
mockParent.MockGetCommit(ctx, "master")
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
assert.NoError(t, rm.Update(ctx))
assert.Equal(t, childCommits[len(childCommits)-1], rm.NextRollRev().Id)
@@ -173,7 +173,7 @@
assert.NoError(t, SetStrategy(ctx, rm, strategy.ROLL_STRATEGY_SINGLE))
mockParent.MockGetCommit(ctx, "master")
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
assert.NoError(t, rm.Update(ctx))
assert.Equal(t, childCommits[1], rm.NextRollRev().Id)
@@ -188,7 +188,7 @@
parentMaster, err := git.GitDir(parentRepo.Dir()).RevParse(ctx, "HEAD")
assert.NoError(t, err)
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
nextRollRev := childCommits[len(childCommits)-1]
assert.NoError(t, rm.Update(ctx))
@@ -201,7 +201,7 @@
// Mock the initial change creation.
logStr := ""
childGitRepo := git.GitDir(childRepo.Dir())
- commitsToRoll, err := childGitRepo.RevList(ctx, fmt.Sprintf("%s..%s", lastRollRev, nextRollRev))
+ commitsToRoll, err := childGitRepo.RevList(ctx, git.LogFromTo(lastRollRev, nextRollRev))
assert.NoError(t, err)
for _, c := range commitsToRoll {
mockChild.MockGetCommit(ctx, c)
@@ -301,7 +301,7 @@
parentMaster, err := git.GitDir(parentRepo.Dir()).RevParse(ctx, "HEAD")
assert.NoError(t, err)
mockParent.MockReadFile(ctx, "DEPS", parentMaster)
- mockChild.MockLog(ctx, childCommits[0], "master")
+ mockChild.MockLog(ctx, git.LogFromTo(childCommits[0], "master"))
mockChild.MockGetCommit(ctx, childCommits[0])
nextRollRev := childCommits[len(childCommits)-1]
assert.NoError(t, rm.Update(ctx))
@@ -317,7 +317,7 @@
// Mock the initial change creation.
logStr := ""
childGitRepo := git.GitDir(childRepo.Dir())
- commitsToRoll, err := childGitRepo.RevList(ctx, fmt.Sprintf("%s..%s", lastRollRev, nextRollRev))
+ commitsToRoll, err := childGitRepo.RevList(ctx, git.LogFromTo(lastRollRev, nextRollRev))
assert.NoError(t, err)
for _, c := range commitsToRoll {
mockChild.MockGetCommit(ctx, c)
diff --git a/autoroll/go/repo_manager/repo_manager.go b/autoroll/go/repo_manager/repo_manager.go
index 478da33..84b494ea0 100644
--- a/autoroll/go/repo_manager/repo_manager.go
+++ b/autoroll/go/repo_manager/repo_manager.go
@@ -311,7 +311,7 @@
if head == lastRollRev.Id {
return []*revision.Revision{}, nil
}
- commits, err := r.childRepo.RevList(ctx, fmt.Sprintf("%s..%s", lastRollRev.Id, head))
+ commits, err := r.childRepo.RevList(ctx, git.LogFromTo(lastRollRev.Id, head))
if err != nil {
return nil, err
}
diff --git a/gitsync/go/gitsync/watcher.go b/gitsync/go/gitsync/watcher.go
index cb8b5ab..51691f5 100644
--- a/gitsync/go/gitsync/watcher.go
+++ b/gitsync/go/gitsync/watcher.go
@@ -126,7 +126,7 @@
if anc {
// Only get the commits between the old and new head.
- revListStr = fmt.Sprintf("%s..%s", foundBranch.Head, newBranch.Head)
+ revListStr = git.LogFromTo(foundBranch.Head, newBranch.Head)
}
}
diff --git a/go/git/gitinfo/gitinfo.go b/go/git/gitinfo/gitinfo.go
index f1390b2..1b90967 100644
--- a/go/git/gitinfo/gitinfo.go
+++ b/go/git/gitinfo/gitinfo.go
@@ -15,6 +15,7 @@
"go.skia.org/infra/go/depot_tools"
"go.skia.org/infra/go/exec"
+ "go.skia.org/infra/go/git"
"go.skia.org/infra/go/sklog"
"go.skia.org/infra/go/tiling"
"go.skia.org/infra/go/util"
@@ -312,7 +313,7 @@
func (g *GitInfo) IndexOf(ctx context.Context, hash string) (int, error) {
// Count the lines from running:
// git rev-list --count <first-commit>..hash.
- output, err := g.RevList(ctx, "--count", fmt.Sprintf("%s..%s", g.firstCommit, hash))
+ output, err := g.RevList(ctx, "--count", git.LogFromTo(g.firstCommit, hash))
if err != nil {
return 0, fmt.Errorf("git rev-list failed: %s", err)
}
diff --git a/go/git/repograph/shared_tests/shared_tests.go b/go/git/repograph/shared_tests/shared_tests.go
index 2ecc52c..dd150f0 100644
--- a/go/git/repograph/shared_tests/shared_tests.go
+++ b/go/git/repograph/shared_tests/shared_tests.go
@@ -385,7 +385,7 @@
if from == "" {
cmd = append(cmd, to)
} else {
- cmd = append(cmd, "--ancestry-path", fmt.Sprintf("%s..%s", from, to))
+ cmd = append(cmd, "--ancestry-path", git.LogFromTo(from, to))
}
hashes, err := gitdir.RevList(ctx, cmd...)
assert.NoError(t, err)
@@ -702,7 +702,7 @@
check := func(from, to string, expectOrig []string) {
expect := util.CopyStringSlice(expectOrig)
- revs, err := co.RevList(ctx, fmt.Sprintf("%s..%s", from, to))
+ revs, err := co.RevList(ctx, git.LogFromTo(from, to))
assert.NoError(t, err)
// Sanity check; assert that the commits returned from git are
// in reverse topological order.
diff --git a/go/git/util.go b/go/git/util.go
index aa1f3c1..c17178d 100644
--- a/go/git/util.go
+++ b/go/git/util.go
@@ -1,10 +1,24 @@
package git
import (
+ "fmt"
"net/url"
"strings"
)
+// LogFromTo returns a string which is used to log from one commit to another.
+// It is important to note that:
+// - The results will include the second commit but not the first.
+// - The results include all commits reachable from the first commit which are
+// not reachable from the second, ie. if there is a merge in the given
+// range, the results will include that line of history and not just the
+// commits which are descendants of the first commit. If you want only commits
+// which are ancestors of the second commit AND descendants of the first, you
+// should use LogLinear.
+func LogFromTo(from, to string) string {
+ return fmt.Sprintf("%s..%s", from, to)
+}
+
// NormalizeURL strips everything from the URL except for the host and the path.
// A trailing ".git" is also stripped. The purpose is to allow for small
// variations in repo URL to be recognized as the same repo. The URL needs to
diff --git a/go/gitiles/gitiles.go b/go/gitiles/gitiles.go
index 7646a49..88fd638 100644
--- a/go/gitiles/gitiles.go
+++ b/go/gitiles/gitiles.go
@@ -206,14 +206,38 @@
return commitToLongCommit(&c)
}
+// LogOption represents an optional parameter to a Log function.
+type LogOption string
+
+// LogReverse is a LogOption which indicates that the commits in the Log should
+// be returned in reverse order from the typical "git log" ordering, ie. each
+// commit's parents appear before the commit itself.
+func LogReverse() LogOption {
+ return LogOption("reverse=true")
+}
+
+// LogBatchSize is a LogOption which indicates the number of commits which
+// should be included in each batch of commits returned by Log.
+func LogBatchSize(n int) LogOption {
+ return LogOption(fmt.Sprintf("n=%d", n))
+}
+
// logHelper is used to perform requests which are equivalent to "git log".
// Loads commits in batches and calls the given function for each batch of
// commits. If the function returns an error, iteration stops, and the error is
// returned, unless it was ErrStopIteration.
-func (r *Repo) logHelper(ctx context.Context, urlTmpl, commit string, fn func(context.Context, []*vcsinfo.LongCommit) error) error {
+func (r *Repo) logHelper(ctx context.Context, url string, fn func(context.Context, []*vcsinfo.LongCommit) error, opts ...LogOption) error {
+ for _, opt := range opts {
+ url += "&" + string(opt)
+ }
+ start := ""
for {
var l Log
- if err := r.getJson(ctx, fmt.Sprintf(urlTmpl, commit), &l); err != nil {
+ u := url
+ if start != "" {
+ u += "&s=" + start
+ }
+ if err := r.getJson(ctx, u, &l); err != nil {
return err
}
// Convert to vcsinfo.LongCommit.
@@ -233,20 +257,19 @@
if l.Next == "" {
return nil
} else {
- commit = l.Next
+ start = l.Next
}
}
}
-// Log returns Gitiles' equivalent to "git log" for the given start and end
-// commits.
-func (r *Repo) Log(ctx context.Context, from, to string) ([]*vcsinfo.LongCommit, error) {
+// Log returns Gitiles' equivalent to "git log" for the given expression.
+func (r *Repo) Log(ctx context.Context, logExpr string, opts ...LogOption) ([]*vcsinfo.LongCommit, error) {
rv := []*vcsinfo.LongCommit{}
- tmpl := fmt.Sprintf(LOG_URL, r.URL, from+"..%s")
- if err := r.logHelper(ctx, tmpl, to, func(ctx context.Context, commits []*vcsinfo.LongCommit) error {
+ url := fmt.Sprintf(LOG_URL, r.URL, logExpr)
+ if err := r.logHelper(ctx, url, func(ctx context.Context, commits []*vcsinfo.LongCommit) error {
rv = append(rv, commits...)
return nil
- }); err != nil {
+ }, opts...); err != nil {
return nil, err
}
return rv, nil
@@ -256,9 +279,9 @@
// ie. it only returns commits which are on the direct path from A to B, and
// only on the "main" branch. This is as opposed to "git log from..to" which
// returns all commits which are ancestors of 'to' but not 'from'.
-func (r *Repo) LogLinear(ctx context.Context, from, to string) ([]*vcsinfo.LongCommit, error) {
+func (r *Repo) LogLinear(ctx context.Context, from, to string, opts ...LogOption) ([]*vcsinfo.LongCommit, error) {
// Retrieve the normal "git log".
- commits, err := r.Log(ctx, from, to)
+ commits, err := r.Log(ctx, git.LogFromTo(from, to), opts...)
if err != nil {
return nil, err
}
@@ -314,31 +337,37 @@
return rv, nil
}
-// LogFn runs the given function for each commit in the log history reachable
-// from the given commit hash or ref name. It stops when ErrStopIteration is
-// returned.
-func (r *Repo) LogFn(ctx context.Context, to string, fn func(context.Context, *vcsinfo.LongCommit) error) error {
- return r.LogFnBatch(ctx, to, func(ctx context.Context, commits []*vcsinfo.LongCommit) error {
+// LogFn runs the given function for each commit in the log for the given
+// expression. It stops when ErrStopIteration is returned.
+func (r *Repo) LogFn(ctx context.Context, logExpr string, fn func(context.Context, *vcsinfo.LongCommit) error, opts ...LogOption) error {
+ return r.LogFnBatch(ctx, logExpr, func(ctx context.Context, commits []*vcsinfo.LongCommit) error {
for _, c := range commits {
if err := fn(ctx, c); err != nil {
return err
}
}
return nil
- })
+ }, opts...)
}
// LogFnBatch is the same as LogFn but it runs the given function over batches
// of commits.
-func (r *Repo) LogFnBatch(ctx context.Context, to string, fn func(context.Context, []*vcsinfo.LongCommit) error) error {
- return r.logHelper(ctx, fmt.Sprintf(LOG_URL, r.URL, "%s"), to, fn)
+func (r *Repo) LogFnBatch(ctx context.Context, logExpr string, fn func(context.Context, []*vcsinfo.LongCommit) error, opts ...LogOption) error {
+ url := fmt.Sprintf(LOG_URL, r.URL, logExpr)
+ return r.logHelper(ctx, url, fn, opts...)
}
+// Ref represents a single ref, as returned by the API.
+type Ref struct {
+ Value string `json:"value"`
+}
+
+// RefsMap is the result of a request to REFS_URL.
+type RefsMap map[string]Ref
+
// Branches returns the list of branches in the repo.
func (r *Repo) Branches(ctx context.Context) ([]*git.Branch, error) {
- branchMap := map[string]struct {
- Value string `json:"value"`
- }{}
+ branchMap := RefsMap{}
if err := r.getJson(ctx, fmt.Sprintf(REFS_URL, r.URL), &branchMap); err != nil {
return nil, err
}
diff --git a/go/gitiles/gitiles_test.go b/go/gitiles/gitiles_test.go
index 51a6b5d..bdce5ac 100644
--- a/go/gitiles/gitiles_test.go
+++ b/go/gitiles/gitiles_test.go
@@ -110,7 +110,7 @@
}
js := testutils.MarshalJSON(t, results)
js = ")]}'\n" + js
- urlMock.MockOnce(fmt.Sprintf(LOG_URL, gb.RepoUrl(), fmt.Sprintf("%s..%s", from, to)), mockhttpclient.MockGetDialogue([]byte(js)))
+ urlMock.MockOnce(fmt.Sprintf(LOG_URL, gb.RepoUrl(), git.LogFromTo(from, to)), mockhttpclient.MockGetDialogue([]byte(js)))
}
// Return a slice of the hashes for the given commits.
@@ -123,9 +123,9 @@
}
// Verify that we got the correct list of commits from the call to Log.
- checkGitiles := func(fn func(context.Context, string, string) ([]*vcsinfo.LongCommit, error), from, to string, expect []string) {
+ checkGitiles := func(fn func(context.Context, string, ...LogOption) ([]*vcsinfo.LongCommit, error), from, to string, expect []string) {
mockLog(from, to, expect)
- log, err := fn(ctx, from, to)
+ log, err := fn(ctx, git.LogFromTo(from, to))
assert.NoError(t, err)
deepequal.AssertDeepEqual(t, hashes(log), expect)
assert.True(t, urlMock.Empty())
@@ -137,7 +137,7 @@
checkGit := func(from, to string, expect []string, args ...string) {
cmd := []string{"rev-list", "--date-order"}
cmd = append(cmd, args...)
- cmd = append(cmd, fmt.Sprintf("%s..%s", from, to))
+ cmd = append(cmd, string(git.LogFromTo(from, to)))
output, err := repo.Git(ctx, cmd...)
assert.NoError(t, err)
log := strings.Split(strings.TrimSpace(output), "\n")
@@ -161,7 +161,11 @@
// ("git log --date-order --first-parent --ancestry-path).
checkLinear := func(from, to string, expect []string) {
checkGit(from, to, expect, "--first-parent", "--ancestry-path")
- checkGitiles(r.LogLinear, from, to, expect)
+ mockLog(from, to, expect)
+ log, err := r.LogLinear(ctx, from, to)
+ assert.NoError(t, err)
+ deepequal.AssertDeepEqual(t, hashes(log), expect)
+ assert.True(t, urlMock.Empty())
}
// Test cases.
@@ -213,7 +217,7 @@
last = rv
return rv
}
- mock := func(from, to *vcsinfo.LongCommit, commits []*vcsinfo.LongCommit, next string) {
+ mock := func(from, to *vcsinfo.LongCommit, commits []*vcsinfo.LongCommit, start, next string) {
// Create the mock results.
results := &Log{
Log: make([]*Commit, 0, len(commits)),
@@ -239,8 +243,14 @@
}
js := testutils.MarshalJSON(t, results)
js = ")]}'\n" + js
- urlMock.MockOnce(fmt.Sprintf(LOG_URL, repoUrl, fmt.Sprintf("%s..%s", from.Hash, to.Hash)), mockhttpclient.MockGetDialogue([]byte(js)))
- urlMock.MockOnce(fmt.Sprintf(LOG_URL, repoUrl, to.Hash), mockhttpclient.MockGetDialogue([]byte(js)))
+ url1 := fmt.Sprintf(LOG_URL, repoUrl, git.LogFromTo(from.Hash, to.Hash))
+ url2 := fmt.Sprintf(LOG_URL, repoUrl, to.Hash)
+ if start != "" {
+ url1 += "&s=" + start
+ url2 += "&s=" + start
+ }
+ urlMock.MockOnce(url1, mockhttpclient.MockGetDialogue([]byte(js)))
+ urlMock.MockOnce(url2, mockhttpclient.MockGetDialogue([]byte(js)))
}
check := func(from, to *vcsinfo.LongCommit, expectCommits []*vcsinfo.LongCommit) {
// The expectations are in chronological order for convenience
@@ -251,7 +261,7 @@
sort.Sort(vcsinfo.LongCommitSlice(expect))
// Test standard Log(from, to) function.
- log, err := repo.Log(ctx, from.Hash, to.Hash)
+ log, err := repo.Log(ctx, git.LogFromTo(from.Hash, to.Hash))
assert.NoError(t, err)
deepequal.AssertDeepEqual(t, expect, log)
@@ -275,20 +285,20 @@
}
// Most basic test case; no pagination.
- mock(commits[0], commits[5], commits[1:5], "")
+ mock(commits[0], commits[5], commits[1:5], "", "")
check(commits[0], commits[5], commits[1:5])
// Two pages.
split := 5
- mock(commits[0], commits[len(commits)-1], commits[split:], commits[split].Hash)
- mock(commits[0], commits[split], commits[1:split], "")
+ mock(commits[0], commits[len(commits)-1], commits[split:], "", commits[split].Hash)
+ mock(commits[0], commits[len(commits)-1], commits[1:split], commits[split].Hash, "")
check(commits[0], commits[len(commits)-1], commits[1:])
// Three pages.
split1 := 7
split2 := 3
- mock(commits[0], commits[len(commits)-1], commits[split1:], commits[split1].Hash)
- mock(commits[0], commits[split1], commits[split2:split1], commits[split2].Hash)
- mock(commits[0], commits[split2], commits[1:split2], "")
+ mock(commits[0], commits[len(commits)-1], commits[split1:], "", commits[split1].Hash)
+ mock(commits[0], commits[len(commits)-1], commits[split2:split1], commits[split1].Hash, commits[split2].Hash)
+ mock(commits[0], commits[len(commits)-1], commits[1:split2], commits[split2].Hash, "")
check(commits[0], commits[len(commits)-1], commits[1:])
}
diff --git a/go/gitiles/testutils/testutils.go b/go/gitiles/testutils/testutils.go
index 947e1d1..6e5cdd9 100644
--- a/go/gitiles/testutils/testutils.go
+++ b/go/gitiles/testutils/testutils.go
@@ -34,6 +34,10 @@
}
}
+func (mr *MockRepo) Empty() bool {
+ return mr.c.Empty()
+}
+
func (mr *MockRepo) MockReadFile(ctx context.Context, srcPath, ref string) {
contents, err := mr.repo.GetFile(ctx, srcPath, ref)
assert.NoError(mr.t, err)
@@ -79,18 +83,37 @@
mr.c.MockOnce(url, mockhttpclient.MockGetDialogue(b))
}
-func (mr *MockRepo) MockLog(ctx context.Context, from, to string) {
- revlist, err := mr.repo.RevList(ctx, fmt.Sprintf("%s..%s", from, to))
+func (mr *MockRepo) MockBranches(ctx context.Context) {
+ branches, err := mr.repo.Branches(ctx)
+ assert.NoError(mr.t, err)
+ res := make(gitiles.RefsMap, len(branches))
+ for _, branch := range branches {
+ res[branch.Name] = gitiles.Ref{
+ Value: branch.Head,
+ }
+ }
+ b, err := json.Marshal(res)
+ assert.NoError(mr.t, err)
+ b = append([]byte(")]}'\n"), b...)
+ url := fmt.Sprintf(gitiles.REFS_URL, mr.url)
+ mr.c.MockOnce(url, mockhttpclient.MockGetDialogue(b))
+}
+
+func (mr *MockRepo) MockLog(ctx context.Context, logExpr string, opts ...gitiles.LogOption) {
+ revlist, err := mr.repo.RevList(ctx, logExpr)
assert.NoError(mr.t, err)
log := &gitiles.Log{
- Log: []*gitiles.Commit{},
+ Log: make([]*gitiles.Commit, len(revlist)),
}
- for _, hash := range revlist {
- log.Log = append(log.Log, mr.getCommit(ctx, hash))
+ for idx, hash := range revlist {
+ log.Log[idx] = mr.getCommit(ctx, hash)
}
b, err := json.Marshal(log)
assert.NoError(mr.t, err)
b = append([]byte(")]}'\n"), b...)
- url := fmt.Sprintf(gitiles.LOG_URL, mr.url, fmt.Sprintf("%s..%s", from, to))
+ url := fmt.Sprintf(gitiles.LOG_URL, mr.url, logExpr)
+ for _, opt := range opts {
+ url += "&" + string(opt)
+ }
mr.c.MockOnce(url, mockhttpclient.MockGetDialogue(b))
}