Merge "Add refs/for/<branch>%submit to auto-merge during push"
This commit is contained in:
@@ -106,6 +106,10 @@ public class Submit implements RestModifyView<RevisionResource, Input> {
|
||||
|
||||
checkSubmitRule(rsrc);
|
||||
change = submit(rsrc, caller);
|
||||
if (change == null) {
|
||||
throw new ResourceConflictException("change is "
|
||||
+ status(dbProvider.get().changes().get(rsrc.getChange().getId())));
|
||||
}
|
||||
|
||||
if (input.waitForMerge) {
|
||||
mergeQueue.merge(change.getDest());
|
||||
@@ -123,21 +127,7 @@ public class Submit implements RestModifyView<RevisionResource, Input> {
|
||||
case MERGED:
|
||||
return new Output(Status.MERGED, change);
|
||||
case NEW:
|
||||
// If the merge was attempted and it failed the system usually
|
||||
// writes a comment as a ChangeMessage and sets status to NEW.
|
||||
// Find the relevant message and report that as the conflict.
|
||||
final Timestamp before = rsrc.getChange().getLastUpdatedOn();
|
||||
ChangeMessage msg = Iterables.getFirst(Iterables.filter(
|
||||
Lists.reverse(dbProvider.get().changeMessages()
|
||||
.byChange(change.getId())
|
||||
.toList()),
|
||||
new Predicate<ChangeMessage>() {
|
||||
@Override
|
||||
public boolean apply(ChangeMessage input) {
|
||||
return input.getAuthor() == null
|
||||
&& input.getWrittenOn().getTime() >= before.getTime();
|
||||
}
|
||||
}), null);
|
||||
ChangeMessage msg = getConflictMessage(rsrc);
|
||||
if (msg != null) {
|
||||
throw new ResourceConflictException(msg.getMessage());
|
||||
}
|
||||
@@ -146,8 +136,30 @@ public class Submit implements RestModifyView<RevisionResource, Input> {
|
||||
}
|
||||
}
|
||||
|
||||
private Change submit(RevisionResource rsrc, IdentifiedUser caller)
|
||||
throws OrmException, ResourceConflictException {
|
||||
/**
|
||||
* If the merge was attempted and it failed the system usually writes a
|
||||
* comment as a ChangeMessage and sets status to NEW. Find the relevant
|
||||
* message and return it.
|
||||
*/
|
||||
public ChangeMessage getConflictMessage(RevisionResource rsrc)
|
||||
throws OrmException {
|
||||
final Timestamp before = rsrc.getChange().getLastUpdatedOn();
|
||||
ChangeMessage msg = Iterables.getFirst(Iterables.filter(
|
||||
Lists.reverse(dbProvider.get().changeMessages()
|
||||
.byChange(rsrc.getChange().getId())
|
||||
.toList()),
|
||||
new Predicate<ChangeMessage>() {
|
||||
@Override
|
||||
public boolean apply(ChangeMessage input) {
|
||||
return input.getAuthor() == null
|
||||
&& input.getWrittenOn().getTime() >= before.getTime();
|
||||
}
|
||||
}), null);
|
||||
return msg;
|
||||
}
|
||||
|
||||
public Change submit(RevisionResource rsrc, IdentifiedUser caller)
|
||||
throws OrmException {
|
||||
final Timestamp timestamp = new Timestamp(System.currentTimeMillis());
|
||||
Change change = rsrc.getChange();
|
||||
ReviewDb db = dbProvider.get();
|
||||
@@ -169,8 +181,7 @@ public class Submit implements RestModifyView<RevisionResource, Input> {
|
||||
}
|
||||
});
|
||||
if (change == null) {
|
||||
throw new ResourceConflictException("change is "
|
||||
+ status(db.changes().get(rsrc.getChange().getId())));
|
||||
return null;
|
||||
}
|
||||
db.commit();
|
||||
} finally {
|
||||
|
@@ -14,7 +14,7 @@
|
||||
|
||||
package com.google.gerrit.server.git;
|
||||
|
||||
enum CommitMergeStatus {
|
||||
public enum CommitMergeStatus {
|
||||
/** */
|
||||
CLEAN_MERGE("Change has been successfully merged into the git repository."),
|
||||
|
||||
|
@@ -59,6 +59,9 @@ import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.AccountResolver;
|
||||
import com.google.gerrit.server.change.ChangeInserter;
|
||||
import com.google.gerrit.server.change.ChangeResource;
|
||||
import com.google.gerrit.server.change.RevisionResource;
|
||||
import com.google.gerrit.server.change.Submit;
|
||||
import com.google.gerrit.server.config.AllProjectsName;
|
||||
import com.google.gerrit.server.config.CanonicalWebUrl;
|
||||
import com.google.gerrit.server.config.TrackingFooters;
|
||||
@@ -87,6 +90,7 @@ import com.google.gwtorm.server.OrmException;
|
||||
import com.google.gwtorm.server.ResultSet;
|
||||
import com.google.gwtorm.server.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||
@@ -277,6 +281,8 @@ public class ReceiveCommits {
|
||||
private Map<String, Ref> allRefs;
|
||||
|
||||
private final SubmoduleOp.Factory subOpFactory;
|
||||
private final Provider<Submit> submitProvider;
|
||||
private final MergeQueue mergeQueue;
|
||||
|
||||
private final List<CommitValidationMessage> messages = new ArrayList<CommitValidationMessage>();
|
||||
private ListMultimap<Error, String> errors = LinkedListMultimap.create();
|
||||
@@ -316,7 +322,9 @@ public class ReceiveCommits {
|
||||
ReceiveConfig config,
|
||||
@Assisted final ProjectControl projectControl,
|
||||
@Assisted final Repository repo,
|
||||
final SubmoduleOp.Factory subOpFactory) throws IOException {
|
||||
final SubmoduleOp.Factory subOpFactory,
|
||||
final Provider<Submit> submitProvider,
|
||||
final MergeQueue mergeQueue) throws IOException {
|
||||
this.currentUser = (IdentifiedUser) projectControl.getCurrentUser();
|
||||
this.db = db;
|
||||
this.schemaFactory = schemaFactory;
|
||||
@@ -351,6 +359,8 @@ public class ReceiveCommits {
|
||||
this.rejectCommits = loadRejectCommitsMap();
|
||||
|
||||
this.subOpFactory = subOpFactory;
|
||||
this.submitProvider = submitProvider;
|
||||
this.mergeQueue = mergeQueue;
|
||||
|
||||
this.messageSender = new ReceivePackMessageSender();
|
||||
|
||||
@@ -1000,6 +1010,9 @@ public class ReceiveCommits {
|
||||
@Option(name = "--draft", usage = "mark new/update changes as draft")
|
||||
boolean draft;
|
||||
|
||||
@Option(name = "--submit", usage = "immediately submit the change")
|
||||
boolean submit;
|
||||
|
||||
@Option(name = "-r", metaVar = "EMAIL", usage = "add reviewer to changes")
|
||||
void reviewer(Account.Id id) {
|
||||
reviewer.add(id);
|
||||
@@ -1024,6 +1037,10 @@ public class ReceiveCommits {
|
||||
return draft;
|
||||
}
|
||||
|
||||
boolean isSubmit() {
|
||||
return submit;
|
||||
}
|
||||
|
||||
MailRecipients getMailRecipients() {
|
||||
return new MailRecipients(reviewer, cc);
|
||||
}
|
||||
@@ -1120,6 +1137,16 @@ public class ReceiveCommits {
|
||||
return;
|
||||
}
|
||||
|
||||
if (magicBranch.isDraft() && magicBranch.isSubmit()) {
|
||||
reject(cmd, "cannot submit draft");
|
||||
return;
|
||||
}
|
||||
|
||||
if (magicBranch.isSubmit() && !projectControl.controlForRef(
|
||||
MagicBranch.NEW_CHANGE + ref).canSubmit()) {
|
||||
reject(cmd, "submit not allowed");
|
||||
}
|
||||
|
||||
// Validate that the new commits are connected with the target
|
||||
// branch. If they aren't, we want to abort. We do this check by
|
||||
// looking to see if we can compute a merge base between the new
|
||||
@@ -1493,6 +1520,41 @@ public class ReceiveCommits {
|
||||
return "send-email newchange";
|
||||
}
|
||||
}));
|
||||
|
||||
if (magicBranch != null && magicBranch.isSubmit()) {
|
||||
submit(projectControl.controlFor(change), ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void submit(ChangeControl changeCtl, PatchSet ps) throws OrmException {
|
||||
Submit submit = submitProvider.get();
|
||||
RevisionResource rsrc = new RevisionResource(new ChangeResource(changeCtl), ps);
|
||||
Change c = submit.submit(rsrc, currentUser);
|
||||
if (c == null) {
|
||||
addError("Submitting change " + changeCtl.getChange().getChangeId()
|
||||
+ " failed.");
|
||||
} else {
|
||||
addMessage("");
|
||||
mergeQueue.merge(c.getDest());
|
||||
c = db.changes().get(c.getId());
|
||||
switch (c.getStatus()) {
|
||||
case SUBMITTED:
|
||||
addMessage("Change " + c.getChangeId() + " submitted.");
|
||||
break;
|
||||
case MERGED:
|
||||
addMessage("Change " + c.getChangeId() + " merged.");
|
||||
break;
|
||||
case NEW:
|
||||
ChangeMessage msg = submit.getConflictMessage(rsrc);
|
||||
if (msg != null) {
|
||||
addMessage("Change " + c.getChangeId() + ": " + msg.getMessage());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
addMessage("change " + c.getChangeId() + " is "
|
||||
+ c.getStatus().name().toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1865,6 +1927,11 @@ public class ReceiveCommits {
|
||||
return "send-email newpatchset";
|
||||
}
|
||||
}));
|
||||
|
||||
if (magicBranch != null && magicBranch.isSubmit()) {
|
||||
submit(changeCtl, newPatchSet);
|
||||
}
|
||||
|
||||
return newPatchSet.getId();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user