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
This commit is contained in:
@@ -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;
|
||||
@@ -211,7 +212,7 @@ public class MergeOp {
|
||||
}
|
||||
}
|
||||
|
||||
public void merge() throws MergeException, NoSuchProjectException {
|
||||
public void merge() throws MergeException {
|
||||
setDestProject();
|
||||
try {
|
||||
openSchema();
|
||||
@@ -270,6 +271,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 {
|
||||
@@ -343,13 +349,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);
|
||||
@@ -1041,4 +1046,53 @@ 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();
|
||||
indexer.index(change);
|
||||
}
|
||||
} finally {
|
||||
db.rollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user