diff options
author | Shawn Pearce <sop@google.com> | 2013-09-11 12:33:18 -0700 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2015-03-03 16:46:00 +0000 |
commit | c40e14cafff332ca08cfc75b2e06f673e0b0b8f6 (patch) | |
tree | afb00d6f178439824abb6d606da7c09408c38660 /gerrit-server | |
parent | f2918e9355cf25012c434a09f834d6f2f83b3083 (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.java | 63 |
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(); + } + } } |