Make the --other-branches configurable
Introduce a branchOrder section in the project.config in order to define a branch order and automate the back/forward porting of changes. For now assume only one branchOrder section. For example: [branchOrder] branch = master branch = stable-2.9 branch = stable-2.8 branch = stable-2.7 This format makes the ordering obvious (top-down) and complete: for any two branches from the list the order is defined. The --other-branches will rely on the branchOrder section in order to find out a set of branches for which to check mergeability. With the above example, If a change is pushed to the master branch then the --other-branches option will test mergeability into the stable-2.9, stable-2.8 and stable-2.7 branches. If the changed would be pushed to the stable-2.8 then the --other-branches option would test mergeability only into the stable-2.7 branch. Change-Id: Ib806d7e4b5702fa2d8effd197829b729cad95432
This commit is contained in:
parent
063f658042
commit
944b838d88
@ -198,6 +198,41 @@ link:access-control.html#global_capabilities[Global Capabilities]
|
|||||||
documentation for a full list of available capabilities.
|
documentation for a full list of available capabilities.
|
||||||
|
|
||||||
|
|
||||||
|
[[branchOrder-section]]
|
||||||
|
=== branchOrder section
|
||||||
|
|
||||||
|
Defines a branch ordering which is used for backporting of changes.
|
||||||
|
Backporting will be offered for a change (in the Gerrit UI) for all
|
||||||
|
more stable branches where the change can merge cleanly.
|
||||||
|
|
||||||
|
[[branchOrder.branch]]branchOrder.branch::
|
||||||
|
+
|
||||||
|
A branch name, typically multiple values will be defined. The order of branch
|
||||||
|
names in this section defines the branch order. The topmost is considered to be
|
||||||
|
the least stable branch (typically the master branch) and the last one the
|
||||||
|
most stable (typically the last maintained release branch).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
----
|
||||||
|
[branchOrder]
|
||||||
|
branch = master
|
||||||
|
branch = stable-2.9
|
||||||
|
branch = stable-2.8
|
||||||
|
branch = stable-2.7
|
||||||
|
----
|
||||||
|
|
||||||
|
The `branchOrder` section is inheritable. This is useful when multiple or all
|
||||||
|
projects follow the same branch rules. A `branchOrder` section in a child
|
||||||
|
project completely overrides any `branchOrder` section from a parent i.e. there
|
||||||
|
is no merging of `branchOrder` sections. A present but empty `branchOrder`
|
||||||
|
section removes all inherited branch order.
|
||||||
|
|
||||||
|
Branches not listed in this section will not be included in the mergeability
|
||||||
|
check. If the `branchOrder` section is not defined then the mergeability of a
|
||||||
|
change into other branches will not be done.
|
||||||
|
|
||||||
|
|
||||||
[[file-groups]]
|
[[file-groups]]
|
||||||
== The file +groups+
|
== The file +groups+
|
||||||
|
|
||||||
|
@ -24,12 +24,14 @@ import com.google.gerrit.reviewdb.client.Change;
|
|||||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
import com.google.gerrit.reviewdb.client.RevId;
|
import com.google.gerrit.reviewdb.client.RevId;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
|
import com.google.gerrit.server.git.BranchOrderSection;
|
||||||
import com.google.gerrit.server.git.CodeReviewCommit;
|
import com.google.gerrit.server.git.CodeReviewCommit;
|
||||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
import com.google.gerrit.server.git.MergeException;
|
import com.google.gerrit.server.git.MergeException;
|
||||||
import com.google.gerrit.server.git.strategy.SubmitStrategyFactory;
|
import com.google.gerrit.server.git.strategy.SubmitStrategyFactory;
|
||||||
import com.google.gerrit.server.index.ChangeIndexer;
|
import com.google.gerrit.server.index.ChangeIndexer;
|
||||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||||
|
import com.google.gerrit.server.project.ProjectCache;
|
||||||
import com.google.gwtorm.server.AtomicUpdate;
|
import com.google.gwtorm.server.AtomicUpdate;
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
@ -73,6 +75,7 @@ public class Mergeable implements RestReadView<RevisionResource> {
|
|||||||
|
|
||||||
private final TestSubmitType.Get submitType;
|
private final TestSubmitType.Get submitType;
|
||||||
private final GitRepositoryManager gitManager;
|
private final GitRepositoryManager gitManager;
|
||||||
|
private final ProjectCache projectCache;
|
||||||
private final SubmitStrategyFactory submitStrategyFactory;
|
private final SubmitStrategyFactory submitStrategyFactory;
|
||||||
private final Provider<ReviewDb> db;
|
private final Provider<ReviewDb> db;
|
||||||
private final ChangeIndexer indexer;
|
private final ChangeIndexer indexer;
|
||||||
@ -82,11 +85,13 @@ public class Mergeable implements RestReadView<RevisionResource> {
|
|||||||
@Inject
|
@Inject
|
||||||
Mergeable(TestSubmitType.Get submitType,
|
Mergeable(TestSubmitType.Get submitType,
|
||||||
GitRepositoryManager gitManager,
|
GitRepositoryManager gitManager,
|
||||||
|
ProjectCache projectCache,
|
||||||
SubmitStrategyFactory submitStrategyFactory,
|
SubmitStrategyFactory submitStrategyFactory,
|
||||||
Provider<ReviewDb> db,
|
Provider<ReviewDb> db,
|
||||||
ChangeIndexer indexer) {
|
ChangeIndexer indexer) {
|
||||||
this.submitType = submitType;
|
this.submitType = submitType;
|
||||||
this.gitManager = gitManager;
|
this.gitManager = gitManager;
|
||||||
|
this.projectCache = projectCache;
|
||||||
this.submitStrategyFactory = submitStrategyFactory;
|
this.submitStrategyFactory = submitStrategyFactory;
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.indexer = indexer;
|
this.indexer = indexer;
|
||||||
@ -124,11 +129,17 @@ public class Mergeable implements RestReadView<RevisionResource> {
|
|||||||
|
|
||||||
if (otherBranches) {
|
if (otherBranches) {
|
||||||
result.mergeableInto = new ArrayList<>();
|
result.mergeableInto = new ArrayList<>();
|
||||||
for (Ref r : refs.values()) {
|
BranchOrderSection branchOrder =
|
||||||
if (r.getName().startsWith(Constants.R_HEADS)
|
projectCache.get(change.getProject()).getBranchOrderSection();
|
||||||
&& !r.getName().equals(ref.getName())) {
|
if (branchOrder != null) {
|
||||||
if (isMergeable(change, ps, SubmitType.CHERRY_PICK, git, refs, r)) {
|
int prefixLen = Constants.R_HEADS.length();
|
||||||
result.mergeableInto.add(r.getName());
|
for (String n : branchOrder.getMoreStable(ref.getName())) {
|
||||||
|
Ref other = refs.get(n);
|
||||||
|
if (other == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (isMergeable(change, ps, SubmitType.CHERRY_PICK, git, refs, other)) {
|
||||||
|
result.mergeableInto.add(other.getName().substring(prefixLen));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
// Copyright (C) 2014 The Android Open Source Project
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package com.google.gerrit.server.git;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.Constants;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BranchOrderSection {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Branch names ordered from least to the most stable.
|
||||||
|
*
|
||||||
|
* Typically the order will be like: master, stable-M.N, stable-M.N-1, ...
|
||||||
|
*/
|
||||||
|
private final ImmutableList<String> order;
|
||||||
|
|
||||||
|
public BranchOrderSection(String[] order) {
|
||||||
|
if (order.length == 0) {
|
||||||
|
this.order = ImmutableList.of();
|
||||||
|
} else {
|
||||||
|
ImmutableList.Builder<String> builder = ImmutableList.builder();
|
||||||
|
for (String b : order) {
|
||||||
|
builder.add(fullName(b));
|
||||||
|
}
|
||||||
|
this.order = builder.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String fullName(String branch) {
|
||||||
|
if (branch.startsWith(Constants.R_HEADS)) {
|
||||||
|
return branch;
|
||||||
|
} else {
|
||||||
|
return Constants.R_HEADS + branch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getMoreStable(String branch) {
|
||||||
|
int i = order.indexOf(fullName(branch));
|
||||||
|
if (0 <= i) {
|
||||||
|
return order.subList(i + 1, order.size());
|
||||||
|
} else {
|
||||||
|
return ImmutableList.of();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -95,6 +95,9 @@ public class ProjectConfig extends VersionedMetaData {
|
|||||||
private static final String ACCOUNTS = "accounts";
|
private static final String ACCOUNTS = "accounts";
|
||||||
private static final String KEY_SAME_GROUP_VISIBILITY = "sameGroupVisibility";
|
private static final String KEY_SAME_GROUP_VISIBILITY = "sameGroupVisibility";
|
||||||
|
|
||||||
|
private static final String BRANCH_ORDER = "branchOrder";
|
||||||
|
private static final String BRANCH = "branch";
|
||||||
|
|
||||||
private static final String CONTRIBUTOR_AGREEMENT = "contributor-agreement";
|
private static final String CONTRIBUTOR_AGREEMENT = "contributor-agreement";
|
||||||
private static final String KEY_ACCEPTED = "accepted";
|
private static final String KEY_ACCEPTED = "accepted";
|
||||||
private static final String KEY_REQUIRE_CONTACT_INFORMATION = "requireContactInformation";
|
private static final String KEY_REQUIRE_CONTACT_INFORMATION = "requireContactInformation";
|
||||||
@ -152,6 +155,7 @@ public class ProjectConfig extends VersionedMetaData {
|
|||||||
private AccountsSection accountsSection;
|
private AccountsSection accountsSection;
|
||||||
private Map<AccountGroup.UUID, GroupReference> groupsByUUID;
|
private Map<AccountGroup.UUID, GroupReference> groupsByUUID;
|
||||||
private Map<String, AccessSection> accessSections;
|
private Map<String, AccessSection> accessSections;
|
||||||
|
private BranchOrderSection branchOrderSection;
|
||||||
private Map<String, ContributorAgreement> contributorAgreements;
|
private Map<String, ContributorAgreement> contributorAgreements;
|
||||||
private Map<String, NotifyConfig> notifySections;
|
private Map<String, NotifyConfig> notifySections;
|
||||||
private Map<String, LabelType> labelSections;
|
private Map<String, LabelType> labelSections;
|
||||||
@ -242,6 +246,10 @@ public class ProjectConfig extends VersionedMetaData {
|
|||||||
return sort(accessSections.values());
|
return sort(accessSections.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BranchOrderSection getBranchOrderSection() {
|
||||||
|
return branchOrderSection;
|
||||||
|
}
|
||||||
|
|
||||||
public void remove(AccessSection section) {
|
public void remove(AccessSection section) {
|
||||||
if (section != null) {
|
if (section != null) {
|
||||||
accessSections.remove(section.getName());
|
accessSections.remove(section.getName());
|
||||||
@ -420,6 +428,7 @@ public class ProjectConfig extends VersionedMetaData {
|
|||||||
loadAccountsSection(rc, groupsByName);
|
loadAccountsSection(rc, groupsByName);
|
||||||
loadContributorAgreements(rc, groupsByName);
|
loadContributorAgreements(rc, groupsByName);
|
||||||
loadAccessSections(rc, groupsByName);
|
loadAccessSections(rc, groupsByName);
|
||||||
|
loadBranchOrderSection(rc);
|
||||||
loadNotifySections(rc, groupsByName);
|
loadNotifySections(rc, groupsByName);
|
||||||
loadLabelSections(rc);
|
loadLabelSections(rc);
|
||||||
loadCommentLinkSections(rc);
|
loadCommentLinkSections(rc);
|
||||||
@ -570,6 +579,13 @@ public class ProjectConfig extends VersionedMetaData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadBranchOrderSection(Config rc) {
|
||||||
|
if (rc.getSections().contains(BRANCH_ORDER)) {
|
||||||
|
branchOrderSection = new BranchOrderSection(
|
||||||
|
rc.getStringList(BRANCH_ORDER, null, BRANCH));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<PermissionRule> loadPermissionRules(Config rc, String section,
|
private List<PermissionRule> loadPermissionRules(Config rc, String section,
|
||||||
String subsection, String varName,
|
String subsection, String varName,
|
||||||
Map<String, GroupReference> groupsByName,
|
Map<String, GroupReference> groupsByName,
|
||||||
|
@ -40,6 +40,7 @@ import com.google.gerrit.server.account.CapabilityCollection;
|
|||||||
import com.google.gerrit.server.account.GroupMembership;
|
import com.google.gerrit.server.account.GroupMembership;
|
||||||
import com.google.gerrit.server.config.AllProjectsName;
|
import com.google.gerrit.server.config.AllProjectsName;
|
||||||
import com.google.gerrit.server.config.SitePaths;
|
import com.google.gerrit.server.config.SitePaths;
|
||||||
|
import com.google.gerrit.server.git.BranchOrderSection;
|
||||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
import com.google.gerrit.server.git.ProjectConfig;
|
import com.google.gerrit.server.git.ProjectConfig;
|
||||||
import com.google.gerrit.server.git.ProjectLevelConfig;
|
import com.google.gerrit.server.git.ProjectLevelConfig;
|
||||||
@ -445,6 +446,16 @@ public class ProjectState {
|
|||||||
return ImmutableList.copyOf(cls.values());
|
return ImmutableList.copyOf(cls.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BranchOrderSection getBranchOrderSection() {
|
||||||
|
for (ProjectState s : tree()) {
|
||||||
|
BranchOrderSection section = s.getConfig().getBranchOrderSection();
|
||||||
|
if (section != null) {
|
||||||
|
return section;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public ThemeInfo getTheme() {
|
public ThemeInfo getTheme() {
|
||||||
ThemeInfo theme = this.theme;
|
ThemeInfo theme = this.theme;
|
||||||
if (theme == null) {
|
if (theme == null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user