Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Unified Diff: common/api/gitiles/gitiles.go

Issue 2981263002: gitiles: add Refs API. (Closed)
Patch Set: review Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | common/api/gitiles/gitiles_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: common/api/gitiles/gitiles.go
diff --git a/common/api/gitiles/gitiles.go b/common/api/gitiles/gitiles.go
index 9d9ec0b7711bc6af489cc7509bdd22f30e4492e8..ac6dfd9296bb15e18cbacaed22a0b3820370c24a 100644
--- a/common/api/gitiles/gitiles.go
+++ b/common/api/gitiles/gitiles.go
@@ -160,8 +160,72 @@ func (c *Client) Log(ctx context.Context, repoURL, treeish string, limit int) ([
}
}
+// Refs returns a map resolving each ref in a repo to git revision.
+//
+// refsPath limits which refs to resolve to only those matching {refsPath}/*.
+// refsPath should start with "refs" and should not include glob '*'.
+// Typically, "refs/heads" should be used.
+//
+// To fetch **all** refs in a repo, specify just "refs" but beware of two
+// caveats:
+// * refs returned include a ref for each patchset for each Gerrit change
+// associated with the repo
+// * returned map will contain special "HEAD" ref whose value in resulting map
+// will be name of the actual ref to which "HEAD" points, which is typically
+// "refs/heads/master".
+//
+// Thus, if you are looking for all tags and all branches of repo, it's
+// recommended to issue two Refs calls limited to "refs/tags" and "refs/heads"
+// instead of one call for "refs".
+//
+// Since Gerrit allows per-ref ACLs, it is possible that some refs matching
+// refPrefix would not be present in results because current user isn't granted
+// read permission on them.
+func (c *Client) Refs(ctx context.Context, repoURL, refsPath string) (map[string]string, error) {
+ repoURL, err := NormalizeRepoURL(repoURL)
+ if err != nil {
+ return nil, err
+ }
+ if refsPath != "refs" && !strings.HasPrefix(refsPath, "refs/") {
+ return nil, fmt.Errorf("refsPath must start with \"refs\": %q", refsPath)
+ }
+ refsPath = strings.TrimRight(refsPath, "/")
+
+ subPath := fmt.Sprintf("+%s?format=json", url.PathEscape(refsPath))
+ resp := refsResponse{}
+ if err := c.get(ctx, repoURL, subPath, &resp); err != nil {
+ return nil, err
+ }
+ r := make(map[string]string, len(resp))
+ for ref, v := range resp {
+ switch {
+ case v.Value == "":
+ // Weird case of what looks like hash with a target in at least Chromium
+ // repo.
+ continue
+ case ref == "HEAD":
+ r["HEAD"] = v.Target
+ case refsPath != "refs":
+ // Gitiles omits refsPath from each ref if refsPath != "refs". Undo this
+ // inconsistency.
+ r[refsPath+"/"+ref] = v.Value
+ default:
+ r[ref] = v.Value
+ }
+ }
+ return r, nil
+}
+
////////////////////////////////////////////////////////////////////////////////
+type refsResponseRefInfo struct {
+ Value string `json:"value"`
+ Target string `json:"target"`
+}
+
+// refsResponse is the JSON response from querying gitiles for a Refs request.
+type refsResponse map[string]refsResponseRefInfo
+
// logResponse is the JSON response from querying gitiles for a log request.
type logResponse struct {
Log []Commit `json:"log"`
« no previous file with comments | « no previous file | common/api/gitiles/gitiles_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698