summaryrefslogtreecommitdiffstats
path: root/gerrit-server
diff options
context:
space:
mode:
authorShawn Pearce <sop@google.com>2013-09-11 12:33:18 -0700
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-03-03 16:46:00 +0000
commitc40e14cafff332ca08cfc75b2e06f673e0b0b8f6 (patch)
treeafb00d6f178439824abb6d606da7c09408c38660 /gerrit-server
parentf2918e9355cf25012c434a09f834d6f2f83b3083 (diff)
Abandon any open changes if a project has been removed
If the Git repository has been deleted and a change has been submitted in that repository MergeOp will contiuously try to submit changes in that project, failing on every attempt when openRepository() fails. Catch this failure and abandon all changes in the project, as the Git data no longer exists. Change-Id: I83087211b281c1e478c0e83b48b8f7d158a93c13 (cherry picked from commit 1eda8192c2ab1027ca499ddad6b7dfe79f29c189) Reviewed-by: Ismo Haataja <ismo.haataja@digia.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'gerrit-server')
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java63
1 files changed, 58 insertions, 5 deletions
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
index 70a1b8233d..785fbacfa5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
@@ -38,6 +38,7 @@ import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.SubmitType;
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
@@ -262,7 +263,7 @@ public class MergeOp {
}
}
- public void merge() throws MergeException, NoSuchProjectException {
+ public void merge() throws MergeException {
setDestProject();
try {
openSchema();
@@ -321,6 +322,11 @@ public class MergeOp {
message(commit.change, capable.getMessage()), false);
}
}
+ } catch (NoSuchProjectException noProject) {
+ log.warn(String.format(
+ "Project %s no longer exists, abandoning open changes",
+ destBranch.getParentKey().get()));
+ abandonAllOpenChanges();
} catch (OrmException e) {
throw new MergeException("Cannot query the database", e);
} finally {
@@ -394,13 +400,12 @@ public class MergeOp {
canMergeFlag, getAlreadyAccepted(branchTip), destBranch);
}
- private void openRepository() throws MergeException {
+ private void openRepository() throws MergeException, NoSuchProjectException {
final Project.NameKey name = destBranch.getParentKey();
try {
repo = repoManager.openRepository(name);
- } catch (RepositoryNotFoundException notGit) {
- final String m = "Repository \"" + name.get() + "\" unknown.";
- throw new MergeException(m, notGit);
+ } catch (RepositoryNotFoundException notFound) {
+ throw new NoSuchProjectException(name, notFound);
} catch (IOException err) {
final String m = "Error opening repository \"" + name.get() + '"';
throw new MergeException(m, err);
@@ -1129,4 +1134,52 @@ public class MergeOp {
}
}
}
+
+ private void abandonAllOpenChanges() {
+ try {
+ openSchema();
+ for (Change c : db.changes().byProjectOpenAll(destBranch.getParentKey())) {
+ abandonOneChange(c);
+ }
+ db.close();
+ db = null;
+ } catch (OrmException e) {
+ log.warn(String.format(
+ "Cannot abandon changes for deleted project %s",
+ destBranch.getParentKey().get()), e);
+ }
+ }
+
+ private void abandonOneChange(Change change) throws OrmException {
+ db.changes().beginTransaction(change.getId());
+ try {
+ change = db.changes().atomicUpdate(
+ change.getId(),
+ new AtomicUpdate<Change>() {
+ @Override
+ public Change update(Change change) {
+ if (change.getStatus().isOpen()) {
+ change.setStatus(Change.Status.ABANDONED);
+ return change;
+ }
+ return null;
+ }
+ });
+ if (change != null) {
+ ChangeMessage msg = new ChangeMessage(
+ new ChangeMessage.Key(
+ change.getId(),
+ ChangeUtil.messageUUID(db)),
+ null,
+ change.getLastUpdatedOn(),
+ change.currentPatchSetId());
+ msg.setMessage("Project was deleted.");
+ db.changeMessages().insert(Collections.singleton(msg));
+ new ApprovalsUtil(db).syncChangeStatus(change);
+ db.commit();
+ }
+ } finally {
+ db.rollback();
+ }
+ }
}