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();