blob: cb45647eec500709cf757ae8180f23e63e14d88e [file] [log] [blame]
package main
import (
"context"
"flag"
"fmt"
"go.skia.org/infra/go/common"
"go.skia.org/infra/go/git"
"go.skia.org/infra/go/gitstore"
"go.skia.org/infra/go/gitstore/bt_gitstore"
"go.skia.org/infra/go/sklog"
"go.skia.org/infra/go/timer"
)
// btgit is a script that queries a BigTable based GitStore.
func main() {
// Define the flags and parse them.
var (
btInstanceID = flag.String("bt_instance", "production", "Big Table instance")
btTableID = flag.String("bt_table", "git-repos", "BigTable table ID")
listBranches = flag.Bool("list", false, "List all branches and quit")
listRepos = flag.Bool("list_repos", false, "List all repositories quit")
loadGraph = flag.Bool("load_graph", false, "Load the entire commit graph. For performance check only.")
projectID = flag.String("project", "skia-public", "ID of the GCP project")
branch = flag.String("branch", "", "Name of the branch to list. Empty means all commits across all branches.")
limit = flag.Int("limit", 100, "Number of commits to show. 0 means no limit")
repoURL = flag.String("repo_url", "", "URL of the git repo.")
verbose = flag.Bool("verbose", false, "Indicate whether to log the commits we find.")
)
common.Init()
// Configure the bigtable instance.
config := &bt_gitstore.BTConfig{
ProjectID: *projectID,
InstanceID: *btInstanceID,
TableID: *btTableID,
}
// Normalize the URL as GitStore does.
normURL, err := git.NormalizeURL(*repoURL)
if err != nil {
sklog.Fatalf("Error getting normalized URL for %s: %s", *repoURL, err)
}
ctx := context.Background()
// Get all repos and find the one we want plus the branch we want.
allRepoInfos, err := bt_gitstore.AllRepos(ctx, config)
if err != nil {
sklog.Fatalf("Error retrieving lists of repositories: %s", err)
}
sklog.Infof("Got all repo info: %d", len(allRepoInfos))
if *listRepos {
for _, repo := range allRepoInfos {
fmt.Printf("Repo: %s \n", repo.RepoURL)
if *verbose {
logBranches(" ", repo.Branches)
}
}
return
}
// Make sure our repoURL exists.
repoInfo, ok := allRepoInfos[normURL]
if !ok {
sklog.Fatalf("Repo %s could not found in BigTable", normURL)
}
sklog.Infof("Found repo for %s", repoInfo.RepoURL)
if *listBranches {
logBranches("", repoInfo.Branches)
return
}
// Make sure the target branch exists
foundBranch, ok := repoInfo.Branches[*branch]
if !ok {
sklog.Fatalf("Error, branch %q does not exist in BigTable git", *branch)
}
sklog.Infof("Found branch %q in repo for %s", *branch, repoInfo.RepoURL)
// Create a new BT based GitStore.
gitStore, err := bt_gitstore.New(ctx, config, *repoURL)
if err != nil {
sklog.Fatalf("Error instantiating git store: %s", err)
}
sklog.Infof("Opened gitstore")
// Determine how many commits we fetch.
startIndex := 0
branchLength := foundBranch.Index + 1
if *limit > 0 {
startIndex = branchLength - *limit
}
// Fetch the graph of the repository to see if it performs well enough.
if *loadGraph {
ggt := timer.New("Getting graph")
commitGraph, err := gitStore.GetGraph(ctx)
if err != nil {
sklog.Fatalf("Error retrieving graph: %s", err)
}
ggt.Stop()
sklog.Infof("Loaded graph with %d nodes", len(commitGraph.Nodes))
}
// Retrieve the index commits we are interested in.
indexCommits, err := gitStore.RangeN(ctx, startIndex, branchLength, *branch)
if err != nil {
sklog.Fatalf("Error retrieving branch %q: %s", *branch, err)
}
// Isolate the hashes and retrieve the LongCommits.
hashes := make([]string, 0, len(indexCommits))
for _, commit := range indexCommits {
hashes = append(hashes, commit.Hash)
}
tlc := timer.New("Long commits")
longCommits, err := gitStore.Get(ctx, hashes)
if err != nil {
sklog.Fatalf("Error retrieving long commits: %s", err)
}
tlc.Stop()
sklog.Infof("Long commits loaded: %d", len(longCommits))
for idx := len(longCommits) - 1; idx >= 0; idx-- {
c := longCommits[idx]
if c == nil {
sklog.Fatalf("Programming error: Unable to retrieve long commit for hash %s", hashes[idx])
}
if *verbose {
fmt.Printf("%s %40s %v %s\n", c.Hash, c.Author, c.Timestamp, c.Subject)
}
}
}
func logBranches(indent string, branches map[string]*gitstore.BranchPointer) {
for branchName, branch := range branches {
fmt.Printf("Branch %s @ %s with index %d\n", branchName, branch.Head, branch.Index)
}
}