GitRepositoryManager should be responsible to enable/disable the GC

According to 8df3d44ee1 JGit library can
perform garbage collection only on FileRepository. Currently Gerrit has
ability to swap the GitRepositoryManager implementation. This means that
we can have more than just LocalDiskRepositoryManager backed by
FileRepository.

Allowing GitRepositoryManager to decide if garbage collection can be
performed fixes the issue with 'Run GC' button hidden when multi-site
plugin installed.

Bug: Issue 14097
Change-Id: I2384a93836c65d90fd7921ed2b63bc45406f74b7
This commit is contained in:
Marcin Czech
2021-02-18 16:16:24 +01:00
parent caba13a06c
commit 63c3b3d867
5 changed files with 78 additions and 2 deletions

View File

@@ -57,4 +57,13 @@ public interface GitRepositoryManager {
/** @return set of all known projects, sorted by natural NameKey order. */
SortedSet<Project.NameKey> list();
/**
* Check if garbage collection can be performed by the repository manager.
*
* @return true if repository can perform garbage collection.
*/
default Boolean canPerformGC() {
return false;
}
}

View File

@@ -199,6 +199,11 @@ public class LocalDiskRepositoryManager implements GitRepositoryManager {
}
}
@Override
public Boolean canPerformGC() {
return true;
}
private boolean isUnreasonableName(Project.NameKey nameKey) {
final String name = nameKey.get();

View File

@@ -29,7 +29,6 @@ import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.UrlFormatter;
import com.google.gerrit.server.git.GarbageCollection;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.LocalDiskRepositoryManager;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.ioutil.HexFormat;
import com.google.gerrit.server.project.ProjectResource;
@@ -66,7 +65,7 @@ public class GarbageCollect
DynamicItem<UrlFormatter> urlFormatter) {
this.workQueue = workQueue;
this.urlFormatter = urlFormatter;
this.canGC = repoManager instanceof LocalDiskRepositoryManager;
this.canGC = repoManager.canPerformGC();
this.garbageCollectionFactory = garbageCollectionFactory;
}

View File

@@ -0,0 +1,58 @@
// Copyright (C) 2021 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.git;
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.reviewdb.client.Project.NameKey;
import com.google.gerrit.testing.GerritBaseTests;
import java.io.IOException;
import java.util.SortedSet;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Test;
public class GitRepositoryManagerTest extends GerritBaseTests {
private GitRepositoryManager objectUnderTest;
@Before
public void setUp() throws Exception {
objectUnderTest = new TestGitRepositoryManager();
}
@Test
public void shouldReturnFalseWhenDefaultCanPerformGC() {
assertThat(objectUnderTest.canPerformGC()).isFalse();
}
private static class TestGitRepositoryManager implements GitRepositoryManager {
@Override
public Repository openRepository(NameKey name) throws RepositoryNotFoundException, IOException {
throw new UnsupportedOperationException("Not implemented");
}
@Override
public Repository createRepository(NameKey name)
throws RepositoryCaseMismatchException, RepositoryNotFoundException, IOException {
throw new UnsupportedOperationException("Not implemented");
}
@Override
public SortedSet<NameKey> list() {
throw new UnsupportedOperationException("Not implemented");
}
}
}

View File

@@ -212,6 +212,11 @@ public class LocalDiskRepositoryManagerTest extends EasyMockSupport {
newRepoManager.createRepository(new Project.NameKey("A"));
}
@Test
public void testRepositoryCanPerformGC() throws Exception {
assertThat(repoManager.canPerformGC()).isTrue();
}
private void createSymLink(Project.NameKey project, String link) throws IOException {
Path base = repoManager.getBasePath(project);
Path projectDir = base.resolve(project.get() + ".git");