Merge changes I14c49cb4,I12d17fe1

* changes:
  Inject ChangeUtil, making most methods non-static
  Inject ApprovalsUtil in more places
This commit is contained in:
Shawn Pearce 2013-12-04 00:36:20 +00:00 committed by Gerrit Code Review
commit 8eb4eb75ba
15 changed files with 396 additions and 478 deletions

View File

@ -19,9 +19,6 @@ 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.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil; import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gwtjsonrpc.common.VoidResult; import com.google.gwtjsonrpc.common.VoidResult;
@ -38,39 +35,28 @@ class DeleteDraftChange extends Handler<VoidResult> {
private final ChangeControl.Factory changeControlFactory; private final ChangeControl.Factory changeControlFactory;
private final ReviewDb db; private final ReviewDb db;
private final GitRepositoryManager gitManager; private final ChangeUtil changeUtil;
private final GitReferenceUpdated gitRefUpdated;
private final ChangeIndexer indexer;
private final PatchSet.Id patchSetId; private final PatchSet.Id patchSetId;
@Inject @Inject
DeleteDraftChange(final ReviewDb db, DeleteDraftChange(ReviewDb db,
final ChangeControl.Factory changeControlFactory, ChangeControl.Factory changeControlFactory,
final GitRepositoryManager gitManager, ChangeUtil changeUtil,
final GitReferenceUpdated gitRefUpdated, @Assisted PatchSet.Id patchSetId) {
final ChangeIndexer indexer,
@Assisted final PatchSet.Id patchSetId) {
this.changeControlFactory = changeControlFactory; this.changeControlFactory = changeControlFactory;
this.db = db; this.db = db;
this.gitManager = gitManager; this.changeUtil = changeUtil;
this.gitRefUpdated = gitRefUpdated;
this.indexer = indexer;
this.patchSetId = patchSetId; this.patchSetId = patchSetId;
} }
@Override @Override
public VoidResult call() throws NoSuchChangeException, OrmException, IOException { public VoidResult call() throws NoSuchChangeException, OrmException, IOException {
Change.Id changeId = patchSetId.getParentKey();
final Change.Id changeId = patchSetId.getParentKey(); ChangeControl control = changeControlFactory.validateFor(changeId);
final ChangeControl control = changeControlFactory.validateFor(changeId);
if (!control.canDeleteDraft(db)) { if (!control.canDeleteDraft(db)) {
throw new NoSuchChangeException(changeId); throw new NoSuchChangeException(changeId);
} }
changeUtil.deleteDraftChange(patchSetId);
ChangeUtil.deleteDraftChange(patchSetId, gitManager, gitRefUpdated, db,
indexer);
return VoidResult.INSTANCE; return VoidResult.INSTANCE;
} }
} }

View File

@ -21,12 +21,9 @@ import com.google.gerrit.common.errors.NoSuchEntityException;
import com.google.gerrit.httpd.rpc.Handler; import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.client.Change; 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.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil; import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.GerritPersonIdent; import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.PatchSetInserter; import com.google.gerrit.server.change.PatchSetInserter;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.mail.CommitMessageEditedSender; import com.google.gerrit.server.mail.CommitMessageEditedSender;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException; import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.ChangeControl;
@ -39,9 +36,7 @@ import com.google.inject.assistedinject.Assisted;
import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import java.io.IOException; import java.io.IOException;
@ -51,37 +46,28 @@ class EditCommitMessageHandler extends Handler<ChangeDetail> {
} }
private final ChangeControl.Factory changeControlFactory; private final ChangeControl.Factory changeControlFactory;
private final ReviewDb db;
private final IdentifiedUser currentUser;
private final ChangeDetailFactory.Factory changeDetailFactory; private final ChangeDetailFactory.Factory changeDetailFactory;
private final CommitMessageEditedSender.Factory commitMessageEditedSenderFactory; private final ChangeUtil changeUtil;
private final PatchSet.Id patchSetId; private final PatchSet.Id patchSetId;
@Nullable @Nullable
private final String message; private final String message;
private final GitRepositoryManager gitManager;
private final PersonIdent myIdent; private final PersonIdent myIdent;
private final PatchSetInserter.Factory patchSetInserterFactory;
@Inject @Inject
EditCommitMessageHandler(final ChangeControl.Factory changeControlFactory, EditCommitMessageHandler(ChangeControl.Factory changeControlFactory,
final ReviewDb db, final IdentifiedUser currentUser, ChangeDetailFactory.Factory changeDetailFactory,
final ChangeDetailFactory.Factory changeDetailFactory, CommitMessageEditedSender.Factory commitMessageEditedSenderFactory,
final CommitMessageEditedSender.Factory commitMessageEditedSenderFactory, @Assisted PatchSet.Id patchSetId,
@Assisted final PatchSet.Id patchSetId, @Assisted @Nullable String message,
@Assisted @Nullable final String message, ChangeUtil changeUtil,
final GitRepositoryManager gitManager, @GerritPersonIdent PersonIdent myIdent,
@GerritPersonIdent final PersonIdent myIdent, PatchSetInserter.Factory patchSetInserterFactory) {
final PatchSetInserter.Factory patchSetInserterFactory) {
this.changeControlFactory = changeControlFactory; this.changeControlFactory = changeControlFactory;
this.db = db;
this.currentUser = currentUser;
this.changeDetailFactory = changeDetailFactory; this.changeDetailFactory = changeDetailFactory;
this.commitMessageEditedSenderFactory = commitMessageEditedSenderFactory; this.changeUtil = changeUtil;
this.patchSetId = patchSetId; this.patchSetId = patchSetId;
this.message = message; this.message = message;
this.gitManager = gitManager;
this.myIdent = myIdent; this.myIdent = myIdent;
this.patchSetInserterFactory = patchSetInserterFactory;
} }
@Override @Override
@ -89,27 +75,13 @@ class EditCommitMessageHandler extends Handler<ChangeDetail> {
EmailException, NoSuchEntityException, PatchSetInfoNotAvailableException, EmailException, NoSuchEntityException, PatchSetInfoNotAvailableException,
MissingObjectException, IncorrectObjectTypeException, IOException, MissingObjectException, IncorrectObjectTypeException, IOException,
InvalidChangeOperationException, NoSuchProjectException { InvalidChangeOperationException, NoSuchProjectException {
Change.Id changeId = patchSetId.getParentKey();
final Change.Id changeId = patchSetId.getParentKey(); ChangeControl control = changeControlFactory.validateFor(changeId);
final ChangeControl control = changeControlFactory.validateFor(changeId);
if (!control.canAddPatchSet()) { if (!control.canAddPatchSet()) {
throw new InvalidChangeOperationException( throw new InvalidChangeOperationException(
"Not allowed to add new Patch Sets to: " + changeId.toString()); "Not allowed to add new Patch Sets to: " + changeId.toString());
} }
changeUtil.editCommitMessage(control, patchSetId, message, myIdent);
final Repository git; return changeDetailFactory.create(changeId).call();
try {
git = gitManager.openRepository(db.changes().get(changeId).getProject());
} catch (RepositoryNotFoundException e) {
throw new NoSuchChangeException(changeId, e);
}
try {
ChangeUtil.editCommitMessage(patchSetId, control.getRefControl(),
currentUser, message, db, commitMessageEditedSenderFactory, git,
myIdent, patchSetInserterFactory);
return changeDetailFactory.create(changeId).call();
} finally {
git.close();
}
} }
} }

View File

@ -70,11 +70,11 @@ public class ApprovalsUtil {
* *
* @throws OrmException * @throws OrmException
*/ */
public static void copyLabels(ReviewDb db, LabelTypes labelTypes, public void copyLabels(LabelTypes labelTypes,
PatchSet.Id source, PatchSet dest, ChangeKind changeKind) throws OrmException { PatchSet.Id source, PatchSet dest, ChangeKind changeKind) throws OrmException {
Iterable<PatchSetApproval> sourceApprovals = Iterable<PatchSetApproval> sourceApprovals =
db.patchSetApprovals().byPatchSet(source); db.patchSetApprovals().byPatchSet(source);
copyLabels(db, labelTypes, sourceApprovals, source, dest, changeKind); copyLabels(labelTypes, sourceApprovals, source, dest, changeKind);
} }
/** /**
@ -82,7 +82,7 @@ public class ApprovalsUtil {
* *
* @throws OrmException * @throws OrmException
*/ */
public static void copyLabels(ReviewDb db, LabelTypes labelTypes, public void copyLabels(LabelTypes labelTypes,
Iterable<PatchSetApproval> sourceApprovals, PatchSet.Id source, Iterable<PatchSetApproval> sourceApprovals, PatchSet.Id source,
PatchSet dest, ChangeKind changeKind) throws OrmException { PatchSet dest, ChangeKind changeKind) throws OrmException {
List<PatchSetApproval> copied = Lists.newArrayList(); List<PatchSetApproval> copied = Lists.newArrayList();
@ -107,7 +107,7 @@ public class ApprovalsUtil {
db.patchSetApprovals().insert(copied); db.patchSetApprovals().insert(copied);
} }
public void addReviewers(ReviewDb db, LabelTypes labelTypes, Change change, public void addReviewers(LabelTypes labelTypes, Change change,
PatchSet ps, PatchSetInfo info, Set<Account.Id> wantReviewers, PatchSet ps, PatchSetInfo info, Set<Account.Id> wantReviewers,
Set<Account.Id> existingReviewers) throws OrmException { Set<Account.Id> existingReviewers) throws OrmException {
List<LabelType> allTypes = labelTypes.getLabelTypes(); List<LabelType> allTypes = labelTypes.getLabelTypes();

View File

@ -21,7 +21,6 @@ import static java.util.concurrent.TimeUnit.SECONDS;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.common.errors.EmailException; import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage; import com.google.gerrit.reviewdb.client.ChangeMessage;
@ -38,21 +37,24 @@ import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.validators.CommitValidationException; import com.google.gerrit.server.git.validators.CommitValidationException;
import com.google.gerrit.server.git.validators.CommitValidators; import com.google.gerrit.server.git.validators.CommitValidators;
import com.google.gerrit.server.index.ChangeIndexer; import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.mail.CommitMessageEditedSender;
import com.google.gerrit.server.mail.RevertedSender; import com.google.gerrit.server.mail.RevertedSender;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException; import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.InvalidChangeOperationException; import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.RefControl; import com.google.gerrit.server.project.RefControl;
import com.google.gerrit.server.ssh.SshInfo;
import com.google.gerrit.server.util.IdGenerator; import com.google.gerrit.server.util.IdGenerator;
import com.google.gerrit.server.util.MagicBranch; import com.google.gerrit.server.util.MagicBranch;
import com.google.gerrit.server.util.TimeUtil; import com.google.gerrit.server.util.TimeUtil;
import com.google.gwtorm.server.OrmConcurrencyException; import com.google.gwtorm.server.OrmConcurrencyException;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.CommitBuilder; import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ObjectInserter;
@ -118,7 +120,7 @@ public class ChangeUtil {
return u + '_' + l; return u + '_' + l;
} }
public static void touch(final Change change, ReviewDb db) public static void touch(Change change, ReviewDb db)
throws OrmException { throws OrmException {
try { try {
updated(change); updated(change);
@ -137,14 +139,14 @@ public class ChangeUtil {
} }
} }
public static void updated(final Change c) { public static void updated(Change c) {
c.setLastUpdatedOn(TimeUtil.nowTs()); c.setLastUpdatedOn(TimeUtil.nowTs());
computeSortKey(c); computeSortKey(c);
} }
public static void insertAncestors(ReviewDb db, PatchSet.Id id, RevCommit src) public static void insertAncestors(ReviewDb db, PatchSet.Id id, RevCommit src)
throws OrmException { throws OrmException {
final int cnt = src.getParentCount(); int cnt = src.getParentCount();
List<PatchSetAncestor> toInsert = new ArrayList<PatchSetAncestor>(cnt); List<PatchSetAncestor> toInsert = new ArrayList<PatchSetAncestor>(cnt);
for (int p = 0; p < cnt; p++) { for (int p = 0; p < cnt; p++) {
PatchSetAncestor a = PatchSetAncestor a =
@ -155,268 +157,7 @@ public class ChangeUtil {
db.patchSetAncestors().insert(toInsert); db.patchSetAncestors().insert(toInsert);
} }
public static Change.Id revert(RefControl refControl, PatchSet.Id patchSetId, public static String sortKey(long lastUpdatedMs, int id) {
IdentifiedUser user, CommitValidators commitValidators, String message,
ReviewDb db, RevertedSender.Factory revertedSenderFactory,
ChangeHooks hooks, Repository git,
PatchSetInfoFactory patchSetInfoFactory, PersonIdent myIdent,
ChangeInserter.Factory changeInserterFactory)
throws NoSuchChangeException, EmailException,
OrmException, MissingObjectException, IncorrectObjectTypeException,
IOException, InvalidChangeOperationException {
final Change.Id changeId = patchSetId.getParentKey();
final PatchSet patch = db.patchSets().get(patchSetId);
if (patch == null) {
throw new NoSuchChangeException(changeId);
}
final Change changeToRevert = db.changes().get(changeId);
final RevWalk revWalk = new RevWalk(git);
try {
RevCommit commitToRevert =
revWalk.parseCommit(ObjectId.fromString(patch.getRevision().get()));
PersonIdent authorIdent =
user.newCommitterIdent(myIdent.getWhen(), myIdent.getTimeZone());
RevCommit parentToCommitToRevert = commitToRevert.getParent(0);
revWalk.parseHeaders(parentToCommitToRevert);
CommitBuilder revertCommitBuilder = new CommitBuilder();
revertCommitBuilder.addParentId(commitToRevert);
revertCommitBuilder.setTreeId(parentToCommitToRevert.getTree());
revertCommitBuilder.setAuthor(authorIdent);
revertCommitBuilder.setCommitter(authorIdent);
if (message == null) {
message = MessageFormat.format(
ChangeMessages.get().revertChangeDefaultMessage,
changeToRevert.getSubject(), patch.getRevision().get());
}
final ObjectId computedChangeId =
ChangeIdUtil.computeChangeId(parentToCommitToRevert.getTree(),
commitToRevert, authorIdent, myIdent, message);
revertCommitBuilder.setMessage(ChangeIdUtil.insertId(message, computedChangeId, true));
RevCommit revertCommit;
final ObjectInserter oi = git.newObjectInserter();
try {
ObjectId id = oi.insert(revertCommitBuilder);
oi.flush();
revertCommit = revWalk.parseCommit(id);
} finally {
oi.release();
}
final Change change = new Change(
new Change.Key("I" + computedChangeId.name()),
new Change.Id(db.nextChangeId()),
user.getAccountId(),
changeToRevert.getDest(),
TimeUtil.nowTs());
change.setTopic(changeToRevert.getTopic());
ChangeInserter ins =
changeInserterFactory.create(refControl, change, revertCommit);
PatchSet ps = ins.getPatchSet();
String ref = refControl.getRefName();
final String cmdRef =
MagicBranch.NEW_PUBLISH_CHANGE
+ ref.substring(ref.lastIndexOf('/') + 1);
CommitReceivedEvent commitReceivedEvent =
new CommitReceivedEvent(new ReceiveCommand(ObjectId.zeroId(),
revertCommit.getId(), cmdRef), refControl.getProjectControl()
.getProject(), refControl.getRefName(), revertCommit, user);
try {
commitValidators.validateForGerritCommits(commitReceivedEvent);
} catch (CommitValidationException e) {
throw new InvalidChangeOperationException(e.getMessage());
}
final RefUpdate ru = git.updateRef(ps.getRefName());
ru.setExpectedOldObjectId(ObjectId.zeroId());
ru.setNewObjectId(revertCommit);
ru.disableRefLog();
if (ru.update(revWalk) != RefUpdate.Result.NEW) {
throw new IOException(String.format(
"Failed to create ref %s in %s: %s", ps.getRefName(),
change.getDest().getParentKey().get(), ru.getResult()));
}
final ChangeMessage cmsg = new ChangeMessage(
new ChangeMessage.Key(changeId, ChangeUtil.messageUUID(db)),
user.getAccountId(), TimeUtil.nowTs(), patchSetId);
final StringBuilder msgBuf =
new StringBuilder("Patch Set " + patchSetId.get() + ": Reverted");
msgBuf.append("\n\n");
msgBuf.append("This patchset was reverted in change: " + change.getKey().get());
cmsg.setMessage(msgBuf.toString());
ins.setMessage(cmsg).insert();
try {
final RevertedSender cm = revertedSenderFactory.create(change);
cm.setFrom(user.getAccountId());
cm.setChangeMessage(cmsg);
cm.send();
} catch (Exception err) {
log.error("Cannot send email for revert change " + change.getId(),
err);
}
return change.getId();
} finally {
revWalk.release();
}
}
public static Change.Id editCommitMessage(final PatchSet.Id patchSetId,
final RefControl refControl, final IdentifiedUser user,
final String message, final ReviewDb db,
final CommitMessageEditedSender.Factory commitMessageEditedSenderFactory,
Repository git, PersonIdent myIdent,
PatchSetInserter.Factory patchSetInserterFactory)
throws NoSuchChangeException, EmailException, OrmException,
MissingObjectException, IncorrectObjectTypeException, IOException,
InvalidChangeOperationException, PatchSetInfoNotAvailableException {
final Change.Id changeId = patchSetId.getParentKey();
final PatchSet originalPS = db.patchSets().get(patchSetId);
if (originalPS == null) {
throw new NoSuchChangeException(changeId);
}
if (message == null || message.length() == 0) {
throw new InvalidChangeOperationException(
"The commit message cannot be empty");
}
final RevWalk revWalk = new RevWalk(git);
try {
RevCommit commit =
revWalk.parseCommit(ObjectId.fromString(originalPS.getRevision()
.get()));
if (commit.getFullMessage().equals(message)) {
throw new InvalidChangeOperationException(
"New commit message cannot be same as existing commit message");
}
Date now = myIdent.getWhen();
Change change = db.changes().get(changeId);
PersonIdent authorIdent =
user.newCommitterIdent(now, myIdent.getTimeZone());
CommitBuilder commitBuilder = new CommitBuilder();
commitBuilder.setTreeId(commit.getTree());
commitBuilder.setParentIds(commit.getParents());
commitBuilder.setAuthor(commit.getAuthorIdent());
commitBuilder.setCommitter(authorIdent);
commitBuilder.setMessage(message);
RevCommit newCommit;
final ObjectInserter oi = git.newObjectInserter();
try {
ObjectId id = oi.insert(commitBuilder);
oi.flush();
newCommit = revWalk.parseCommit(id);
} finally {
oi.release();
}
PatchSet.Id id = nextPatchSetId(git, change.currentPatchSetId());
final PatchSet newPatchSet = new PatchSet(id);
newPatchSet.setCreatedOn(new Timestamp(now.getTime()));
newPatchSet.setUploader(user.getAccountId());
newPatchSet.setRevision(new RevId(newCommit.name()));
final String msg =
"Patch Set " + newPatchSet.getPatchSetId()
+ ": Commit message was updated";
change = patchSetInserterFactory
.create(git, revWalk, refControl, user, change, newCommit)
.setPatchSet(newPatchSet)
.setMessage(msg)
.setCopyLabels(true)
.setValidatePolicy(RECEIVE_COMMITS)
.setDraft(originalPS.isDraft())
.insert();
return change.getId();
} finally {
revWalk.release();
}
}
public static void deleteDraftChange(PatchSet.Id patchSetId,
GitRepositoryManager gitManager,
GitReferenceUpdated gitRefUpdated, ReviewDb db, ChangeIndexer indexer)
throws NoSuchChangeException, OrmException, IOException {
final Change.Id changeId = patchSetId.getParentKey();
deleteDraftChange(changeId, gitManager, gitRefUpdated, db, indexer);
}
public static void deleteDraftChange(Change.Id changeId,
GitRepositoryManager gitManager,
GitReferenceUpdated gitRefUpdated, ReviewDb db, ChangeIndexer indexer)
throws NoSuchChangeException, OrmException, IOException {
Change change = db.changes().get(changeId);
if (change == null || change.getStatus() != Change.Status.DRAFT) {
throw new NoSuchChangeException(changeId);
}
for (PatchSet ps : db.patchSets().byChange(changeId)) {
// These should all be draft patch sets.
deleteOnlyDraftPatchSet(ps, change, gitManager, gitRefUpdated, db);
}
db.changeMessages().delete(db.changeMessages().byChange(changeId));
db.starredChanges().delete(db.starredChanges().byChange(changeId));
db.changes().delete(Collections.singleton(change));
indexer.delete(change);
}
public static void deleteOnlyDraftPatchSet(final PatchSet patch,
final Change change, GitRepositoryManager gitManager,
final GitReferenceUpdated gitRefUpdated, final ReviewDb db)
throws NoSuchChangeException, OrmException, IOException {
final PatchSet.Id patchSetId = patch.getId();
if (!patch.isDraft()) {
throw new NoSuchChangeException(patchSetId.getParentKey());
}
Repository repo = gitManager.openRepository(change.getProject());
try {
RefUpdate update = repo.updateRef(patch.getRefName());
update.setForceUpdate(true);
update.disableRefLog();
switch (update.delete()) {
case NEW:
case FAST_FORWARD:
case FORCED:
case NO_CHANGE:
// Successful deletion.
break;
default:
throw new IOException("Failed to delete ref " + patch.getRefName() +
" in " + repo.getDirectory() + ": " + update.getResult());
}
gitRefUpdated.fire(change.getProject(), update);
} finally {
repo.close();
}
db.accountPatchReviews().delete(db.accountPatchReviews().byPatchSet(patchSetId));
db.changeMessages().delete(db.changeMessages().byPatchSet(patchSetId));
db.patchComments().delete(db.patchComments().byPatchSet(patchSetId));
db.patchSetApprovals().delete(db.patchSetApprovals().byPatchSet(patchSetId));
db.patchSetAncestors().delete(db.patchSetAncestors().byPatchSet(patchSetId));
db.patchSets().delete(Collections.singleton(patch));
}
public static String sortKey(long lastUpdatedMs, int id){
long lastUpdatedMins = MINUTES.convert(lastUpdatedMs, MILLISECONDS); long lastUpdatedMins = MINUTES.convert(lastUpdatedMs, MILLISECONDS);
long minsSinceEpoch = lastUpdatedMins - SORT_KEY_EPOCH_MINS; long minsSinceEpoch = lastUpdatedMins - SORT_KEY_EPOCH_MINS;
StringBuilder r = new StringBuilder(16); StringBuilder r = new StringBuilder(16);
@ -453,6 +194,310 @@ public class ChangeUtil {
return nextPatchSetId(git.getRefDatabase().getRefs(RefDatabase.ALL), id); return nextPatchSetId(git.getRefDatabase().getRefs(RefDatabase.ALL), id);
} }
private final Provider<CurrentUser> userProvider;
private final CommitValidators.Factory commitValidatorsFactory;
private final Provider<ReviewDb> db;
private final RevertedSender.Factory revertedSenderFactory;
private final ChangeInserter.Factory changeInserterFactory;
private final PatchSetInserter.Factory patchSetInserterFactory;
private final GitRepositoryManager gitManager;
private final GitReferenceUpdated gitRefUpdated;
private final ChangeIndexer indexer;
@Inject
ChangeUtil(Provider<CurrentUser> userProvider,
CommitValidators.Factory commitValidatorsFactory,
Provider<ReviewDb> db,
RevertedSender.Factory revertedSenderFactory,
ChangeInserter.Factory changeInserterFactory,
PatchSetInserter.Factory patchSetInserterFactory,
GitRepositoryManager gitManager,
GitReferenceUpdated gitRefUpdated,
ChangeIndexer indexer) {
this.userProvider = userProvider;
this.commitValidatorsFactory = commitValidatorsFactory;
this.db = db;
this.revertedSenderFactory = revertedSenderFactory;
this.changeInserterFactory = changeInserterFactory;
this.patchSetInserterFactory = patchSetInserterFactory;
this.gitManager = gitManager;
this.gitRefUpdated = gitRefUpdated;
this.indexer = indexer;
}
public Change.Id revert(ChangeControl ctl, PatchSet.Id patchSetId,
String message, PersonIdent myIdent, SshInfo sshInfo)
throws NoSuchChangeException, EmailException, OrmException,
MissingObjectException, IncorrectObjectTypeException, IOException,
InvalidChangeOperationException {
Change.Id changeId = patchSetId.getParentKey();
PatchSet patch = db.get().patchSets().get(patchSetId);
if (patch == null) {
throw new NoSuchChangeException(changeId);
}
Change changeToRevert = db.get().changes().get(changeId);
Repository git;
try {
git = gitManager.openRepository(ctl.getChange().getProject());
} catch (RepositoryNotFoundException e) {
throw new NoSuchChangeException(changeId, e);
}
try {
RevWalk revWalk = new RevWalk(git);
try {
RevCommit commitToRevert =
revWalk.parseCommit(ObjectId.fromString(patch.getRevision().get()));
PersonIdent authorIdent =
user().newCommitterIdent(myIdent.getWhen(), myIdent.getTimeZone());
RevCommit parentToCommitToRevert = commitToRevert.getParent(0);
revWalk.parseHeaders(parentToCommitToRevert);
CommitBuilder revertCommitBuilder = new CommitBuilder();
revertCommitBuilder.addParentId(commitToRevert);
revertCommitBuilder.setTreeId(parentToCommitToRevert.getTree());
revertCommitBuilder.setAuthor(authorIdent);
revertCommitBuilder.setCommitter(authorIdent);
if (message == null) {
message = MessageFormat.format(
ChangeMessages.get().revertChangeDefaultMessage,
changeToRevert.getSubject(), patch.getRevision().get());
}
ObjectId computedChangeId =
ChangeIdUtil.computeChangeId(parentToCommitToRevert.getTree(),
commitToRevert, authorIdent, myIdent, message);
revertCommitBuilder.setMessage(
ChangeIdUtil.insertId(message, computedChangeId, true));
RevCommit revertCommit;
ObjectInserter oi = git.newObjectInserter();
try {
ObjectId id = oi.insert(revertCommitBuilder);
oi.flush();
revertCommit = revWalk.parseCommit(id);
} finally {
oi.release();
}
RefControl refControl = ctl.getRefControl();
Change change = new Change(
new Change.Key("I" + computedChangeId.name()),
new Change.Id(db.get().nextChangeId()),
user().getAccountId(),
changeToRevert.getDest(),
TimeUtil.nowTs());
change.setTopic(changeToRevert.getTopic());
ChangeInserter ins =
changeInserterFactory.create(refControl, change, revertCommit);
PatchSet ps = ins.getPatchSet();
String ref = refControl.getRefName();
String cmdRef = MagicBranch.NEW_PUBLISH_CHANGE
+ ref.substring(ref.lastIndexOf('/') + 1);
CommitReceivedEvent commitReceivedEvent = new CommitReceivedEvent(
new ReceiveCommand(ObjectId.zeroId(), revertCommit.getId(), cmdRef),
refControl.getProjectControl().getProject(),
refControl.getRefName(), revertCommit, user());
try {
commitValidatorsFactory.create(refControl, sshInfo, git)
.validateForGerritCommits(commitReceivedEvent);
} catch (CommitValidationException e) {
throw new InvalidChangeOperationException(e.getMessage());
}
RefUpdate ru = git.updateRef(ps.getRefName());
ru.setExpectedOldObjectId(ObjectId.zeroId());
ru.setNewObjectId(revertCommit);
ru.disableRefLog();
if (ru.update(revWalk) != RefUpdate.Result.NEW) {
throw new IOException(String.format(
"Failed to create ref %s in %s: %s", ps.getRefName(),
change.getDest().getParentKey().get(), ru.getResult()));
}
ChangeMessage cmsg = new ChangeMessage(
new ChangeMessage.Key(changeId, messageUUID(db.get())),
user().getAccountId(), TimeUtil.nowTs(), patchSetId);
StringBuilder msgBuf =
new StringBuilder("Patch Set " + patchSetId.get() + ": Reverted");
msgBuf.append("\n\n");
msgBuf.append("This patchset was reverted in change: " + change.getKey().get());
cmsg.setMessage(msgBuf.toString());
ins.setMessage(cmsg).insert();
try {
RevertedSender cm = revertedSenderFactory.create(change);
cm.setFrom(user().getAccountId());
cm.setChangeMessage(cmsg);
cm.send();
} catch (Exception err) {
log.error("Cannot send email for revert change " + change.getId(),
err);
}
return change.getId();
} finally {
revWalk.release();
}
} finally {
git.close();
}
}
public Change.Id editCommitMessage(ChangeControl ctl, PatchSet.Id patchSetId,
String message, PersonIdent myIdent)
throws NoSuchChangeException, EmailException, OrmException,
MissingObjectException, IncorrectObjectTypeException, IOException,
InvalidChangeOperationException, PatchSetInfoNotAvailableException {
Change.Id changeId = patchSetId.getParentKey();
PatchSet originalPS = db.get().patchSets().get(patchSetId);
if (originalPS == null) {
throw new NoSuchChangeException(changeId);
}
if (message == null || message.length() == 0) {
throw new InvalidChangeOperationException(
"The commit message cannot be empty");
}
Repository git;
try {
git = gitManager.openRepository(ctl.getChange().getProject());
} catch (RepositoryNotFoundException e) {
throw new NoSuchChangeException(changeId, e);
}
try {
RevWalk revWalk = new RevWalk(git);
try {
RevCommit commit =
revWalk.parseCommit(ObjectId.fromString(originalPS.getRevision()
.get()));
if (commit.getFullMessage().equals(message)) {
throw new InvalidChangeOperationException(
"New commit message cannot be same as existing commit message");
}
Date now = myIdent.getWhen();
Change change = db.get().changes().get(changeId);
PersonIdent authorIdent =
user().newCommitterIdent(now, myIdent.getTimeZone());
CommitBuilder commitBuilder = new CommitBuilder();
commitBuilder.setTreeId(commit.getTree());
commitBuilder.setParentIds(commit.getParents());
commitBuilder.setAuthor(commit.getAuthorIdent());
commitBuilder.setCommitter(authorIdent);
commitBuilder.setMessage(message);
RevCommit newCommit;
ObjectInserter oi = git.newObjectInserter();
try {
ObjectId id = oi.insert(commitBuilder);
oi.flush();
newCommit = revWalk.parseCommit(id);
} finally {
oi.release();
}
PatchSet.Id id = nextPatchSetId(git, change.currentPatchSetId());
PatchSet newPatchSet = new PatchSet(id);
newPatchSet.setCreatedOn(new Timestamp(now.getTime()));
newPatchSet.setUploader(user().getAccountId());
newPatchSet.setRevision(new RevId(newCommit.name()));
String msg = "Patch Set " + newPatchSet.getPatchSetId()
+ ": Commit message was updated";
change = patchSetInserterFactory
.create(git, revWalk, ctl.getRefControl(), user(), change, newCommit)
.setPatchSet(newPatchSet)
.setMessage(msg)
.setCopyLabels(true)
.setValidatePolicy(RECEIVE_COMMITS)
.setDraft(originalPS.isDraft())
.insert();
return change.getId();
} finally {
revWalk.release();
}
} finally {
git.close();
}
}
public void deleteDraftChange(PatchSet.Id patchSetId)
throws NoSuchChangeException, OrmException, IOException {
deleteDraftChange(patchSetId.getParentKey());
}
public void deleteDraftChange(Change.Id changeId)
throws NoSuchChangeException, OrmException, IOException {
ReviewDb db = this.db.get();
Change change = db.changes().get(changeId);
if (change == null || change.getStatus() != Change.Status.DRAFT) {
throw new NoSuchChangeException(changeId);
}
for (PatchSet ps : db.patchSets().byChange(changeId)) {
// These should all be draft patch sets.
deleteOnlyDraftPatchSet(ps, change);
}
db.changeMessages().delete(db.changeMessages().byChange(changeId));
db.starredChanges().delete(db.starredChanges().byChange(changeId));
db.changes().delete(Collections.singleton(change));
indexer.delete(change);
}
public void deleteOnlyDraftPatchSet(PatchSet patch, Change change)
throws NoSuchChangeException, OrmException, IOException {
PatchSet.Id patchSetId = patch.getId();
if (!patch.isDraft()) {
throw new NoSuchChangeException(patchSetId.getParentKey());
}
Repository repo = gitManager.openRepository(change.getProject());
try {
RefUpdate update = repo.updateRef(patch.getRefName());
update.setForceUpdate(true);
update.disableRefLog();
switch (update.delete()) {
case NEW:
case FAST_FORWARD:
case FORCED:
case NO_CHANGE:
// Successful deletion.
break;
default:
throw new IOException("Failed to delete ref " + patch.getRefName() +
" in " + repo.getDirectory() + ": " + update.getResult());
}
gitRefUpdated.fire(change.getProject(), update);
} finally {
repo.close();
}
ReviewDb db = this.db.get();
db.accountPatchReviews().delete(db.accountPatchReviews().byPatchSet(patchSetId));
db.changeMessages().delete(db.changeMessages().byPatchSet(patchSetId));
db.patchComments().delete(db.patchComments().byPatchSet(patchSetId));
db.patchSetApprovals().delete(db.patchSetApprovals().byPatchSet(patchSetId));
db.patchSetAncestors().delete(db.patchSetAncestors().byPatchSet(patchSetId));
db.patchSets().delete(Collections.singleton(patch));
}
private IdentifiedUser user() {
return (IdentifiedUser) userProvider.get();
}
private static PatchSet.Id nextPatchSetId(PatchSet.Id id) { private static PatchSet.Id nextPatchSetId(PatchSet.Id id) {
return new PatchSet.Id(id.getParentKey(), id.get() + 1); return new PatchSet.Id(id.getParentKey(), id.get() + 1);
} }

View File

@ -51,6 +51,7 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
private final ChangeHooks hooks; private final ChangeHooks hooks;
private final AbandonedSender.Factory abandonedSenderFactory; private final AbandonedSender.Factory abandonedSenderFactory;
private final Provider<ReviewDb> dbProvider; private final Provider<ReviewDb> dbProvider;
private final Provider<ApprovalsUtil> approvals;
private final ChangeJson json; private final ChangeJson json;
private final ChangeIndexer indexer; private final ChangeIndexer indexer;
@ -58,11 +59,13 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
Abandon(ChangeHooks hooks, Abandon(ChangeHooks hooks,
AbandonedSender.Factory abandonedSenderFactory, AbandonedSender.Factory abandonedSenderFactory,
Provider<ReviewDb> dbProvider, Provider<ReviewDb> dbProvider,
Provider<ApprovalsUtil> approvals,
ChangeJson json, ChangeJson json,
ChangeIndexer indexer) { ChangeIndexer indexer) {
this.hooks = hooks; this.hooks = hooks;
this.abandonedSenderFactory = abandonedSenderFactory; this.abandonedSenderFactory = abandonedSenderFactory;
this.dbProvider = dbProvider; this.dbProvider = dbProvider;
this.approvals = approvals;
this.json = json; this.json = json;
this.indexer = indexer; this.indexer = indexer;
} }
@ -103,7 +106,7 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
} }
message = newMessage(input, caller, change); message = newMessage(input, caller, change);
db.changeMessages().insert(Collections.singleton(message)); db.changeMessages().insert(Collections.singleton(message));
new ApprovalsUtil(db).syncChangeStatus(change); approvals.get().syncChangeStatus(change);
db.commit(); db.commit();
} finally { } finally {
db.rollback(); db.rollback();

View File

@ -75,6 +75,7 @@ public class ChangeInserter {
@Inject @Inject
ChangeInserter(Provider<ReviewDb> dbProvider, ChangeInserter(Provider<ReviewDb> dbProvider,
Provider<ApprovalsUtil> approvals,
PatchSetInfoFactory patchSetInfoFactory, PatchSetInfoFactory patchSetInfoFactory,
GitReferenceUpdated gitRefUpdated, GitReferenceUpdated gitRefUpdated,
ChangeHooks hooks, ChangeHooks hooks,
@ -159,7 +160,7 @@ public class ChangeInserter {
db.patchSets().insert(Collections.singleton(patchSet)); db.patchSets().insert(Collections.singleton(patchSet));
db.changes().insert(Collections.singleton(change)); db.changes().insert(Collections.singleton(change));
LabelTypes labelTypes = refControl.getProjectControl().getLabelTypes(); LabelTypes labelTypes = refControl.getProjectControl().getLabelTypes();
approvalsUtil.addReviewers(db, labelTypes, change, patchSet, patchSetInfo, approvalsUtil.addReviewers(labelTypes, change, patchSet, patchSetInfo,
reviewers, Collections.<Account.Id> emptySet()); reviewers, Collections.<Account.Id> emptySet());
db.commit(); db.commit();
} finally { } finally {

View File

@ -24,9 +24,6 @@ import com.google.gerrit.reviewdb.client.Change.Status;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil; import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.change.DeleteDraftChange.Input; import com.google.gerrit.server.change.DeleteDraftChange.Input;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.patch.PatchSetInfoFactory; import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@ -41,20 +38,14 @@ public class DeleteDraftChange implements
} }
protected final Provider<ReviewDb> dbProvider; protected final Provider<ReviewDb> dbProvider;
private final GitRepositoryManager gitManager; private final ChangeUtil changeUtil;
private final GitReferenceUpdated gitRefUpdated;
private final ChangeIndexer indexer;
@Inject @Inject
public DeleteDraftChange(Provider<ReviewDb> dbProvider, public DeleteDraftChange(Provider<ReviewDb> dbProvider,
GitRepositoryManager gitManager,
GitReferenceUpdated gitRefUpdated,
PatchSetInfoFactory patchSetInfoFactory, PatchSetInfoFactory patchSetInfoFactory,
ChangeIndexer indexer) { ChangeUtil changeUtil) {
this.dbProvider = dbProvider; this.dbProvider = dbProvider;
this.gitManager = gitManager; this.changeUtil = changeUtil;
this.gitRefUpdated = gitRefUpdated;
this.indexer = indexer;
} }
@Override @Override
@ -70,8 +61,7 @@ public class DeleteDraftChange implements
} }
try { try {
ChangeUtil.deleteDraftChange(rsrc.getChange().getId(), changeUtil.deleteDraftChange(rsrc.getChange().getId());
gitManager, gitRefUpdated, dbProvider.get(), indexer);
} catch (NoSuchChangeException e) { } catch (NoSuchChangeException e) {
throw new ResourceNotFoundException(e.getMessage()); throw new ResourceNotFoundException(e.getMessage());
} }

View File

@ -26,9 +26,6 @@ import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil; import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.change.DeleteDraftPatchSet.Input; import com.google.gerrit.server.change.DeleteDraftPatchSet.Input;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.patch.PatchSetInfoFactory; import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException; import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
@ -45,22 +42,16 @@ public class DeleteDraftPatchSet implements RestModifyView<RevisionResource, Inp
} }
protected final Provider<ReviewDb> dbProvider; protected final Provider<ReviewDb> dbProvider;
private final GitRepositoryManager gitManager;
private final GitReferenceUpdated gitRefUpdated;
private final PatchSetInfoFactory patchSetInfoFactory; private final PatchSetInfoFactory patchSetInfoFactory;
private final ChangeIndexer indexer; private final ChangeUtil changeUtil;
@Inject @Inject
public DeleteDraftPatchSet(Provider<ReviewDb> dbProvider, public DeleteDraftPatchSet(Provider<ReviewDb> dbProvider,
GitRepositoryManager gitManager,
GitReferenceUpdated gitRefUpdated,
PatchSetInfoFactory patchSetInfoFactory, PatchSetInfoFactory patchSetInfoFactory,
ChangeIndexer indexer) { ChangeUtil changeUtil) {
this.dbProvider = dbProvider; this.dbProvider = dbProvider;
this.gitManager = gitManager;
this.gitRefUpdated = gitRefUpdated;
this.patchSetInfoFactory = patchSetInfoFactory; this.patchSetInfoFactory = patchSetInfoFactory;
this.indexer = indexer; this.changeUtil = changeUtil;
} }
@Override @Override
@ -104,8 +95,7 @@ public class DeleteDraftPatchSet implements RestModifyView<RevisionResource, Inp
private void deleteDraftPatchSet(PatchSet patchSet, Change change) private void deleteDraftPatchSet(PatchSet patchSet, Change change)
throws ResourceNotFoundException, OrmException, IOException { throws ResourceNotFoundException, OrmException, IOException {
try { try {
ChangeUtil.deleteOnlyDraftPatchSet(patchSet, changeUtil.deleteOnlyDraftPatchSet(patchSet, change);
change, gitManager, gitRefUpdated, dbProvider.get());
} catch (NoSuchChangeException e) { } catch (NoSuchChangeException e) {
throw new ResourceNotFoundException(e.getMessage()); throw new ResourceNotFoundException(e.getMessage());
} }
@ -130,8 +120,7 @@ public class DeleteDraftPatchSet implements RestModifyView<RevisionResource, Inp
private void deleteDraftChange(PatchSet.Id patchSetId) private void deleteDraftChange(PatchSet.Id patchSetId)
throws OrmException, IOException, ResourceNotFoundException { throws OrmException, IOException, ResourceNotFoundException {
try { try {
ChangeUtil.deleteDraftChange(patchSetId, changeUtil.deleteDraftChange(patchSetId);
gitManager, gitRefUpdated, dbProvider.get(), indexer);
} catch (NoSuchChangeException e) { } catch (NoSuchChangeException e) {
throw new ResourceNotFoundException(e.getMessage()); throw new ResourceNotFoundException(e.getMessage());
} }

View File

@ -23,37 +23,26 @@ import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestModifyView; import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.webui.UiAction; import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil; import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.GerritPersonIdent; import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.ChangeJson.ChangeInfo; import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
import com.google.gerrit.server.change.EditMessage.Input; import com.google.gerrit.server.change.EditMessage.Input;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.mail.CommitMessageEditedSender;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException; import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.InvalidChangeOperationException; import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import java.io.IOException; import java.io.IOException;
class EditMessage implements RestModifyView<RevisionResource, Input>, class EditMessage implements RestModifyView<RevisionResource, Input>,
UiAction<RevisionResource> { UiAction<RevisionResource> {
private final ChangeUtil changeUtil;
private final Provider<ReviewDb> dbProvider;
private final CommitMessageEditedSender.Factory commitMessageEditedSenderFactory;
private final GitRepositoryManager gitManager;
private final PersonIdent myIdent; private final PersonIdent myIdent;
private final PatchSetInserter.Factory patchSetInserterFactory;
private final ChangeJson json; private final ChangeJson json;
static class Input { static class Input {
@ -62,17 +51,11 @@ class EditMessage implements RestModifyView<RevisionResource, Input>,
} }
@Inject @Inject
EditMessage(final Provider<ReviewDb> dbProvider, EditMessage(ChangeUtil changeUtil,
final CommitMessageEditedSender.Factory commitMessageEditedSenderFactory, @GerritPersonIdent PersonIdent myIdent,
final GitRepositoryManager gitManager,
final PatchSetInserter.Factory patchSetInserterFactory,
@GerritPersonIdent final PersonIdent myIdent,
ChangeJson json) { ChangeJson json) {
this.dbProvider = dbProvider; this.changeUtil = changeUtil;
this.commitMessageEditedSenderFactory = commitMessageEditedSenderFactory;
this.gitManager = gitManager;
this.myIdent = myIdent; this.myIdent = myIdent;
this.patchSetInserterFactory = patchSetInserterFactory;
this.json = json; this.json = json;
} }
@ -83,22 +66,12 @@ class EditMessage implements RestModifyView<RevisionResource, Input>,
if (Strings.isNullOrEmpty(input.message)) { if (Strings.isNullOrEmpty(input.message)) {
throw new BadRequestException("message must be non-empty"); throw new BadRequestException("message must be non-empty");
} }
final Repository git;
try { try {
git = gitManager.openRepository(rsrc.getChange().getProject()); return json.format(changeUtil.editCommitMessage(
} catch (RepositoryNotFoundException e) { rsrc.getControl(),
throw new ResourceNotFoundException(e.getMessage());
}
try {
return json.format(ChangeUtil.editCommitMessage(
rsrc.getPatchSet().getId(), rsrc.getPatchSet().getId(),
rsrc.getControl().getRefControl(), input.message,
(IdentifiedUser) rsrc.getControl().getCurrentUser(), myIdent));
input.message, dbProvider.get(),
commitMessageEditedSenderFactory, git, myIdent,
patchSetInserterFactory));
} catch (InvalidChangeOperationException e) { } catch (InvalidChangeOperationException e) {
throw new BadRequestException(e.getMessage()); throw new BadRequestException(e.getMessage());
} catch (NoSuchChangeException e) { } catch (NoSuchChangeException e) {
@ -106,8 +79,6 @@ class EditMessage implements RestModifyView<RevisionResource, Input>,
} catch (MissingObjectException | IncorrectObjectTypeException } catch (MissingObjectException | IncorrectObjectTypeException
| PatchSetInfoNotAvailableException e) { | PatchSetInfoNotAvailableException e) {
throw new ResourceConflictException(e.getMessage()); throw new ResourceConflictException(e.getMessage());
} finally {
git.close();
} }
} }

View File

@ -95,6 +95,7 @@ public class PatchSetInserter {
private final MergeabilityChecker mergeabilityChecker; private final MergeabilityChecker mergeabilityChecker;
private final ReplacePatchSetSender.Factory replacePatchSetFactory; private final ReplacePatchSetSender.Factory replacePatchSetFactory;
private final MergeUtil.Factory mergeUtilFactory; private final MergeUtil.Factory mergeUtilFactory;
private final ApprovalsUtil approvalsUtil;
private final Repository git; private final Repository git;
private final RevWalk revWalk; private final RevWalk revWalk;
@ -120,6 +121,7 @@ public class PatchSetInserter {
MergeabilityChecker mergeabilityChecker, MergeabilityChecker mergeabilityChecker,
ReplacePatchSetSender.Factory replacePatchSetFactory, ReplacePatchSetSender.Factory replacePatchSetFactory,
MergeUtil.Factory mergeUtilFactory, MergeUtil.Factory mergeUtilFactory,
ApprovalsUtil approvalsUtil,
@Assisted Repository git, @Assisted Repository git,
@Assisted RevWalk revWalk, @Assisted RevWalk revWalk,
@Assisted RefControl refControl, @Assisted RefControl refControl,
@ -135,6 +137,7 @@ public class PatchSetInserter {
this.mergeabilityChecker = mergeabilityChecker; this.mergeabilityChecker = mergeabilityChecker;
this.replacePatchSetFactory = replacePatchSetFactory; this.replacePatchSetFactory = replacePatchSetFactory;
this.mergeUtilFactory = mergeUtilFactory; this.mergeUtilFactory = mergeUtilFactory;
this.approvalsUtil = approvalsUtil;
this.git = git; this.git = git;
this.revWalk = revWalk; this.revWalk = revWalk;
@ -279,7 +282,7 @@ public class PatchSetInserter {
ChangeKind changeKind = ChangeKind changeKind =
getChangeKind(mergeUtilFactory, projectState, git, priorCommit, commit); getChangeKind(mergeUtilFactory, projectState, git, priorCommit, commit);
ApprovalsUtil.copyLabels(db, refControl.getProjectControl() approvalsUtil.copyLabels(refControl.getProjectControl()
.getLabelTypes(), currentPatchSetId, patchSet, changeKind); .getLabelTypes(), currentPatchSetId, patchSet, changeKind);
} }
db.commit(); db.commit();

View File

@ -52,6 +52,7 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
private final ChangeHooks hooks; private final ChangeHooks hooks;
private final RestoredSender.Factory restoredSenderFactory; private final RestoredSender.Factory restoredSenderFactory;
private final Provider<ReviewDb> dbProvider; private final Provider<ReviewDb> dbProvider;
private final Provider<ApprovalsUtil> approvals;
private final ChangeJson json; private final ChangeJson json;
private final ChangeIndexer indexer; private final ChangeIndexer indexer;
@ -59,11 +60,13 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
Restore(ChangeHooks hooks, Restore(ChangeHooks hooks,
RestoredSender.Factory restoredSenderFactory, RestoredSender.Factory restoredSenderFactory,
Provider<ReviewDb> dbProvider, Provider<ReviewDb> dbProvider,
Provider<ApprovalsUtil> approvals,
ChangeJson json, ChangeJson json,
ChangeIndexer indexer) { ChangeIndexer indexer) {
this.hooks = hooks; this.hooks = hooks;
this.restoredSenderFactory = restoredSenderFactory; this.restoredSenderFactory = restoredSenderFactory;
this.dbProvider = dbProvider; this.dbProvider = dbProvider;
this.approvals = approvals;
this.json = json; this.json = json;
this.indexer = indexer; this.indexer = indexer;
} }
@ -104,7 +107,7 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
} }
message = newMessage(input, caller, change); message = newMessage(input, caller, change);
db.changeMessages().insert(Collections.singleton(message)); db.changeMessages().insert(Collections.singleton(message));
new ApprovalsUtil(db).syncChangeStatus(change); approvals.get().syncChangeStatus(change);
db.commit(); db.commit();
} finally { } finally {
db.rollback(); db.rollback();

View File

@ -15,7 +15,6 @@
package com.google.gerrit.server.change; package com.google.gerrit.server.change;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.common.errors.EmailException; import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.extensions.api.changes.RevertInput; import com.google.gerrit.extensions.api.changes.RevertInput;
import com.google.gerrit.extensions.restapi.AuthException; import com.google.gerrit.extensions.restapi.AuthException;
@ -26,59 +25,33 @@ import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.webui.UiAction; import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Change.Status; import com.google.gerrit.reviewdb.client.Change.Status;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil; import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.GerritPersonIdent; import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.ChangeJson.ChangeInfo; import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.validators.CommitValidators;
import com.google.gerrit.server.mail.RevertedSender;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.InvalidChangeOperationException; import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.ssh.NoSshInfo; import com.google.gerrit.server.ssh.NoSshInfo;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import java.io.IOException; import java.io.IOException;
public class Revert implements RestModifyView<ChangeResource, RevertInput>, public class Revert implements RestModifyView<ChangeResource, RevertInput>,
UiAction<ChangeResource> { UiAction<ChangeResource> {
private final ChangeHooks hooks;
private final RevertedSender.Factory revertedSenderFactory;
private final CommitValidators.Factory commitValidatorsFactory;
private final Provider<ReviewDb> dbProvider;
private final ChangeJson json; private final ChangeJson json;
private final GitRepositoryManager gitManager; private final ChangeUtil changeUtil;
private final PersonIdent myIdent; private final PersonIdent myIdent;
private final PatchSetInfoFactory patchSetInfoFactory;
private final ChangeInserter.Factory changeInserterFactory;
@Inject @Inject
Revert(ChangeHooks hooks, Revert(ChangeJson json,
RevertedSender.Factory revertedSenderFactory, ChangeUtil changeUtil,
final CommitValidators.Factory commitValidatorsFactory, @GerritPersonIdent PersonIdent myIdent) {
Provider<ReviewDb> dbProvider,
ChangeJson json,
GitRepositoryManager gitManager,
final PatchSetInfoFactory patchSetInfoFactory,
@GerritPersonIdent final PersonIdent myIdent,
final ChangeInserter.Factory changeInserterFactory) {
this.hooks = hooks;
this.revertedSenderFactory = revertedSenderFactory;
this.commitValidatorsFactory = commitValidatorsFactory;
this.dbProvider = dbProvider;
this.json = json; this.json = json;
this.gitManager = gitManager; this.changeUtil = changeUtil;
this.myIdent = myIdent; this.myIdent = myIdent;
this.changeInserterFactory = changeInserterFactory;
this.patchSetInfoFactory = patchSetInfoFactory;
} }
@Override @Override
@ -93,26 +66,17 @@ public class Revert implements RestModifyView<ChangeResource, RevertInput>,
throw new ResourceConflictException("change is " + status(change)); throw new ResourceConflictException("change is " + status(change));
} }
final Repository git = gitManager.openRepository(control.getProject().getNameKey());
try { try {
CommitValidators commitValidators =
commitValidatorsFactory.create(control.getRefControl(), new NoSshInfo(), git);
Change.Id revertedChangeId = Change.Id revertedChangeId =
ChangeUtil.revert(control.getRefControl(), change.currentPatchSetId(), changeUtil.revert(control, change.currentPatchSetId(),
(IdentifiedUser) control.getCurrentUser(), Strings.emptyToNull(input.message),
commitValidators, myIdent, new NoSshInfo());
Strings.emptyToNull(input.message), dbProvider.get(),
revertedSenderFactory, hooks, git, patchSetInfoFactory,
myIdent, changeInserterFactory);
return json.format(revertedChangeId); return json.format(revertedChangeId);
} catch (InvalidChangeOperationException e) { } catch (InvalidChangeOperationException e) {
throw new BadRequestException(e.getMessage()); throw new BadRequestException(e.getMessage());
} catch (NoSuchChangeException e) { } catch (NoSuchChangeException e) {
throw new ResourceNotFoundException(e.getMessage()); throw new ResourceNotFoundException(e.getMessage());
} finally {
git.close();
} }
} }

View File

@ -20,8 +20,6 @@ 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.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil; import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.ChangeIndexer; import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.patch.PatchSetInfoFactory; import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException; import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
@ -37,44 +35,38 @@ import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
public class DeleteDraftPatchSet implements Callable<ReviewResult> { public class DeleteDraftPatchSet implements Callable<ReviewResult> {
public interface Factory { public interface Factory {
DeleteDraftPatchSet create(PatchSet.Id patchSetId); DeleteDraftPatchSet create(PatchSet.Id patchSetId);
} }
private final ChangeControl.Factory changeControlFactory; private final ChangeControl.Factory changeControlFactory;
private final ReviewDb db; private final ReviewDb db;
private final GitRepositoryManager gitManager;
private final GitReferenceUpdated gitRefUpdated;
private final PatchSetInfoFactory patchSetInfoFactory; private final PatchSetInfoFactory patchSetInfoFactory;
private final ChangeIndexer indexer; private final ChangeUtil changeUtil;
private final PatchSet.Id patchSetId; private final PatchSet.Id patchSetId;
@Inject @Inject
DeleteDraftPatchSet(ChangeControl.Factory changeControlFactory, DeleteDraftPatchSet(ChangeControl.Factory changeControlFactory,
ReviewDb db, GitRepositoryManager gitManager, ReviewDb db,
GitReferenceUpdated gitRefUpdated, PatchSetInfoFactory patchSetInfoFactory, PatchSetInfoFactory patchSetInfoFactory,
ChangeIndexer indexer, ChangeIndexer indexer,
@Assisted final PatchSet.Id patchSetId) { ChangeUtil changeUtil,
@Assisted PatchSet.Id patchSetId) {
this.changeControlFactory = changeControlFactory; this.changeControlFactory = changeControlFactory;
this.db = db; this.db = db;
this.gitManager = gitManager;
this.gitRefUpdated = gitRefUpdated;
this.patchSetInfoFactory = patchSetInfoFactory; this.patchSetInfoFactory = patchSetInfoFactory;
this.indexer = indexer; this.changeUtil = changeUtil;
this.patchSetId = patchSetId; this.patchSetId = patchSetId;
} }
@Override @Override
public ReviewResult call() throws NoSuchChangeException, OrmException { public ReviewResult call() throws NoSuchChangeException, OrmException {
final ReviewResult result = new ReviewResult(); ReviewResult result = new ReviewResult();
final Change.Id changeId = patchSetId.getParentKey(); Change.Id changeId = patchSetId.getParentKey();
result.setChangeId(changeId); result.setChangeId(changeId);
final ChangeControl control = changeControlFactory.validateFor(changeId); ChangeControl control = changeControlFactory.validateFor(changeId);
final PatchSet patch = db.patchSets().get(patchSetId); PatchSet patch = db.patchSets().get(patchSetId);
if (patch == null) { if (patch == null) {
throw new NoSuchChangeException(changeId); throw new NoSuchChangeException(changeId);
} }
@ -89,10 +81,10 @@ public class DeleteDraftPatchSet implements Callable<ReviewResult> {
ReviewResult.Error.Type.DELETE_NOT_PERMITTED)); ReviewResult.Error.Type.DELETE_NOT_PERMITTED));
return result; return result;
} }
final Change change = control.getChange(); Change change = control.getChange();
try { try {
ChangeUtil.deleteOnlyDraftPatchSet(patch, change, gitManager, gitRefUpdated, db); changeUtil.deleteOnlyDraftPatchSet(patch, change);
} catch (IOException e) { } catch (IOException e) {
result.addError(new ReviewResult.Error( result.addError(new ReviewResult.Error(
ReviewResult.Error.Type.GIT_ERROR, e.getMessage())); ReviewResult.Error.Type.GIT_ERROR, e.getMessage()));
@ -101,8 +93,7 @@ public class DeleteDraftPatchSet implements Callable<ReviewResult> {
List<PatchSet> restOfPatches = db.patchSets().byChange(changeId).toList(); List<PatchSet> restOfPatches = db.patchSets().byChange(changeId).toList();
if (restOfPatches.size() == 0) { if (restOfPatches.size() == 0) {
try { try {
ChangeUtil.deleteDraftChange(patchSetId, gitManager, gitRefUpdated, db, changeUtil.deleteDraftChange(patchSetId);
indexer);
result.setChangeId(null); result.setChangeId(null);
} catch (IOException e) { } catch (IOException e) {
result.addError(new ReviewResult.Error( result.addError(new ReviewResult.Error(

View File

@ -1856,9 +1856,9 @@ public class ReceiveCommits {
db.patchSetApprovals().byChange(change.getId()).toList(); db.patchSetApprovals().byChange(change.getId()).toList();
final MailRecipients oldRecipients = getRecipientsFromApprovals( final MailRecipients oldRecipients = getRecipientsFromApprovals(
oldChangeApprovals); oldChangeApprovals);
ApprovalsUtil.copyLabels(db, labelTypes, oldChangeApprovals, approvalsUtil.copyLabels(labelTypes, oldChangeApprovals,
priorPatchSet, newPatchSet, changeKind); priorPatchSet, newPatchSet, changeKind);
approvalsUtil.addReviewers(db, labelTypes, change, newPatchSet, info, approvalsUtil.addReviewers(labelTypes, change, newPatchSet, info,
recipients.getReviewers(), oldRecipients.getAll()); recipients.getReviewers(), oldRecipients.getAll());
recipients.add(oldRecipients); recipients.add(oldRecipients);

View File

@ -103,7 +103,7 @@ public class PatchSetNotificationSender {
recipients.remove(me); recipients.remove(me);
if (newChange) { if (newChange) {
approvalsUtil.addReviewers(db, labelTypes, approvalsUtil.addReviewers(labelTypes,
updatedChange, updatedPatchSet, info, updatedChange, updatedPatchSet, info,
recipients.getReviewers(), Collections.<Account.Id> emptySet()); recipients.getReviewers(), Collections.<Account.Id> emptySet());
try { try {
@ -122,7 +122,7 @@ public class PatchSetNotificationSender {
updatedChange.getId()).toList(); updatedChange.getId()).toList();
final MailRecipients oldRecipients = final MailRecipients oldRecipients =
getRecipientsFromApprovals(patchSetApprovals); getRecipientsFromApprovals(patchSetApprovals);
approvalsUtil.addReviewers(db, labelTypes, updatedChange, approvalsUtil.addReviewers(labelTypes, updatedChange,
updatedPatchSet, info, recipients.getReviewers(), updatedPatchSet, info, recipients.getReviewers(),
oldRecipients.getAll()); oldRecipients.getAll());
final ChangeMessage msg = final ChangeMessage msg =