diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/DeleteDraftChange.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/DeleteDraftChange.java index 0f088c952b..bee5613464 100644 --- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/DeleteDraftChange.java +++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/DeleteDraftChange.java @@ -19,9 +19,6 @@ import com.google.gerrit.reviewdb.client.Change; 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.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.NoSuchChangeException; import com.google.gwtjsonrpc.common.VoidResult; @@ -38,39 +35,28 @@ class DeleteDraftChange extends Handler { private final ChangeControl.Factory changeControlFactory; private final ReviewDb db; - private final GitRepositoryManager gitManager; - private final GitReferenceUpdated gitRefUpdated; - private final ChangeIndexer indexer; - + private final ChangeUtil changeUtil; private final PatchSet.Id patchSetId; @Inject - DeleteDraftChange(final ReviewDb db, - final ChangeControl.Factory changeControlFactory, - final GitRepositoryManager gitManager, - final GitReferenceUpdated gitRefUpdated, - final ChangeIndexer indexer, - @Assisted final PatchSet.Id patchSetId) { + DeleteDraftChange(ReviewDb db, + ChangeControl.Factory changeControlFactory, + ChangeUtil changeUtil, + @Assisted PatchSet.Id patchSetId) { this.changeControlFactory = changeControlFactory; this.db = db; - this.gitManager = gitManager; - this.gitRefUpdated = gitRefUpdated; - this.indexer = indexer; - + this.changeUtil = changeUtil; this.patchSetId = patchSetId; } @Override public VoidResult call() throws NoSuchChangeException, OrmException, IOException { - - final Change.Id changeId = patchSetId.getParentKey(); - final ChangeControl control = changeControlFactory.validateFor(changeId); + Change.Id changeId = patchSetId.getParentKey(); + ChangeControl control = changeControlFactory.validateFor(changeId); if (!control.canDeleteDraft(db)) { throw new NoSuchChangeException(changeId); } - - ChangeUtil.deleteDraftChange(patchSetId, gitManager, gitRefUpdated, db, - indexer); + changeUtil.deleteDraftChange(patchSetId); return VoidResult.INSTANCE; } } diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/EditCommitMessageHandler.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/EditCommitMessageHandler.java index 564c13672d..f8e4d1eeac 100644 --- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/EditCommitMessageHandler.java +++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/EditCommitMessageHandler.java @@ -21,12 +21,9 @@ import com.google.gerrit.common.errors.NoSuchEntityException; import com.google.gerrit.httpd.rpc.Handler; import com.google.gerrit.reviewdb.client.Change; 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.GerritPersonIdent; -import com.google.gerrit.server.IdentifiedUser; 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.patch.PatchSetInfoNotAvailableException; 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.MissingObjectException; -import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.lib.PersonIdent; -import org.eclipse.jgit.lib.Repository; import java.io.IOException; @@ -51,37 +46,28 @@ class EditCommitMessageHandler extends Handler { } private final ChangeControl.Factory changeControlFactory; - private final ReviewDb db; - private final IdentifiedUser currentUser; private final ChangeDetailFactory.Factory changeDetailFactory; - private final CommitMessageEditedSender.Factory commitMessageEditedSenderFactory; + private final ChangeUtil changeUtil; private final PatchSet.Id patchSetId; @Nullable private final String message; - private final GitRepositoryManager gitManager; private final PersonIdent myIdent; - private final PatchSetInserter.Factory patchSetInserterFactory; @Inject - EditCommitMessageHandler(final ChangeControl.Factory changeControlFactory, - final ReviewDb db, final IdentifiedUser currentUser, - final ChangeDetailFactory.Factory changeDetailFactory, - final CommitMessageEditedSender.Factory commitMessageEditedSenderFactory, - @Assisted final PatchSet.Id patchSetId, - @Assisted @Nullable final String message, - final GitRepositoryManager gitManager, - @GerritPersonIdent final PersonIdent myIdent, - final PatchSetInserter.Factory patchSetInserterFactory) { + EditCommitMessageHandler(ChangeControl.Factory changeControlFactory, + ChangeDetailFactory.Factory changeDetailFactory, + CommitMessageEditedSender.Factory commitMessageEditedSenderFactory, + @Assisted PatchSet.Id patchSetId, + @Assisted @Nullable String message, + ChangeUtil changeUtil, + @GerritPersonIdent PersonIdent myIdent, + PatchSetInserter.Factory patchSetInserterFactory) { this.changeControlFactory = changeControlFactory; - this.db = db; - this.currentUser = currentUser; this.changeDetailFactory = changeDetailFactory; - this.commitMessageEditedSenderFactory = commitMessageEditedSenderFactory; + this.changeUtil = changeUtil; this.patchSetId = patchSetId; this.message = message; - this.gitManager = gitManager; this.myIdent = myIdent; - this.patchSetInserterFactory = patchSetInserterFactory; } @Override @@ -89,27 +75,13 @@ class EditCommitMessageHandler extends Handler { EmailException, NoSuchEntityException, PatchSetInfoNotAvailableException, MissingObjectException, IncorrectObjectTypeException, IOException, InvalidChangeOperationException, NoSuchProjectException { - - final Change.Id changeId = patchSetId.getParentKey(); - final ChangeControl control = changeControlFactory.validateFor(changeId); + Change.Id changeId = patchSetId.getParentKey(); + ChangeControl control = changeControlFactory.validateFor(changeId); if (!control.canAddPatchSet()) { throw new InvalidChangeOperationException( "Not allowed to add new Patch Sets to: " + changeId.toString()); } - - final Repository git; - 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(); - } + changeUtil.editCommitMessage(control, patchSetId, message, myIdent); + return changeDetailFactory.create(changeId).call(); } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java index deb6f30fb6..03f73f437f 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java @@ -70,11 +70,11 @@ public class ApprovalsUtil { * * @throws OrmException */ - public static void copyLabels(ReviewDb db, LabelTypes labelTypes, + public void copyLabels(LabelTypes labelTypes, PatchSet.Id source, PatchSet dest, ChangeKind changeKind) throws OrmException { Iterable sourceApprovals = 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 */ - public static void copyLabels(ReviewDb db, LabelTypes labelTypes, + public void copyLabels(LabelTypes labelTypes, Iterable sourceApprovals, PatchSet.Id source, PatchSet dest, ChangeKind changeKind) throws OrmException { List copied = Lists.newArrayList(); @@ -107,7 +107,7 @@ public class ApprovalsUtil { 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 wantReviewers, Set existingReviewers) throws OrmException { List allTypes = labelTypes.getLabelTypes(); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java index f5e9c5a1ac..afba67f9e3 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java @@ -21,7 +21,6 @@ import static java.util.concurrent.TimeUnit.SECONDS; import com.google.common.annotations.VisibleForTesting; import com.google.common.primitives.Ints; -import com.google.gerrit.common.ChangeHooks; import com.google.gerrit.common.errors.EmailException; import com.google.gerrit.reviewdb.client.Change; 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.CommitValidators; 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.patch.PatchSetInfoFactory; 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.NoSuchChangeException; 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.MagicBranch; import com.google.gerrit.server.util.TimeUtil; import com.google.gwtorm.server.OrmConcurrencyException; 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.MissingObjectException; +import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.lib.CommitBuilder; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; @@ -118,7 +120,7 @@ public class ChangeUtil { return u + '_' + l; } - public static void touch(final Change change, ReviewDb db) + public static void touch(Change change, ReviewDb db) throws OrmException { try { 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()); computeSortKey(c); } public static void insertAncestors(ReviewDb db, PatchSet.Id id, RevCommit src) throws OrmException { - final int cnt = src.getParentCount(); + int cnt = src.getParentCount(); List toInsert = new ArrayList(cnt); for (int p = 0; p < cnt; p++) { PatchSetAncestor a = @@ -155,268 +157,7 @@ public class ChangeUtil { db.patchSetAncestors().insert(toInsert); } - public static Change.Id revert(RefControl refControl, PatchSet.Id patchSetId, - 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){ + public static String sortKey(long lastUpdatedMs, int id) { long lastUpdatedMins = MINUTES.convert(lastUpdatedMs, MILLISECONDS); long minsSinceEpoch = lastUpdatedMins - SORT_KEY_EPOCH_MINS; StringBuilder r = new StringBuilder(16); @@ -453,6 +194,310 @@ public class ChangeUtil { return nextPatchSetId(git.getRefDatabase().getRefs(RefDatabase.ALL), id); } + private final Provider userProvider; + private final CommitValidators.Factory commitValidatorsFactory; + private final Provider 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 userProvider, + CommitValidators.Factory commitValidatorsFactory, + Provider 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) { return new PatchSet.Id(id.getParentKey(), id.get() + 1); } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java index de0438beb7..8c523e044f 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java @@ -51,6 +51,7 @@ public class Abandon implements RestModifyView, private final ChangeHooks hooks; private final AbandonedSender.Factory abandonedSenderFactory; private final Provider dbProvider; + private final Provider approvals; private final ChangeJson json; private final ChangeIndexer indexer; @@ -58,11 +59,13 @@ public class Abandon implements RestModifyView, Abandon(ChangeHooks hooks, AbandonedSender.Factory abandonedSenderFactory, Provider dbProvider, + Provider approvals, ChangeJson json, ChangeIndexer indexer) { this.hooks = hooks; this.abandonedSenderFactory = abandonedSenderFactory; this.dbProvider = dbProvider; + this.approvals = approvals; this.json = json; this.indexer = indexer; } @@ -103,7 +106,7 @@ public class Abandon implements RestModifyView, } message = newMessage(input, caller, change); db.changeMessages().insert(Collections.singleton(message)); - new ApprovalsUtil(db).syncChangeStatus(change); + approvals.get().syncChangeStatus(change); db.commit(); } finally { db.rollback(); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeInserter.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeInserter.java index 51b1bc84f1..95a7a58bf9 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeInserter.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeInserter.java @@ -75,6 +75,7 @@ public class ChangeInserter { @Inject ChangeInserter(Provider dbProvider, + Provider approvals, PatchSetInfoFactory patchSetInfoFactory, GitReferenceUpdated gitRefUpdated, ChangeHooks hooks, @@ -159,7 +160,7 @@ public class ChangeInserter { db.patchSets().insert(Collections.singleton(patchSet)); db.changes().insert(Collections.singleton(change)); LabelTypes labelTypes = refControl.getProjectControl().getLabelTypes(); - approvalsUtil.addReviewers(db, labelTypes, change, patchSet, patchSetInfo, + approvalsUtil.addReviewers(labelTypes, change, patchSet, patchSetInfo, reviewers, Collections. emptySet()); db.commit(); } finally { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteDraftChange.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteDraftChange.java index efdb9cb6ad..a5af648b1d 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteDraftChange.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteDraftChange.java @@ -24,9 +24,6 @@ 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.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.project.NoSuchChangeException; import com.google.gwtorm.server.OrmException; @@ -41,20 +38,14 @@ public class DeleteDraftChange implements } protected final Provider dbProvider; - private final GitRepositoryManager gitManager; - private final GitReferenceUpdated gitRefUpdated; - private final ChangeIndexer indexer; + private final ChangeUtil changeUtil; @Inject public DeleteDraftChange(Provider dbProvider, - GitRepositoryManager gitManager, - GitReferenceUpdated gitRefUpdated, PatchSetInfoFactory patchSetInfoFactory, - ChangeIndexer indexer) { + ChangeUtil changeUtil) { this.dbProvider = dbProvider; - this.gitManager = gitManager; - this.gitRefUpdated = gitRefUpdated; - this.indexer = indexer; + this.changeUtil = changeUtil; } @Override @@ -70,8 +61,7 @@ public class DeleteDraftChange implements } try { - ChangeUtil.deleteDraftChange(rsrc.getChange().getId(), - gitManager, gitRefUpdated, dbProvider.get(), indexer); + changeUtil.deleteDraftChange(rsrc.getChange().getId()); } catch (NoSuchChangeException e) { throw new ResourceNotFoundException(e.getMessage()); } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteDraftPatchSet.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteDraftPatchSet.java index ce86721879..3bc331f3b6 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteDraftPatchSet.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteDraftPatchSet.java @@ -26,9 +26,6 @@ import com.google.gerrit.reviewdb.client.PatchSetInfo; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.ChangeUtil; 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.PatchSetInfoNotAvailableException; import com.google.gerrit.server.project.NoSuchChangeException; @@ -45,22 +42,16 @@ public class DeleteDraftPatchSet implements RestModifyView dbProvider; - private final GitRepositoryManager gitManager; - private final GitReferenceUpdated gitRefUpdated; private final PatchSetInfoFactory patchSetInfoFactory; - private final ChangeIndexer indexer; + private final ChangeUtil changeUtil; @Inject public DeleteDraftPatchSet(Provider dbProvider, - GitRepositoryManager gitManager, - GitReferenceUpdated gitRefUpdated, PatchSetInfoFactory patchSetInfoFactory, - ChangeIndexer indexer) { + ChangeUtil changeUtil) { this.dbProvider = dbProvider; - this.gitManager = gitManager; - this.gitRefUpdated = gitRefUpdated; this.patchSetInfoFactory = patchSetInfoFactory; - this.indexer = indexer; + this.changeUtil = changeUtil; } @Override @@ -104,8 +95,7 @@ public class DeleteDraftPatchSet implements RestModifyView, UiAction { - - private final Provider dbProvider; - private final CommitMessageEditedSender.Factory commitMessageEditedSenderFactory; - private final GitRepositoryManager gitManager; + private final ChangeUtil changeUtil; private final PersonIdent myIdent; - private final PatchSetInserter.Factory patchSetInserterFactory; private final ChangeJson json; static class Input { @@ -62,17 +51,11 @@ class EditMessage implements RestModifyView, } @Inject - EditMessage(final Provider dbProvider, - final CommitMessageEditedSender.Factory commitMessageEditedSenderFactory, - final GitRepositoryManager gitManager, - final PatchSetInserter.Factory patchSetInserterFactory, - @GerritPersonIdent final PersonIdent myIdent, + EditMessage(ChangeUtil changeUtil, + @GerritPersonIdent PersonIdent myIdent, ChangeJson json) { - this.dbProvider = dbProvider; - this.commitMessageEditedSenderFactory = commitMessageEditedSenderFactory; - this.gitManager = gitManager; + this.changeUtil = changeUtil; this.myIdent = myIdent; - this.patchSetInserterFactory = patchSetInserterFactory; this.json = json; } @@ -83,22 +66,12 @@ class EditMessage implements RestModifyView, if (Strings.isNullOrEmpty(input.message)) { throw new BadRequestException("message must be non-empty"); } - - final Repository git; try { - git = gitManager.openRepository(rsrc.getChange().getProject()); - } catch (RepositoryNotFoundException e) { - throw new ResourceNotFoundException(e.getMessage()); - } - - try { - return json.format(ChangeUtil.editCommitMessage( + return json.format(changeUtil.editCommitMessage( + rsrc.getControl(), rsrc.getPatchSet().getId(), - rsrc.getControl().getRefControl(), - (IdentifiedUser) rsrc.getControl().getCurrentUser(), - input.message, dbProvider.get(), - commitMessageEditedSenderFactory, git, myIdent, - patchSetInserterFactory)); + input.message, + myIdent)); } catch (InvalidChangeOperationException e) { throw new BadRequestException(e.getMessage()); } catch (NoSuchChangeException e) { @@ -106,8 +79,6 @@ class EditMessage implements RestModifyView, } catch (MissingObjectException | IncorrectObjectTypeException | PatchSetInfoNotAvailableException e) { throw new ResourceConflictException(e.getMessage()); - } finally { - git.close(); } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java index ad5ded9106..4e0d3b8c09 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java @@ -95,6 +95,7 @@ public class PatchSetInserter { private final MergeabilityChecker mergeabilityChecker; private final ReplacePatchSetSender.Factory replacePatchSetFactory; private final MergeUtil.Factory mergeUtilFactory; + private final ApprovalsUtil approvalsUtil; private final Repository git; private final RevWalk revWalk; @@ -120,6 +121,7 @@ public class PatchSetInserter { MergeabilityChecker mergeabilityChecker, ReplacePatchSetSender.Factory replacePatchSetFactory, MergeUtil.Factory mergeUtilFactory, + ApprovalsUtil approvalsUtil, @Assisted Repository git, @Assisted RevWalk revWalk, @Assisted RefControl refControl, @@ -135,6 +137,7 @@ public class PatchSetInserter { this.mergeabilityChecker = mergeabilityChecker; this.replacePatchSetFactory = replacePatchSetFactory; this.mergeUtilFactory = mergeUtilFactory; + this.approvalsUtil = approvalsUtil; this.git = git; this.revWalk = revWalk; @@ -279,7 +282,7 @@ public class PatchSetInserter { ChangeKind changeKind = getChangeKind(mergeUtilFactory, projectState, git, priorCommit, commit); - ApprovalsUtil.copyLabels(db, refControl.getProjectControl() + approvalsUtil.copyLabels(refControl.getProjectControl() .getLabelTypes(), currentPatchSetId, patchSet, changeKind); } db.commit(); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Restore.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Restore.java index 58494c4841..8b7eb642bf 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Restore.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Restore.java @@ -52,6 +52,7 @@ public class Restore implements RestModifyView, private final ChangeHooks hooks; private final RestoredSender.Factory restoredSenderFactory; private final Provider dbProvider; + private final Provider approvals; private final ChangeJson json; private final ChangeIndexer indexer; @@ -59,11 +60,13 @@ public class Restore implements RestModifyView, Restore(ChangeHooks hooks, RestoredSender.Factory restoredSenderFactory, Provider dbProvider, + Provider approvals, ChangeJson json, ChangeIndexer indexer) { this.hooks = hooks; this.restoredSenderFactory = restoredSenderFactory; this.dbProvider = dbProvider; + this.approvals = approvals; this.json = json; this.indexer = indexer; } @@ -104,7 +107,7 @@ public class Restore implements RestModifyView, } message = newMessage(input, caller, change); db.changeMessages().insert(Collections.singleton(message)); - new ApprovalsUtil(db).syncChangeStatus(change); + approvals.get().syncChangeStatus(change); db.commit(); } finally { db.rollback(); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Revert.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Revert.java index 5d2ddde700..022c12c13e 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Revert.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Revert.java @@ -15,7 +15,6 @@ package com.google.gerrit.server.change; import com.google.common.base.Strings; -import com.google.gerrit.common.ChangeHooks; import com.google.gerrit.common.errors.EmailException; import com.google.gerrit.extensions.api.changes.RevertInput; 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.reviewdb.client.Change; 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.GerritPersonIdent; -import com.google.gerrit.server.IdentifiedUser; 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.InvalidChangeOperationException; import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.ssh.NoSshInfo; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; -import com.google.inject.Provider; import org.eclipse.jgit.lib.PersonIdent; -import org.eclipse.jgit.lib.Repository; import java.io.IOException; public class Revert implements RestModifyView, UiAction { - private final ChangeHooks hooks; - private final RevertedSender.Factory revertedSenderFactory; - private final CommitValidators.Factory commitValidatorsFactory; - private final Provider dbProvider; private final ChangeJson json; - private final GitRepositoryManager gitManager; + private final ChangeUtil changeUtil; private final PersonIdent myIdent; - private final PatchSetInfoFactory patchSetInfoFactory; - private final ChangeInserter.Factory changeInserterFactory; @Inject - Revert(ChangeHooks hooks, - RevertedSender.Factory revertedSenderFactory, - final CommitValidators.Factory commitValidatorsFactory, - Provider 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; + Revert(ChangeJson json, + ChangeUtil changeUtil, + @GerritPersonIdent PersonIdent myIdent) { this.json = json; - this.gitManager = gitManager; + this.changeUtil = changeUtil; this.myIdent = myIdent; - this.changeInserterFactory = changeInserterFactory; - this.patchSetInfoFactory = patchSetInfoFactory; } @Override @@ -93,26 +66,17 @@ public class Revert implements RestModifyView, throw new ResourceConflictException("change is " + status(change)); } - final Repository git = gitManager.openRepository(control.getProject().getNameKey()); try { - CommitValidators commitValidators = - commitValidatorsFactory.create(control.getRefControl(), new NoSshInfo(), git); - Change.Id revertedChangeId = - ChangeUtil.revert(control.getRefControl(), change.currentPatchSetId(), - (IdentifiedUser) control.getCurrentUser(), - commitValidators, - Strings.emptyToNull(input.message), dbProvider.get(), - revertedSenderFactory, hooks, git, patchSetInfoFactory, - myIdent, changeInserterFactory); + changeUtil.revert(control, change.currentPatchSetId(), + Strings.emptyToNull(input.message), + myIdent, new NoSshInfo()); return json.format(revertedChangeId); } catch (InvalidChangeOperationException e) { throw new BadRequestException(e.getMessage()); } catch (NoSuchChangeException e) { throw new ResourceNotFoundException(e.getMessage()); - } finally { - git.close(); } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/DeleteDraftPatchSet.java b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/DeleteDraftPatchSet.java index e6ce4c2451..f5e08cc1b8 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/DeleteDraftPatchSet.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/DeleteDraftPatchSet.java @@ -20,8 +20,6 @@ import com.google.gerrit.reviewdb.client.Change; 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.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.PatchSetInfoNotAvailableException; @@ -37,44 +35,38 @@ import java.util.List; import java.util.concurrent.Callable; public class DeleteDraftPatchSet implements Callable { - public interface Factory { DeleteDraftPatchSet create(PatchSet.Id patchSetId); } private final ChangeControl.Factory changeControlFactory; private final ReviewDb db; - private final GitRepositoryManager gitManager; - private final GitReferenceUpdated gitRefUpdated; private final PatchSetInfoFactory patchSetInfoFactory; - private final ChangeIndexer indexer; - + private final ChangeUtil changeUtil; private final PatchSet.Id patchSetId; @Inject DeleteDraftPatchSet(ChangeControl.Factory changeControlFactory, - ReviewDb db, GitRepositoryManager gitManager, - GitReferenceUpdated gitRefUpdated, PatchSetInfoFactory patchSetInfoFactory, + ReviewDb db, + PatchSetInfoFactory patchSetInfoFactory, ChangeIndexer indexer, - @Assisted final PatchSet.Id patchSetId) { + ChangeUtil changeUtil, + @Assisted PatchSet.Id patchSetId) { this.changeControlFactory = changeControlFactory; this.db = db; - this.gitManager = gitManager; - this.gitRefUpdated = gitRefUpdated; this.patchSetInfoFactory = patchSetInfoFactory; - this.indexer = indexer; - + this.changeUtil = changeUtil; this.patchSetId = patchSetId; } @Override 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); - final ChangeControl control = changeControlFactory.validateFor(changeId); - final PatchSet patch = db.patchSets().get(patchSetId); + ChangeControl control = changeControlFactory.validateFor(changeId); + PatchSet patch = db.patchSets().get(patchSetId); if (patch == null) { throw new NoSuchChangeException(changeId); } @@ -89,10 +81,10 @@ public class DeleteDraftPatchSet implements Callable { ReviewResult.Error.Type.DELETE_NOT_PERMITTED)); return result; } - final Change change = control.getChange(); + Change change = control.getChange(); try { - ChangeUtil.deleteOnlyDraftPatchSet(patch, change, gitManager, gitRefUpdated, db); + changeUtil.deleteOnlyDraftPatchSet(patch, change); } catch (IOException e) { result.addError(new ReviewResult.Error( ReviewResult.Error.Type.GIT_ERROR, e.getMessage())); @@ -101,8 +93,7 @@ public class DeleteDraftPatchSet implements Callable { List restOfPatches = db.patchSets().byChange(changeId).toList(); if (restOfPatches.size() == 0) { try { - ChangeUtil.deleteDraftChange(patchSetId, gitManager, gitRefUpdated, db, - indexer); + changeUtil.deleteDraftChange(patchSetId); result.setChangeId(null); } catch (IOException e) { result.addError(new ReviewResult.Error( diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java index a2a053fb2b..825749246a 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java @@ -1856,9 +1856,9 @@ public class ReceiveCommits { db.patchSetApprovals().byChange(change.getId()).toList(); final MailRecipients oldRecipients = getRecipientsFromApprovals( oldChangeApprovals); - ApprovalsUtil.copyLabels(db, labelTypes, oldChangeApprovals, + approvalsUtil.copyLabels(labelTypes, oldChangeApprovals, priorPatchSet, newPatchSet, changeKind); - approvalsUtil.addReviewers(db, labelTypes, change, newPatchSet, info, + approvalsUtil.addReviewers(labelTypes, change, newPatchSet, info, recipients.getReviewers(), oldRecipients.getAll()); recipients.add(oldRecipients); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/PatchSetNotificationSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/PatchSetNotificationSender.java index 3484dd8048..37ac462d82 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/PatchSetNotificationSender.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/PatchSetNotificationSender.java @@ -103,7 +103,7 @@ public class PatchSetNotificationSender { recipients.remove(me); if (newChange) { - approvalsUtil.addReviewers(db, labelTypes, + approvalsUtil.addReviewers(labelTypes, updatedChange, updatedPatchSet, info, recipients.getReviewers(), Collections. emptySet()); try { @@ -122,7 +122,7 @@ public class PatchSetNotificationSender { updatedChange.getId()).toList(); final MailRecipients oldRecipients = getRecipientsFromApprovals(patchSetApprovals); - approvalsUtil.addReviewers(db, labelTypes, updatedChange, + approvalsUtil.addReviewers(labelTypes, updatedChange, updatedPatchSet, info, recipients.getReviewers(), oldRecipients.getAll()); final ChangeMessage msg =