maintner: account for CLs changing branches
Fixes golang/go#23007
Change-Id: I1e791d1a96033e77edf077909c2a20afaea511c3
Reviewed-on: https://go-review.googlesource.com/83635
Reviewed-by: Andrew Bonventre <andybons@golang.org>
diff --git a/maintner/gerrit.go b/maintner/gerrit.go
index abb4745..f0f151a 100644
--- a/maintner/gerrit.go
+++ b/maintner/gerrit.go
@@ -262,6 +262,11 @@
// Previous versions are available via GerritProject.remote.
Commit *GitCommit
+ // branch is a cache of the latest "Branch: " value seen from
+ // MetaCommits' commit message values, stripped of any
+ // "refs/heads/" prefix. It's usually "master".
+ branch string
+
// Meta is the head of the most recent Gerrit "meta" commit
// for this CL. This is guaranteed to be a linear history
// back to a CL-specific root commit for this meta branch.
@@ -332,9 +337,17 @@
}
// Branch returns the CL's branch, with any "refs/heads/" prefix removed.
-func (cl *GerritCL) Branch() string {
- branch, _ := lineValue(cl.firstMetaCommit().Msg, "Branch:")
- return branch
+func (cl *GerritCL) Branch() string { return cl.branch }
+
+func (cl *GerritCL) updateBranch() {
+ for i := len(cl.MetaCommits) - 1; i >= 0; i-- {
+ mc := cl.MetaCommits[i]
+ branch, _ := lineValue(mc.Msg, "Branch:")
+ if branch != "" {
+ cl.branch = strings.TrimPrefix(branch, "refs/heads/")
+ return
+ }
+ }
}
// lineValue extracts a value from an RFC 822-style "key: value" series of lines.
@@ -803,6 +816,7 @@
for i := len(backwardMeta) - 1; i >= 0; i-- {
cl.MetaCommits = append(cl.MetaCommits, backwardMeta[i])
}
+ cl.updateBranch()
}
// clSliceContains reports whether cls contains cl.
diff --git a/maintner/godata/godata_test.go b/maintner/godata/godata_test.go
index 3e1b6c4..128e03d 100644
--- a/maintner/godata/godata_test.go
+++ b/maintner/godata/godata_test.go
@@ -154,3 +154,31 @@
}
}
}
+
+// Issue 23007: a Gerrit CL can switch branches. Make sure we handle that.
+func TestGerritCLChangingBranches(t *testing.T) {
+ c := getGoData(t)
+
+ tests := []struct {
+ server, project string
+ cl int32
+ want string
+ }{
+ // Changed branch in the middle:
+ // (Unsubmitted at the time of this test, so if it changes back, this test
+ // may break.)
+ {"go.googlesource.com", "go", 33776, "master"},
+
+ // Submitted to boringcrypto:
+ {"go.googlesource.com", "go", 82138, "dev.boringcrypto"},
+ // Submitted to master:
+ {"go.googlesource.com", "go", 83578, "master"},
+ }
+
+ for _, tt := range tests {
+ cl := c.Gerrit().Project(tt.server, tt.project).CL(tt.cl)
+ if got := cl.Branch(); got != tt.want {
+ t.Errorf("%q, %q, CL %d = branch %q; want %q", tt.server, tt.project, tt.cl, got, tt.want)
+ }
+ }
+}