Fix rollback implementation When executing the rollback of a newly created ref due to a global-refdb failure or misalignment, the global-refdb might have persisted loose refs pointing to the zero-id rather than removing the ref itself. Add a logic in the rollback strategy that checks whether the new objectId is the zeroId and perform a delete instead. Bug: Issue 435473094 Change-Id: Ieff087d27b4e361ab6310fa611c79c733455232f
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbRefUpdate.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbRefUpdate.java index e9809e1..7c95d48 100644 --- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbRefUpdate.java +++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbRefUpdate.java
@@ -39,6 +39,7 @@ private final String projectName; private final RefUpdateValidator.Factory refValidatorFactory; private final RefUpdateValidator refUpdateValidator; + private final RefDatabase refDatabase; /** {@code SharedRefDbRefUpdate} Factory for Guice assisted injection. */ public interface Factory { @@ -71,6 +72,7 @@ refUpdateBase = refUpdate; this.projectName = projectName; this.refValidatorFactory = refValidatorFactory; + this.refDatabase = refDb; refUpdateValidator = this.refValidatorFactory.create(this.projectName, refDb, ignoredRefs); } @@ -309,6 +311,9 @@ private Result rollback(ObjectId objectId, NoParameterFunction<Result> updateFunction) throws IOException { + if (objectId == null || ObjectId.zeroId().equals(objectId)) { + return refDatabase.newUpdate(getRef().getName(), true).delete(); + } refUpdateBase.setExpectedOldObjectId(refUpdateBase.getNewObjectId()); refUpdateBase.setNewObjectId(objectId); return updateFunction.invoke();