maintner: record all gerrit refs, not just change refs
Change-Id: I820b970f1e2ebdb365feb90b1e06650862cfcf66
Reviewed-on: https://go-review.googlesource.com/43616
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/maintner/gerrit.go b/maintner/gerrit.go
index 493fb7e..007c819 100644
--- a/maintner/gerrit.go
+++ b/maintner/gerrit.go
@@ -68,6 +68,7 @@
proj: gerritProj,
cls: map[int32]*GerritCL{},
remote: map[gerritCLVersion]GitHash{},
+ ref: map[string]GitHash{},
}
g.projects[gerritProj] = proj
return proj
@@ -91,6 +92,13 @@
cls map[int32]*GerritCL
remote map[gerritCLVersion]GitHash
need map[GitHash]bool
+
+ // ref are the non-change refs with keys like "HEAD",
+ // "refs/heads/master", "refs/tags/v0.8.0", etc.
+ //
+ // Notably, this excludes the "refs/changes/*" refs matched by
+ // rxChangeRef. Those are in the remote map.
+ ref map[string]GitHash
}
func (gp *GerritProject) gitDir() string {
@@ -356,16 +364,23 @@
c := gp.gerrit.c
for _, refp := range gm.Refs {
+ hash := c.gitHashFromHexStr(refp.Sha1)
m := rxChangeRef.FindStringSubmatch(refp.Ref)
if m == nil {
+ // Misc ref, not a change ref.
+ if _, ok := c.gitCommit[hash]; !ok {
+ gp.logf("ERROR: non-change ref %v references unknown hash %v; ignoring", refp, hash)
+ continue
+ }
+ gp.ref[refp.Ref] = hash
continue
}
+
clNum64, err := strconv.ParseInt(m[1], 10, 32)
version, ok := gerritVersionNumber(m[2])
if !ok || err != nil {
continue
}
- hash := c.gitHashFromHexStr(refp.Sha1)
gc, ok := c.gitCommit[hash]
if !ok {
gp.logf("ERROR: ref %v references unknown hash %v; ignoring", refp, hash)
@@ -535,24 +550,38 @@
// already been slurped into memory.
c.mu.Lock()
for bs.Scan() {
- m := rxRemoteRef.FindSubmatch(bs.Bytes())
- if m == nil {
+ line := bs.Bytes()
+ tab := bytes.IndexByte(line, '\t')
+ if tab == -1 {
+ if !strings.HasPrefix(bs.Text(), "From ") {
+ gp.logf("bogus ls-remote line: %q", line)
+ }
continue
}
- clNum, err := strconv.ParseInt(string(m[2]), 10, 32)
- version, ok := gerritVersionNumber(string(m[3]))
- if err != nil || !ok {
- continue
+ sha1 := string(line[:tab])
+ refName := strings.TrimSpace(string(line[tab+1:]))
+ hash := c.gitHashFromHexStr(sha1)
+
+ var needFetch bool
+
+ m := rxRemoteRef.FindSubmatch(line)
+ if m != nil {
+ clNum, err := strconv.ParseInt(string(m[2]), 10, 32)
+ version, ok := gerritVersionNumber(string(m[3]))
+ if err != nil || !ok {
+ continue
+ }
+ curHash := gp.remote[gerritCLVersion{int32(clNum), version}]
+ needFetch = curHash != hash
+ } else if trackGerritRef(refName) && gp.ref[refName] != hash {
+ needFetch = true
+ gp.logf("gerrit ref %q = %q", refName, sha1)
}
- sha1 := m[1]
- hash := c.gitHashFromHex(sha1)
- curHash := gp.remote[gerritCLVersion{int32(clNum), version}]
-
- if curHash != hash {
+ if needFetch {
toFetch = append(toFetch, hash)
changedRefs = append(changedRefs, &maintpb.GitRef{
- Ref: strings.TrimSpace(bs.Text()[len(sha1):]),
+ Ref: refName,
Sha1: string(sha1),
})
}
@@ -709,3 +738,15 @@
return nil
}
+
+// trackGerritRef reports whether we care to record changes about the
+// given ref.
+func trackGerritRef(ref string) bool {
+ if strings.HasPrefix(ref, "refs/users/") {
+ return false
+ }
+ if strings.HasPrefix(ref, "refs/cache-automerge/") {
+ return false
+ }
+ return true
+}