Merge "SubmoduleOp: Allow all branches to be subscribed"
diff --git a/Documentation/user-submodules.txt b/Documentation/user-submodules.txt
index bccb074..7b5f0a6 100644
--- a/Documentation/user-submodules.txt
+++ b/Documentation/user-submodules.txt
@@ -86,7 +86,7 @@
and add the following lines:
----
[allowSuperproject "<superproject>"]
- refs = <refspec>
+ matching = <refspec>
----
where the 'superproject' should be the exact project name of the superproject.
The refspec defines which branches of the submodule are allowed to be
@@ -104,7 +104,7 @@
a configuration in the "All-Projects" project like:
----
[allowSuperproject "my-only-superproject"]
- refs = refs/heads/*:refs/heads/*
+ matching = refs/heads/*:refs/heads/*
----
and then you don't have to worry about configuring the individual projects
any more. Child projects cannot negate the parent's configuration.
@@ -147,14 +147,17 @@
[[acl_refspec]]
=== The RefSpec in the allowSuperproject section
-The RefSpec for defining the branch level access for subscriptions look similar
-to Git style RefSpecs used for pushing in Git. Regular expressions
-as found in the ACL configuration are not supported. The most restrictive
-RefSpec is allowing one specific branch of the submodule to be subscribed
-to one specific branch of the superproject via:
+There are two options for specifying which branches can be subscribed
+to. The most common is to set `allowSuperproject.<superproject>.matching`
+to a Git-style refspec, which has the same syntax as the refspecs used
+for pushing in Git. Regular expressions as found in the ACL configuration
+are not supported.
+
+The most restrictive refspec is allowing one specific branch of the
+submodule to be subscribed to one specific branch of the superproject:
----
[allowSuperproject "<superproject>"]
- refs = refs/heads/<submodule-branch>:refs/heads/<superproject-branch>
+ matching = refs/heads/<submodule-branch>:refs/heads/<superproject-branch>
----
If you want to allow for a 1:1 mapping, i.e. 'master' maps to 'master',
@@ -162,14 +165,24 @@
'stable':
----
[allowSuperproject "<superproject>"]
- refs = refs/heads/*:refs/heads/*
+ matching = refs/heads/*:refs/heads/*
----
-If you want to enable a branch to be subscribed to any other branch of
-the superproject, omit the second part of the RefSpec:
+To allow all refs matching one pattern to subscribe to all refs
+matching another pattern, set `allowSuperproject.<superproject>.all`
+to the patterns concatenated with a colon. For example, to make a
+single branch available for subscription from all branches of the
+superproject:
----
[allowSuperproject "<superproject>"]
- refs = refs/heads/<submodule-branch>
+ all = refs/heads/<submodule-branch>:refs/heads/*
+----
+
+To make all branches available for subscription from all branches of
+the superproject:
+----
+ [allowSuperproject "<superproject>"]
+ all = refs/heads/*:refs/heads/*
----
=== Subscription Limitations
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java
index 2ca4691..28f7ff8 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java
@@ -130,18 +130,25 @@
return pushChangeTo(repo, "refs/heads/" + branch, "some change", "");
}
- protected void allowSubmoduleSubscription(String submodule, String subBranch,
- String superproject, String superBranch) throws Exception {
+ protected void allowSubmoduleSubscription(String submodule,
+ String subBranch, String superproject, String superBranch, boolean match)
+ throws Exception {
Project.NameKey sub = new Project.NameKey(name(submodule));
Project.NameKey superName = new Project.NameKey(name(superproject));
try (MetaDataUpdate md = metaDataUpdateFactory.create(sub)) {
md.setMessage("Added superproject subscription");
ProjectConfig pc = ProjectConfig.read(md);
SubscribeSection s = new SubscribeSection(superName);
+ String refspec;
if (superBranch == null) {
- s.addRefSpec(subBranch);
+ refspec = subBranch;
} else {
- s.addRefSpec(subBranch + ":" + superBranch);
+ refspec = subBranch + ":" + superBranch;
+ }
+ if (match) {
+ s.addMatchingRefSpec(refspec);
+ } else {
+ s.addMultiMatchRefSpec(refspec);
}
pc.addSubscribeSection(s);
ObjectId oldId = pc.getRevision();
@@ -151,6 +158,13 @@
}
}
+ protected void allowMatchingSubmoduleSubscription(String submodule,
+ String subBranch, String superproject, String superBranch)
+ throws Exception {
+ allowSubmoduleSubscription(submodule, subBranch, superproject,
+ superBranch, true);
+ }
+
protected void createSubmoduleSubscription(TestRepository<?> repo, String branch,
String subscribeToRepo, String subscribeToBranch) throws Exception {
Config config = new Config();
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java
index 5326262..6684e85 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java
@@ -44,7 +44,7 @@
public void testSubscriptionWithoutGlobalServerSetting() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master",
@@ -70,7 +70,7 @@
public void testSubscriptionToEmptyRepo() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master",
@@ -87,7 +87,7 @@
public void testSubscriptionToExistingRepo() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
@@ -104,8 +104,8 @@
public void testSubscriptionWildcardACLForSingleBranch() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- // master is allowed to be subscribed to any superprojects branch:
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ // master is allowed to be subscribed to master branch only:
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", null);
// create 'branch':
pushChangeTo(superRepo, "branch");
@@ -120,14 +120,14 @@
expectToHaveSubmoduleState(superRepo, "master",
"subscribed-to-project", subHEAD);
- expectToHaveSubmoduleState(superRepo, "branch",
- "subscribed-to-project", subHEAD);
+ assertThat(hasSubmodule(superRepo, "branch",
+ "subscribed-to-project")).isFalse();
}
@Test
public void testSubscriptionWildcardACLForMissingProject() throws Exception {
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
"not-existing-super-project", "refs/heads/*");
pushChangeTo(subRepo, "master");
}
@@ -136,7 +136,7 @@
public void testSubscriptionWildcardACLForMissingBranch() throws Exception {
createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
"super-project", "refs/heads/*");
pushChangeTo(subRepo, "foo");
}
@@ -145,7 +145,7 @@
public void testSubscriptionWildcardACLForMissingGitmodules() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
"super-project", "refs/heads/*");
pushChangeTo(superRepo, "master");
pushChangeTo(subRepo, "master");
@@ -156,7 +156,7 @@
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
// any branch is allowed to be subscribed to the same superprojects branch:
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
"super-project", "refs/heads/*");
// create 'branch' in both repos:
@@ -189,11 +189,52 @@
}
@Test
+ public void testSubscriptionWildcardACLForManyBranches() throws Exception {
+ TestRepository<?> superRepo = createProjectWithPush("super-project");
+ TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
+
+ // Any branch is allowed to be subscribed to any superproject branch:
+ allowSubmoduleSubscription("subscribed-to-project", "refs/heads/*",
+ "super-project", null, false);
+ pushChangeTo(superRepo, "branch");
+ pushChangeTo(subRepo, "another-branch");
+ createSubmoduleSubscription(superRepo, "branch",
+ "subscribed-to-project", "another-branch");
+ ObjectId subHEAD = pushChangeTo(subRepo, "another-branch");
+ expectToHaveSubmoduleState(superRepo, "branch",
+ "subscribed-to-project", subHEAD);
+ }
+
+ @Test
+ public void testSubscriptionWildcardACLOneToManyBranches() throws Exception {
+ TestRepository<?> superRepo = createProjectWithPush("super-project");
+ TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
+
+ // Any branch is allowed to be subscribed to any superproject branch:
+ allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ "super-project", "refs/heads/*", false);
+ pushChangeTo(superRepo, "branch");
+ createSubmoduleSubscription(superRepo, "branch",
+ "subscribed-to-project", "master");
+ ObjectId subHEAD = pushChangeTo(subRepo, "master");
+ expectToHaveSubmoduleState(superRepo, "branch",
+ "subscribed-to-project", subHEAD);
+
+ createSubmoduleSubscription(superRepo, "branch",
+ "subscribed-to-project", "branch");
+ pushChangeTo(subRepo, "branch");
+
+ // no change expected, as only master is subscribed:
+ expectToHaveSubmoduleState(superRepo, "branch",
+ "subscribed-to-project", subHEAD);
+ }
+
+ @Test
@GerritConfig(name = "submodule.verboseSuperprojectUpdate", value = "false")
public void testSubmoduleShortCommitMessage() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
@@ -220,7 +261,7 @@
public void testSubmoduleSubjectCommitMessage() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
@@ -248,7 +289,7 @@
public void testSubmoduleCommitMessage() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
@@ -276,7 +317,7 @@
public void testSubscriptionUnsubscribe() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
@@ -303,7 +344,7 @@
throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
@@ -329,7 +370,7 @@
public void testSubscriptionToDifferentBranches() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/foo",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/foo",
"super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master",
@@ -345,9 +386,9 @@
public void testBranchCircularSubscription() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
- allowSubmoduleSubscription("super-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("super-project", "refs/heads/master",
"subscribed-to-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
@@ -370,9 +411,9 @@
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
- allowSubmoduleSubscription("super-project", "refs/heads/dev",
+ allowMatchingSubmoduleSubscription("super-project", "refs/heads/dev",
"subscribed-to-project", "refs/heads/dev");
pushChangeTo(subRepo, "master");
@@ -414,7 +455,7 @@
public void testSubscriptionFailOnWrongProjectACL() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"wrong-super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
@@ -429,7 +470,7 @@
public void testSubscriptionFailOnWrongBranchACL() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/wrong-branch");
pushChangeTo(subRepo, "master");
@@ -448,7 +489,7 @@
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project",
new Project.NameKey(name("config-repo2")));
- allowSubmoduleSubscription("config-repo", "refs/heads/*",
+ allowMatchingSubmoduleSubscription("config-repo", "refs/heads/*",
"super-project", "refs/heads/*");
pushChangeTo(subRepo, "master");
@@ -463,7 +504,7 @@
public void testAllowedButNotSubscribed() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
pushChangeTo(subRepo, "master");
@@ -490,7 +531,7 @@
TestRepository<?> subRepo = createProjectWithPush(
"nested/subscribed-to-project");
// master is allowed to be subscribed to any superprojects branch:
- allowSubmoduleSubscription("nested/subscribed-to-project",
+ allowMatchingSubmoduleSubscription("nested/subscribed-to-project",
"refs/heads/master", "super-project", null);
pushChangeTo(subRepo, "master");
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
index dfce62e..0ff3af5 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
@@ -58,7 +58,7 @@
public void testSubscriptionUpdateOfManyChanges() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
@@ -113,7 +113,7 @@
public void testSubscriptionUpdateIncludingChangeInSuperproject() throws Exception {
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master", "subscribed-to-project", "master");
@@ -181,11 +181,11 @@
TestRepository<?> sub2 = createProjectWithPush("sub2");
TestRepository<?> sub3 = createProjectWithPush("sub3");
- allowSubmoduleSubscription("sub1", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("sub1", "refs/heads/master",
"super-project", "refs/heads/master");
- allowSubmoduleSubscription("sub2", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("sub2", "refs/heads/master",
"super-project", "refs/heads/master");
- allowSubmoduleSubscription("sub3", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("sub3", "refs/heads/master",
"super-project", "refs/heads/master");
Config config = new Config();
@@ -227,7 +227,7 @@
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> sub = createProjectWithPush("sub");
- allowSubmoduleSubscription("sub", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("sub", "refs/heads/master",
"super-project", "refs/heads/master");
Config config = new Config();
@@ -261,7 +261,7 @@
TestRepository<?> sub = createProjectWithPush("sub");
TestRepository<?> standAlone = createProjectWithPush("standalone");
- allowSubmoduleSubscription("sub", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("sub", "refs/heads/master",
"super-project", "refs/heads/master");
createSubmoduleSubscription(superRepo, "master", "sub", "master");
@@ -301,9 +301,9 @@
TestRepository<?> midRepo = createProjectWithPush("mid-project");
TestRepository<?> bottomRepo = createProjectWithPush("bottom-project");
- allowSubmoduleSubscription("mid-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("mid-project", "refs/heads/master",
"top-project", "refs/heads/master");
- allowSubmoduleSubscription("bottom-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("bottom-project", "refs/heads/master",
"mid-project", "refs/heads/master");
createSubmoduleSubscription(topRepo, "master", "mid-project", "master");
@@ -332,11 +332,11 @@
TestRepository<?> midRepo = createProjectWithPush("mid-project");
TestRepository<?> bottomRepo = createProjectWithPush("bottom-project");
- allowSubmoduleSubscription("mid-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("mid-project", "refs/heads/master",
"top-project", "refs/heads/master");
- allowSubmoduleSubscription("bottom-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("bottom-project", "refs/heads/master",
"mid-project", "refs/heads/master");
- allowSubmoduleSubscription("bottom-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("bottom-project", "refs/heads/master",
"top-project", "refs/heads/master");
createSubmoduleSubscription(midRepo, "master", "bottom-project", "master");
@@ -373,11 +373,11 @@
createSubmoduleSubscription(topRepo, "master", "mid-project", "master");
createSubmoduleSubscription(bottomRepo, "master", "top-project", "master");
- allowSubmoduleSubscription("bottom-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("bottom-project", "refs/heads/master",
"mid-project", "refs/heads/master");
- allowSubmoduleSubscription("mid-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("mid-project", "refs/heads/master",
"top-project", "refs/heads/master");
- allowSubmoduleSubscription("top-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("top-project", "refs/heads/master",
"bottom-project", "refs/heads/master");
ObjectId bottomMasterHead =
@@ -401,9 +401,9 @@
TestRepository<?> superRepo = createProjectWithPush("super-project");
TestRepository<?> subRepo = createProjectWithPush("subscribed-to-project");
- allowSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
+ allowMatchingSubmoduleSubscription("subscribed-to-project", "refs/heads/master",
"super-project", "refs/heads/master");
- allowSubmoduleSubscription("super-project", "refs/heads/dev",
+ allowMatchingSubmoduleSubscription("super-project", "refs/heads/dev",
"subscribed-to-project", "refs/heads/dev");
pushChangeTo(subRepo, "dev");
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/SubscribeSection.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/SubscribeSection.java
index 6cee630..3fdc331 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/SubscribeSection.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/SubscribeSection.java
@@ -29,20 +29,28 @@
@GwtIncompatible("Unemulated org.eclipse.jgit.transport.RefSpec")
public class SubscribeSection {
- private final List<RefSpec> refSpecs;
+ private final List<RefSpec> multiMatchRefSpecs;
+ private final List<RefSpec> matchingRefSpecs;
private final Project.NameKey project;
public SubscribeSection(Project.NameKey p) {
project = p;
- refSpecs = new ArrayList<>();
+ matchingRefSpecs = new ArrayList<>();
+ multiMatchRefSpecs = new ArrayList<>();
}
- public void addRefSpec(RefSpec spec) {
- refSpecs.add(spec);
+ public void addMatchingRefSpec(RefSpec spec) {
+ matchingRefSpecs.add(spec);
}
- public void addRefSpec(String spec) {
- refSpecs.add(new RefSpec(spec));
+ public void addMatchingRefSpec(String spec) {
+ RefSpec r = new RefSpec(spec);
+ matchingRefSpecs.add(r);
+ }
+
+ public void addMultiMatchRefSpec(String spec) {
+ RefSpec r = new RefSpec(spec, RefSpec.WildcardMode.ALLOW_MISMATCH);
+ multiMatchRefSpecs.add(r);
}
public Project.NameKey getProject() {
@@ -57,7 +65,12 @@
* @return if the branch could trigger a superproject update
*/
public boolean appliesTo(Branch.NameKey branch) {
- for (RefSpec r : refSpecs) {
+ for (RefSpec r : matchingRefSpecs) {
+ if (r.matchSource(branch.get())) {
+ return true;
+ }
+ }
+ for (RefSpec r : multiMatchRefSpecs) {
if (r.matchSource(branch.get())) {
return true;
}
@@ -65,8 +78,12 @@
return false;
}
- public Collection<RefSpec> getRefSpecs() {
- return Collections.unmodifiableCollection(refSpecs);
+ public Collection<RefSpec> getMatchingRefSpecs() {
+ return Collections.unmodifiableCollection(matchingRefSpecs);
+ }
+
+ public Collection<RefSpec> getMultiMatchRefSpecs() {
+ return Collections.unmodifiableCollection(multiMatchRefSpecs);
}
@Override
@@ -74,10 +91,19 @@
StringBuilder ret = new StringBuilder();
ret.append("[SubscribeSection, project=");
ret.append(project);
- ret.append(", refs=[");
- for (RefSpec r : refSpecs) {
- ret.append(r.toString());
- ret.append(", ");
+ if (!matchingRefSpecs.isEmpty()) {
+ ret.append(", matching=[");
+ for (RefSpec r : matchingRefSpecs) {
+ ret.append(r.toString());
+ ret.append(", ");
+ }
+ }
+ if (!multiMatchRefSpecs.isEmpty()) {
+ ret.append(", all=[");
+ for (RefSpec r : multiMatchRefSpecs) {
+ ret.append(r.toString());
+ ret.append(", ");
+ }
}
ret.append("]");
return ret.toString();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
index 6d9d759..64d9a9c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
@@ -132,7 +132,8 @@
private static final String KEY_STATE = "state";
private static final String SUBSCRIBE_SECTION = "allowSuperproject";
- private static final String SUBSCRIBE_REFS = "refs";
+ private static final String SUBSCRIBE_MATCH_REFS = "matching";
+ private static final String SUBSCRIBE_MULTI_MATCH_REFS = "all";
private static final String DASHBOARD = "dashboard";
private static final String KEY_DEFAULT = "default";
@@ -848,8 +849,12 @@
Project.NameKey p = new Project.NameKey(projectName);
SubscribeSection ss = new SubscribeSection(p);
for (String s : rc.getStringList(SUBSCRIBE_SECTION,
- projectName, SUBSCRIBE_REFS)) {
- ss.addRefSpec(s);
+ projectName, SUBSCRIBE_MULTI_MATCH_REFS)) {
+ ss.addMultiMatchRefSpec(s);
+ }
+ for (String s : rc.getStringList(SUBSCRIBE_SECTION,
+ projectName, SUBSCRIBE_MATCH_REFS)) {
+ ss.addMatchingRefSpec(s);
}
subscribeSections.put(p, ss);
}
@@ -1238,8 +1243,13 @@
private void saveSubscribeSections(Config rc) {
for (Project.NameKey p : subscribeSections.keySet()) {
SubscribeSection s = subscribeSections.get(p);
- for (RefSpec r : s.getRefSpecs()) {
- rc.setString(SUBSCRIBE_SECTION, p.get(), SUBSCRIBE_REFS, r.toString());
+ for (RefSpec r : s.getMatchingRefSpecs()) {
+ rc.setString(SUBSCRIBE_SECTION, p.get(),
+ SUBSCRIBE_MATCH_REFS, r.toString());
+ }
+ for (RefSpec r : s.getMultiMatchRefSpecs()) {
+ rc.setString(SUBSCRIBE_SECTION, p.get(),
+ SUBSCRIBE_MULTI_MATCH_REFS, r.toString());
}
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
index b23ff95..76f74ed 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
@@ -62,6 +62,7 @@
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
@@ -222,33 +223,50 @@
private Collection<Branch.NameKey> getDestinationBranches(Branch.NameKey src,
SubscribeSection s) throws IOException {
- Collection<Branch.NameKey> ret = new ArrayList<>();
+ Collection<Branch.NameKey> ret = new HashSet<>();
logDebug("Inspecting SubscribeSection " + s);
- for (RefSpec r : s.getRefSpecs()) {
- logDebug("Inspecting ref " + r);
- if (r.matchSource(src.get())) {
- if (r.getDestination() == null) {
- // no need to care for wildcard, as we matched already
- OpenRepo or;
- try {
- or = orm.openRepo(s.getProject(), false);
- } catch (NoSuchProjectException e) {
- // A project listed a non existent project to be allowed
- // to subscribe to it. Allow this for now.
- continue;
- }
+ for (RefSpec r : s.getMatchingRefSpecs()) {
+ logDebug("Inspecting [matching] ref " + r);
+ if (!r.matchSource(src.get())) {
+ continue;
+ }
+ if (r.isWildcard()) {
+ // refs/heads/*[:refs/somewhere/*]
+ ret.add(new Branch.NameKey(s.getProject(),
+ r.expandFromSource(src.get()).getDestination()));
+ } else {
+ // e.g. refs/heads/master[:refs/heads/stable]
+ String dest = r.getDestination();
+ if (dest == null) {
+ dest = r.getSource();
+ }
+ ret.add(new Branch.NameKey(s.getProject(), dest));
+ }
+ }
- for (Ref ref : or.repo.getRefDatabase().getRefs(
- RefNames.REFS_HEADS).values()) {
- ret.add(new Branch.NameKey(s.getProject(), ref.getName()));
- }
- } else if (r.isWildcard()) {
- // refs/heads/*:refs/heads/*
- ret.add(new Branch.NameKey(s.getProject(),
- r.expandFromSource(src.get()).getDestination()));
- } else {
- // e.g. refs/heads/master:refs/heads/stable
- ret.add(new Branch.NameKey(s.getProject(), r.getDestination()));
+ for (RefSpec r : s.getMultiMatchRefSpecs()) {
+ logDebug("Inspecting [all] ref " + r);
+ if (!r.matchSource(src.get())) {
+ continue;
+ }
+ OpenRepo or;
+ try {
+ or = orm.openRepo(s.getProject(), false);
+ } catch (NoSuchProjectException e) {
+ // A project listed a non existent project to be allowed
+ // to subscribe to it. Allow this for now, i.e. no exception is
+ // thrown.
+ continue;
+ }
+
+ for (Ref ref : or.repo.getRefDatabase().getRefs(
+ RefNames.REFS_HEADS).values()) {
+ if (r.getDestination() != null && !r.matchDestination(ref.getName())) {
+ continue;
+ }
+ Branch.NameKey b = new Branch.NameKey(s.getProject(), ref.getName());
+ if (!ret.contains(b)) {
+ ret.add(b);
}
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_120.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_120.java
index e95353a..fc1b0cd 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_120.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_120.java
@@ -79,10 +79,10 @@
}
RefSpec newRefSpec = new RefSpec(subbranch.get() + ":" + superBranch.get());
- if (!s.getRefSpecs().contains(newRefSpec)) {
+ if (!s.getMatchingRefSpecs().contains(newRefSpec)) {
// For the migration we use only exact RefSpecs, we're not trying to
// generalize it.
- s.addRefSpec(newRefSpec);
+ s.addMatchingRefSpec(newRefSpec);
}
pc.commit(md);