Support fixing corrupt changes in ConsistencyChecker
To fix changes, pass an appropriate input to the checker; for now this is empty, but may include things like a strategy to choose when there are multiple options. (For example, if multiple patch sets have the same SHA-1, we could delete all but the newest, or all but the oldest.) Change-Id: I016a94e27b8f6b63b3662b46271c01ed86110ec3
This commit is contained in:
@@ -21,13 +21,16 @@ import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.gerrit.common.Nullable;
|
||||
import com.google.gerrit.extensions.api.changes.FixInput;
|
||||
import com.google.gerrit.extensions.common.ProblemInfo;
|
||||
import com.google.gerrit.extensions.common.ProblemInfo.Status;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.query.change.ChangeData;
|
||||
import com.google.gwtorm.server.AtomicUpdate;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
@@ -80,6 +83,7 @@ public class ConsistencyChecker {
|
||||
private final Provider<ReviewDb> db;
|
||||
private final GitRepositoryManager repoManager;
|
||||
|
||||
private FixInput fix;
|
||||
private Change change;
|
||||
private Repository repo;
|
||||
private RevWalk rw;
|
||||
@@ -105,9 +109,13 @@ public class ConsistencyChecker {
|
||||
}
|
||||
|
||||
public Result check(ChangeData cd) {
|
||||
return check(cd, null);
|
||||
}
|
||||
|
||||
public Result check(ChangeData cd, @Nullable FixInput f) {
|
||||
reset();
|
||||
try {
|
||||
return check(cd.change());
|
||||
return check(cd.change(), f);
|
||||
} catch (OrmException e) {
|
||||
error("Error looking up change", e);
|
||||
return Result.create(cd.getId(), problems);
|
||||
@@ -115,7 +123,12 @@ public class ConsistencyChecker {
|
||||
}
|
||||
|
||||
public Result check(Change c) {
|
||||
return check(c, null);
|
||||
}
|
||||
|
||||
public Result check(Change c, @Nullable FixInput f) {
|
||||
reset();
|
||||
fix = f;
|
||||
change = c;
|
||||
try {
|
||||
checkImpl();
|
||||
@@ -258,10 +271,13 @@ public class ConsistencyChecker {
|
||||
return;
|
||||
}
|
||||
if (merged && change.getStatus() != Change.Status.MERGED) {
|
||||
problem(String.format("Patch set %d (%s) is merged into destination"
|
||||
+ " ref %s (%s), but change status is %s", currPs.getId().get(),
|
||||
currPsCommit.name(), refName, tip.name(), change.getStatus()));
|
||||
// TODO(dborowitz): Just fix it.
|
||||
ProblemInfo p = problem(String.format(
|
||||
"Patch set %d (%s) is merged into destination ref %s (%s), but change"
|
||||
+ " status is %s", currPs.getId().get(), currPsCommit.name(),
|
||||
refName, tip.name(), change.getStatus()));
|
||||
if (fix != null) {
|
||||
fixMerged(p);
|
||||
}
|
||||
} else if (!merged && change.getStatus() == Change.Status.MERGED) {
|
||||
problem(String.format("Patch set %d (%s) is not merged into"
|
||||
+ " destination ref %s (%s), but change status is %s",
|
||||
@@ -270,6 +286,25 @@ public class ConsistencyChecker {
|
||||
}
|
||||
}
|
||||
|
||||
private void fixMerged(ProblemInfo p) {
|
||||
try {
|
||||
change = db.get().changes().atomicUpdate(change.getId(),
|
||||
new AtomicUpdate<Change>() {
|
||||
@Override
|
||||
public Change update(Change c) {
|
||||
c.setStatus(Change.Status.MERGED);
|
||||
return c;
|
||||
}
|
||||
});
|
||||
p.status = Status.FIXED;
|
||||
p.outcome = "Marked change as merged";
|
||||
} catch (OrmException e) {
|
||||
log.warn("Error marking " + change.getId() + "as merged", e);
|
||||
p.status = Status.FIX_FAILED;
|
||||
p.outcome = "Error updating status to merged";
|
||||
}
|
||||
}
|
||||
|
||||
private RevCommit parseCommit(ObjectId objId, String desc) {
|
||||
try {
|
||||
return rw.parseCommit(objId);
|
||||
@@ -283,10 +318,11 @@ public class ConsistencyChecker {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void problem(String msg) {
|
||||
private ProblemInfo problem(String msg) {
|
||||
ProblemInfo p = new ProblemInfo();
|
||||
p.message = msg;
|
||||
problems.add(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
private boolean error(String msg, Throwable t) {
|
||||
|
Reference in New Issue
Block a user