Support different project level merge policies
Replace the hidden "gerrit.fastforwardonly" config file option with a project level property stored in the database containing one of three different values: * FAST_FORWARD_ONLY: Never create a merge commit * MERGE_IF_NECESSARY: Standard/default behavior * MERGE_ALWAYS: Always create a merge commit Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -43,11 +43,13 @@ for a project named `project`.
|
|||||||
INSERT INTO projects
|
INSERT INTO projects
|
||||||
(project_id
|
(project_id
|
||||||
,use_contributor_agreements
|
,use_contributor_agreements
|
||||||
|
,submit_type
|
||||||
,owner_group_id
|
,owner_group_id
|
||||||
,name)
|
,name)
|
||||||
VALUES
|
VALUES
|
||||||
(nextval('project_id')
|
(nextval('project_id')
|
||||||
,'Y'
|
,'Y'
|
||||||
|
,'M'
|
||||||
,(SELECT admin_group_id FROM system_config)
|
,(SELECT admin_group_id FROM system_config)
|
||||||
,'new/project');
|
,'new/project');
|
||||||
|
|
||||||
@@ -61,6 +63,40 @@ for a project named `project`.
|
|||||||
,'new/project');
|
,'new/project');
|
||||||
====
|
====
|
||||||
|
|
||||||
|
Change Submit Action
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The method Gerrit uses to submit a change to a project can be
|
||||||
|
modified by any project owner through the project console, `Admin` >
|
||||||
|
`Projects`. The following methods are supported:
|
||||||
|
|
||||||
|
* Fast Forward Only
|
||||||
|
+
|
||||||
|
This method produces a strictly linear history. All merges must
|
||||||
|
be handled on the client, prior to uploading to Gerrit for review.
|
||||||
|
+
|
||||||
|
To submit a change, the change must be a strict superset of the
|
||||||
|
destination branch. That is, the change must already contain the
|
||||||
|
tip of the destination branch at submit time.
|
||||||
|
|
||||||
|
* Merge If Necessary
|
||||||
|
+
|
||||||
|
This is the default for a new project (and why `\'M'` is suggested
|
||||||
|
above in the insert statement).
|
||||||
|
+
|
||||||
|
If the change being submitted is a strict superset of the destination
|
||||||
|
branch, then the branch is fast-forwarded to the change. If not,
|
||||||
|
then a merge commit is automatically created. This is identical
|
||||||
|
to the classical `git merge` behavior, or `git merge \--ff`.
|
||||||
|
|
||||||
|
* Always Merge
|
||||||
|
+
|
||||||
|
Always produce a merge commit, even if the change is a strict
|
||||||
|
superset of the destination branch. This is identical to the
|
||||||
|
behavior of `git merge \--no-ff`, and may be useful if the
|
||||||
|
project needs to follow submits with `git log \--first-parent`.
|
||||||
|
|
||||||
|
|
||||||
Registering Additional Branches
|
Registering Additional Branches
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
@@ -32,10 +32,15 @@ public interface AdminConstants extends Constants {
|
|||||||
|
|
||||||
String headingOwner();
|
String headingOwner();
|
||||||
String headingDescription();
|
String headingDescription();
|
||||||
|
String headingSubmitType();
|
||||||
String headingMembers();
|
String headingMembers();
|
||||||
String headingCreateGroup();
|
String headingCreateGroup();
|
||||||
String headingAccessRights();
|
String headingAccessRights();
|
||||||
|
|
||||||
|
String projectSubmitType_FAST_FORWARD_ONLY();
|
||||||
|
String projectSubmitType_MERGE_ALWAYS();
|
||||||
|
String projectSubmitType_MERGE_IF_NECESSARY();
|
||||||
|
|
||||||
String columnMember();
|
String columnMember();
|
||||||
String columnEmailAddress();
|
String columnEmailAddress();
|
||||||
String columnGroupName();
|
String columnGroupName();
|
||||||
|
@@ -13,10 +13,15 @@ buttonAddProjectRight = Add Access Right
|
|||||||
|
|
||||||
headingOwner = Owners
|
headingOwner = Owners
|
||||||
headingDescription = Description
|
headingDescription = Description
|
||||||
|
headingSubmitType = Change Submit Action
|
||||||
headingMembers = Members
|
headingMembers = Members
|
||||||
headingCreateGroup = Create New Group
|
headingCreateGroup = Create New Group
|
||||||
headingAccessRights = Access Rights
|
headingAccessRights = Access Rights
|
||||||
|
|
||||||
|
projectSubmitType_FAST_FORWARD_ONLY = Fast Forward Only
|
||||||
|
projectSubmitType_MERGE_IF_NECESSARY = Merge If Necessary
|
||||||
|
projectSubmitType_MERGE_ALWAYS = Always Merge
|
||||||
|
|
||||||
columnMember = Member
|
columnMember = Member
|
||||||
columnEmailAddress = Email Address
|
columnEmailAddress = Email Address
|
||||||
columnGroupName = Group Name
|
columnGroupName = Group Name
|
||||||
|
@@ -41,6 +41,10 @@ public interface ProjectAdminService extends RemoteJsonService {
|
|||||||
void changeProjectOwner(Project.Id projectId, String newOwnerName,
|
void changeProjectOwner(Project.Id projectId, String newOwnerName,
|
||||||
AsyncCallback<VoidResult> callback);
|
AsyncCallback<VoidResult> callback);
|
||||||
|
|
||||||
|
@SignInRequired
|
||||||
|
void changeProjectSubmitType(Project.Id projectId,
|
||||||
|
Project.SubmitType newSubmitType, AsyncCallback<VoidResult> callback);
|
||||||
|
|
||||||
@SignInRequired
|
@SignInRequired
|
||||||
void deleteRight(Set<ProjectRight.Key> ids, AsyncCallback<VoidResult> callback);
|
void deleteRight(Set<ProjectRight.Key> ids, AsyncCallback<VoidResult> callback);
|
||||||
|
|
||||||
|
@@ -22,9 +22,11 @@ import com.google.gerrit.client.ui.AccountGroupSuggestOracle;
|
|||||||
import com.google.gerrit.client.ui.SmallHeading;
|
import com.google.gerrit.client.ui.SmallHeading;
|
||||||
import com.google.gerrit.client.ui.TextSaveButtonListener;
|
import com.google.gerrit.client.ui.TextSaveButtonListener;
|
||||||
import com.google.gwt.user.client.ui.Button;
|
import com.google.gwt.user.client.ui.Button;
|
||||||
|
import com.google.gwt.user.client.ui.ChangeListener;
|
||||||
import com.google.gwt.user.client.ui.ClickListener;
|
import com.google.gwt.user.client.ui.ClickListener;
|
||||||
import com.google.gwt.user.client.ui.Composite;
|
import com.google.gwt.user.client.ui.Composite;
|
||||||
import com.google.gwt.user.client.ui.FlowPanel;
|
import com.google.gwt.user.client.ui.FlowPanel;
|
||||||
|
import com.google.gwt.user.client.ui.ListBox;
|
||||||
import com.google.gwt.user.client.ui.Panel;
|
import com.google.gwt.user.client.ui.Panel;
|
||||||
import com.google.gwt.user.client.ui.SuggestBox;
|
import com.google.gwt.user.client.ui.SuggestBox;
|
||||||
import com.google.gwt.user.client.ui.TextArea;
|
import com.google.gwt.user.client.ui.TextArea;
|
||||||
@@ -41,6 +43,10 @@ public class ProjectInfoPanel extends Composite {
|
|||||||
private SuggestBox ownerTxt;
|
private SuggestBox ownerTxt;
|
||||||
private Button saveOwner;
|
private Button saveOwner;
|
||||||
|
|
||||||
|
private Panel submitTypePanel;
|
||||||
|
private ListBox submitType;
|
||||||
|
private Project.SubmitType currentSubmitType;
|
||||||
|
|
||||||
private TextArea descTxt;
|
private TextArea descTxt;
|
||||||
private Button saveDesc;
|
private Button saveDesc;
|
||||||
|
|
||||||
@@ -48,6 +54,7 @@ public class ProjectInfoPanel extends Composite {
|
|||||||
final FlowPanel body = new FlowPanel();
|
final FlowPanel body = new FlowPanel();
|
||||||
initOwner(body);
|
initOwner(body);
|
||||||
initDescription(body);
|
initDescription(body);
|
||||||
|
initSubmitType(body);
|
||||||
initWidget(body);
|
initWidget(body);
|
||||||
|
|
||||||
projectId = toShow;
|
projectId = toShow;
|
||||||
@@ -72,6 +79,7 @@ public class ProjectInfoPanel extends Composite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void enableForm(final boolean on) {
|
private void enableForm(final boolean on) {
|
||||||
|
submitType.setEnabled(on);
|
||||||
ownerTxtBox.setEnabled(on);
|
ownerTxtBox.setEnabled(on);
|
||||||
descTxt.setEnabled(on);
|
descTxt.setEnabled(on);
|
||||||
}
|
}
|
||||||
@@ -132,6 +140,56 @@ public class ProjectInfoPanel extends Composite {
|
|||||||
new TextSaveButtonListener(descTxt, saveDesc);
|
new TextSaveButtonListener(descTxt, saveDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initSubmitType(final Panel body) {
|
||||||
|
submitTypePanel = new VerticalPanel();
|
||||||
|
submitTypePanel.add(new SmallHeading(Util.C.headingSubmitType()));
|
||||||
|
|
||||||
|
submitType = new ListBox();
|
||||||
|
for (final Project.SubmitType type : Project.SubmitType.values()) {
|
||||||
|
submitType.addItem(Util.toLongString(type), type.name());
|
||||||
|
}
|
||||||
|
submitType.addChangeListener(new ChangeListener() {
|
||||||
|
public void onChange(Widget sender) {
|
||||||
|
final int i = submitType.getSelectedIndex();
|
||||||
|
if (i < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Project.SubmitType newSubmitType =
|
||||||
|
Project.SubmitType.valueOf(submitType.getValue(i));
|
||||||
|
submitType.setEnabled(false);
|
||||||
|
Util.PROJECT_SVC.changeProjectSubmitType(projectId, newSubmitType,
|
||||||
|
new GerritCallback<VoidResult>() {
|
||||||
|
public void onSuccess(final VoidResult result) {
|
||||||
|
currentSubmitType = newSubmitType;
|
||||||
|
submitType.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(final Throwable caught) {
|
||||||
|
submitType.setEnabled(false);
|
||||||
|
setSubmitType(currentSubmitType);
|
||||||
|
super.onFailure(caught);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
submitTypePanel.add(submitType);
|
||||||
|
body.add(submitTypePanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSubmitType(final Project.SubmitType newSubmitType) {
|
||||||
|
currentSubmitType = newSubmitType;
|
||||||
|
if (submitType != null) {
|
||||||
|
for (int i = 0; i < submitType.getItemCount(); i++) {
|
||||||
|
if (newSubmitType.name().equals(submitType.getValue(i))) {
|
||||||
|
submitType.setSelectedIndex(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
submitType.setSelectedIndex(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void display(final ProjectDetail result) {
|
void display(final ProjectDetail result) {
|
||||||
final Project project = result.project;
|
final Project project = result.project;
|
||||||
final AccountGroup owner = result.groups.get(project.getOwnerGroupId());
|
final AccountGroup owner = result.groups.get(project.getOwnerGroupId());
|
||||||
@@ -143,10 +201,13 @@ public class ProjectInfoPanel extends Composite {
|
|||||||
|
|
||||||
if (ProjectRight.WILD_PROJECT.equals(project.getId())) {
|
if (ProjectRight.WILD_PROJECT.equals(project.getId())) {
|
||||||
ownerPanel.setVisible(false);
|
ownerPanel.setVisible(false);
|
||||||
|
submitTypePanel.setVisible(false);
|
||||||
} else {
|
} else {
|
||||||
ownerPanel.setVisible(true);
|
ownerPanel.setVisible(true);
|
||||||
|
submitTypePanel.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
descTxt.setText(project.getDescription());
|
descTxt.setText(project.getDescription());
|
||||||
|
setSubmitType(project.getSubmitType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
package com.google.gerrit.client.admin;
|
package com.google.gerrit.client.admin;
|
||||||
|
|
||||||
|
import com.google.gerrit.client.reviewdb.Project;
|
||||||
import com.google.gwt.core.client.GWT;
|
import com.google.gwt.core.client.GWT;
|
||||||
import com.google.gwtjsonrpc.client.JsonUtil;
|
import com.google.gwtjsonrpc.client.JsonUtil;
|
||||||
|
|
||||||
@@ -30,4 +31,20 @@ public class Util {
|
|||||||
PROJECT_SVC = GWT.create(ProjectAdminService.class);
|
PROJECT_SVC = GWT.create(ProjectAdminService.class);
|
||||||
JsonUtil.bind(PROJECT_SVC, "rpc/ProjectAdminService");
|
JsonUtil.bind(PROJECT_SVC, "rpc/ProjectAdminService");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String toLongString(final Project.SubmitType type) {
|
||||||
|
if (type == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
switch (type) {
|
||||||
|
case FAST_FORWARD_ONLY:
|
||||||
|
return C.projectSubmitType_FAST_FORWARD_ONLY();
|
||||||
|
case MERGE_IF_NECESSARY:
|
||||||
|
return C.projectSubmitType_MERGE_IF_NECESSARY();
|
||||||
|
case MERGE_ALWAYS:
|
||||||
|
return C.projectSubmitType_MERGE_ALWAYS();
|
||||||
|
default:
|
||||||
|
return type.name();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -81,6 +81,33 @@ public final class Project {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static enum SubmitType {
|
||||||
|
FAST_FORWARD_ONLY('F'),
|
||||||
|
|
||||||
|
MERGE_IF_NECESSARY('M'),
|
||||||
|
|
||||||
|
MERGE_ALWAYS('A');
|
||||||
|
|
||||||
|
private final char code;
|
||||||
|
|
||||||
|
private SubmitType(final char c) {
|
||||||
|
code = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SubmitType forCode(final char c) {
|
||||||
|
for (final SubmitType s : SubmitType.values()) {
|
||||||
|
if (s.code == c) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
protected NameKey name;
|
protected NameKey name;
|
||||||
|
|
||||||
@@ -96,6 +123,9 @@ public final class Project {
|
|||||||
@Column
|
@Column
|
||||||
protected boolean useContributorAgreements;
|
protected boolean useContributorAgreements;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
protected char submitType;
|
||||||
|
|
||||||
protected Project() {
|
protected Project() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,6 +133,7 @@ public final class Project {
|
|||||||
name = newName;
|
name = newName;
|
||||||
projectId = newId;
|
projectId = newId;
|
||||||
useContributorAgreements = true;
|
useContributorAgreements = true;
|
||||||
|
setSubmitType(SubmitType.MERGE_IF_NECESSARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Project.Id getId() {
|
public Project.Id getId() {
|
||||||
@@ -140,4 +171,12 @@ public final class Project {
|
|||||||
public void setUseContributorAgreements(final boolean u) {
|
public void setUseContributorAgreements(final boolean u) {
|
||||||
useContributorAgreements = u;
|
useContributorAgreements = u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SubmitType getSubmitType() {
|
||||||
|
return SubmitType.forCode(submitType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubmitType(final SubmitType type) {
|
||||||
|
submitType = type.getCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@ import com.google.gwtorm.client.Sequence;
|
|||||||
|
|
||||||
/** The review service database schema. */
|
/** The review service database schema. */
|
||||||
public interface ReviewDb extends Schema {
|
public interface ReviewDb extends Schema {
|
||||||
public static final int VERSION = 8;
|
public static final int VERSION = 9;
|
||||||
|
|
||||||
@Relation
|
@Relation
|
||||||
SchemaVersionAccess schemaVersion();
|
SchemaVersionAccess schemaVersion();
|
||||||
|
@@ -15,12 +15,14 @@
|
|||||||
package com.google.gerrit.git;
|
package com.google.gerrit.git;
|
||||||
|
|
||||||
import com.google.gerrit.client.data.ApprovalType;
|
import com.google.gerrit.client.data.ApprovalType;
|
||||||
|
import com.google.gerrit.client.data.ProjectCache;
|
||||||
import com.google.gerrit.client.reviewdb.ApprovalCategory;
|
import com.google.gerrit.client.reviewdb.ApprovalCategory;
|
||||||
import com.google.gerrit.client.reviewdb.Branch;
|
import com.google.gerrit.client.reviewdb.Branch;
|
||||||
import com.google.gerrit.client.reviewdb.Change;
|
import com.google.gerrit.client.reviewdb.Change;
|
||||||
import com.google.gerrit.client.reviewdb.ChangeApproval;
|
import com.google.gerrit.client.reviewdb.ChangeApproval;
|
||||||
import com.google.gerrit.client.reviewdb.ChangeMessage;
|
import com.google.gerrit.client.reviewdb.ChangeMessage;
|
||||||
import com.google.gerrit.client.reviewdb.PatchSet;
|
import com.google.gerrit.client.reviewdb.PatchSet;
|
||||||
|
import com.google.gerrit.client.reviewdb.Project;
|
||||||
import com.google.gerrit.client.reviewdb.ReviewDb;
|
import com.google.gerrit.client.reviewdb.ReviewDb;
|
||||||
import com.google.gerrit.client.rpc.Common;
|
import com.google.gerrit.client.rpc.Common;
|
||||||
import com.google.gerrit.client.workflow.FunctionState;
|
import com.google.gerrit.client.workflow.FunctionState;
|
||||||
@@ -84,6 +86,7 @@ public class MergeOp {
|
|||||||
private final GerritServer server;
|
private final GerritServer server;
|
||||||
private final PersonIdent myIdent;
|
private final PersonIdent myIdent;
|
||||||
private final Branch.NameKey destBranch;
|
private final Branch.NameKey destBranch;
|
||||||
|
private Project destProject;
|
||||||
private final List<CodeReviewCommit> toMerge;
|
private final List<CodeReviewCommit> toMerge;
|
||||||
private List<Change> submitted;
|
private List<Change> submitted;
|
||||||
private final Map<Change.Id, CommitMergeStatus> status;
|
private final Map<Change.Id, CommitMergeStatus> status;
|
||||||
@@ -103,6 +106,13 @@ public class MergeOp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void merge() throws MergeException {
|
public void merge() throws MergeException {
|
||||||
|
final ProjectCache.Entry pe =
|
||||||
|
Common.getProjectCache().get(destBranch.getParentKey());
|
||||||
|
if (pe == null) {
|
||||||
|
throw new MergeException("No such project: " + destBranch.getParentKey());
|
||||||
|
}
|
||||||
|
destProject = pe.getProject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
schema = Common.getSchemaFactory().open();
|
schema = Common.getSchemaFactory().open();
|
||||||
} catch (OrmException e) {
|
} catch (OrmException e) {
|
||||||
@@ -274,23 +284,24 @@ public class MergeOp {
|
|||||||
|
|
||||||
// Take the first fast-forward available, if any is available in the set.
|
// Take the first fast-forward available, if any is available in the set.
|
||||||
//
|
//
|
||||||
for (final Iterator<CodeReviewCommit> i = toMerge.iterator(); i.hasNext();) {
|
if (destProject.getSubmitType() != Project.SubmitType.MERGE_ALWAYS) {
|
||||||
try {
|
for (final Iterator<CodeReviewCommit> i = toMerge.iterator(); i.hasNext();) {
|
||||||
final CodeReviewCommit n = i.next();
|
try {
|
||||||
if (mergeTip == null || rw.isMergedInto(mergeTip, n)) {
|
final CodeReviewCommit n = i.next();
|
||||||
mergeTip = n;
|
if (mergeTip == null || rw.isMergedInto(mergeTip, n)) {
|
||||||
i.remove();
|
mergeTip = n;
|
||||||
break;
|
i.remove();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new MergeException("Cannot fast-forward test during merge", e);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
throw new MergeException("Cannot fast-forward test during merge", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this project only permits fast-forwards, abort everything else.
|
// If this project only permits fast-forwards, abort everything else.
|
||||||
//
|
//
|
||||||
if ("true".equals(db.getConfig().getString("gerrit", null,
|
if (destProject.getSubmitType() == Project.SubmitType.FAST_FORWARD_ONLY) {
|
||||||
"fastforwardonly"))) {
|
|
||||||
while (!toMerge.isEmpty()) {
|
while (!toMerge.isEmpty()) {
|
||||||
final CodeReviewCommit n = toMerge.remove(0);
|
final CodeReviewCommit n = toMerge.remove(0);
|
||||||
n.statusCode = CommitMergeStatus.PATH_CONFLICT;
|
n.statusCode = CommitMergeStatus.PATH_CONFLICT;
|
||||||
|
@@ -0,0 +1,89 @@
|
|||||||
|
// Copyright (C) 2009 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.pgm;
|
||||||
|
|
||||||
|
import com.google.gerrit.client.reviewdb.Project;
|
||||||
|
import com.google.gerrit.client.reviewdb.ReviewDb;
|
||||||
|
import com.google.gerrit.client.rpc.Common;
|
||||||
|
import com.google.gerrit.git.InvalidRepositoryException;
|
||||||
|
import com.google.gerrit.git.WorkQueue;
|
||||||
|
import com.google.gerrit.server.GerritServer;
|
||||||
|
import com.google.gwtjsonrpc.server.XsrfException;
|
||||||
|
import com.google.gwtorm.client.OrmException;
|
||||||
|
|
||||||
|
import org.spearce.jgit.lib.ProgressMonitor;
|
||||||
|
import org.spearce.jgit.lib.Repository;
|
||||||
|
import org.spearce.jgit.lib.TextProgressMonitor;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/** Update project's submit_type field from their git config files. */
|
||||||
|
public class ImportProjectSubmitTypes {
|
||||||
|
private static final String GERRIT = "gerrit";
|
||||||
|
private static final String FFO = "fastforwardonly";
|
||||||
|
|
||||||
|
public static void main(final String[] argv) throws OrmException,
|
||||||
|
XsrfException {
|
||||||
|
try {
|
||||||
|
mainImpl(argv);
|
||||||
|
} finally {
|
||||||
|
WorkQueue.terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void mainImpl(final String[] argv) throws OrmException,
|
||||||
|
XsrfException {
|
||||||
|
final ProgressMonitor pm = new TextProgressMonitor();
|
||||||
|
final GerritServer gs = GerritServer.getInstance();
|
||||||
|
final ReviewDb db = Common.getSchemaFactory().open();
|
||||||
|
try {
|
||||||
|
final List<Project> all = db.projects().all().toList();
|
||||||
|
pm.start(1);
|
||||||
|
pm.beginTask("Update projects", all.size());
|
||||||
|
for (final Project p : all) {
|
||||||
|
if (p.getSubmitType() != null
|
||||||
|
&& p.getSubmitType() != Project.SubmitType.MERGE_IF_NECESSARY) {
|
||||||
|
pm.update(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Repository r;
|
||||||
|
try {
|
||||||
|
r = gs.getRepositoryCache().get(p.getName());
|
||||||
|
} catch (InvalidRepositoryException e) {
|
||||||
|
pm.update(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("true".equals(r.getConfig().getString(GERRIT, null, FFO))) {
|
||||||
|
p.setSubmitType(Project.SubmitType.FAST_FORWARD_ONLY);
|
||||||
|
db.projects().update(Collections.singleton(p));
|
||||||
|
r.getConfig().unsetString(GERRIT, null, FFO);
|
||||||
|
try {
|
||||||
|
r.getConfig().save();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Ignore a save error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pm.update(1);
|
||||||
|
}
|
||||||
|
pm.endTask();
|
||||||
|
} finally {
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -180,6 +180,24 @@ public class ProjectAdminServiceImpl extends BaseServiceImplementation
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void changeProjectSubmitType(final Project.Id projectId,
|
||||||
|
final Project.SubmitType newSubmitType,
|
||||||
|
final AsyncCallback<VoidResult> callback) {
|
||||||
|
run(callback, new Action<VoidResult>() {
|
||||||
|
public VoidResult run(final ReviewDb db) throws OrmException, Failure {
|
||||||
|
assertAmProjectOwner(db, projectId);
|
||||||
|
final Project project = db.projects().get(projectId);
|
||||||
|
if (project == null) {
|
||||||
|
throw new Failure(new NoSuchEntityException());
|
||||||
|
}
|
||||||
|
project.setSubmitType(newSubmitType);
|
||||||
|
db.projects().update(Collections.singleton(project));
|
||||||
|
Common.getProjectCache().invalidate(project);
|
||||||
|
return VoidResult.INSTANCE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void deleteRight(final Set<ProjectRight.Key> keys,
|
public void deleteRight(final Set<ProjectRight.Key> keys,
|
||||||
final AsyncCallback<VoidResult> callback) {
|
final AsyncCallback<VoidResult> callback) {
|
||||||
run(callback, new Action<VoidResult>() {
|
run(callback, new Action<VoidResult>() {
|
||||||
|
9
src/main/webapp/WEB-INF/sql/upgrade008_009.sql
Normal file
9
src/main/webapp/WEB-INF/sql/upgrade008_009.sql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
-- Upgrade: schema_version 8 to 9
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE projects ADD submit_type CHAR(1);
|
||||||
|
UPDATE projects SET submit_type = 'M'; -- MERGE_IF_NECESSARY
|
||||||
|
ALTER TABLE projects ALTER COLUMN submit_type SET DEFAULT ' ';
|
||||||
|
ALTER TABLE projects ALTER COLUMN submit_type SET NOT NULL;
|
||||||
|
|
||||||
|
UPDATE schema_version SET version_nbr = 9;
|
Reference in New Issue
Block a user