Respect `remote.mirror` option in DeleteRefCommand When the `remote.mirror` option is disable, the replica should ignore branch and tag deletions. This is handled correctly for CGit and JGit fetches, but is ignored when ref deletion is applied through `ApplyObjectAction`. This change adds a check for `mirror` option status to the `DeleteRefCommand` and ignores it when it is set to `false`. This is aligning HTTP and Brodker-based implementations with the behaviour of `git fetch` command. Bug: Issue 40015323 Change-Id: Idf565ddb69602be9af41857ca5135db7b5429570
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java index 0f7af40..9984a03 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java
@@ -906,6 +906,10 @@ return config.replicateProjectDeletions(); } + public boolean isMirror() { + return config.getRemoteConfig().isMirror(); + } + public boolean enableBatchedRefs() { return config.enableBatchedRefs(); }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommand.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommand.java index f204f89..3150fe1 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommand.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommand.java
@@ -68,6 +68,18 @@ public void deleteRef(Project.NameKey name, String refName, String sourceLabel) throws IOException, RestApiException { + Source source = + sourcesCollection + .getByRemoteName(sourceLabel) + .orElseThrow( + () -> + new IllegalStateException( + String.format("Could not find URI for %s remote", sourceLabel))); + if (!source.isMirror()) { + repLog.info( + "Ignoring ref {} deletion from project {}, as mirror option is false", refName, name); + return; + } try { repLog.info("Delete ref from {} for project {}, ref name {}", sourceLabel, name, refName); Optional<ProjectState> projectState = projectCache.get(name); @@ -81,13 +93,6 @@ return; } - Source source = - sourcesCollection - .getByRemoteName(sourceLabel) - .orElseThrow( - () -> - new IllegalStateException( - String.format("Could not find URI for %s remote", sourceLabel))); URIish sourceUri = source.getURI(name); try {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommandTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommandTest.java index 6e40226..9c9c689 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommandTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommandTest.java
@@ -19,6 +19,7 @@ import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import com.google.gerrit.entities.Project; @@ -106,6 +107,8 @@ @Test public void shouldSendEventWhenDeletingRef() throws Exception { + when(source.isMirror()).thenReturn(true); + objectUnderTest.deleteRef(TEST_PROJECT_NAME, TEST_REF_NAME, TEST_SOURCE_LABEL); verify(eventDispatcher).postEvent(eventCaptor.capture()); @@ -117,7 +120,17 @@ } @Test + public void shouldNotSendNotSendEventWhenMirroringIsDisabled() throws Exception { + when(source.isMirror()).thenReturn(false); + + objectUnderTest.deleteRef(TEST_PROJECT_NAME, TEST_REF_NAME, TEST_SOURCE_LABEL); + + verifyNoInteractions(eventDispatcher); + } + + @Test public void shouldHandleNonExistingRef() throws Exception { + when(source.isMirror()).thenReturn(true); when(refDb.exactRef(anyString())).thenReturn(null); objectUnderTest.deleteRef(TEST_PROJECT_NAME, NON_EXISTING_REF_NAME, TEST_SOURCE_LABEL);