Double check if a ref is missing locally before deleting from remote Repository.getRefs sometimes does not return the correct list of refs in the local repository (missing some). For this reason, we double check using Repository.getRef. Without this check, the ref is deleted from the remote by mistake. The suspicion for the former function not returning the correct list is primarily heavy garbage collection. It isn't confirmed whether the latter function always returns the correct value. Possibly a second check isn't enough, but it still catches many occurences of the issue. The presumption is that getRef is more atomic than getRefs. Change-Id: I619c92c55e36a4b6719ef812bdddb2d3b2aab814
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java index 4a2d01b..66304bc 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
@@ -483,6 +483,12 @@ if (spec != null) { // If the ref still exists locally, send it, otherwise delete it. Ref srcRef = local.get(src); + + // Second try to ensure that the ref is truly not found locally + if (srcRef == null) { + srcRef = git.getRef(src); + } + if (srcRef != null && canPushRef(src, noPerms)) { push(cmds, spec, srcRef); } else if (config.isMirror()) {