Merge changes from topic 'repo-manager-gh16'

* changes:
  Support multiple git repositories locations
  Rework LocalDiskRepositoryManager to be extendable
This commit is contained in:
Dave Borowitz 2016-03-18 12:58:06 +00:00 committed by Gerrit Code Review
commit d751ec1c6c
12 changed files with 478 additions and 35 deletions

View File

@ -3190,6 +3190,17 @@ named `project/plugins/a` would be `CHERRY_PICK`.
the previous example, all properties will be used from `project/plugins/\*`
section and no properties will be inherited nor overridden from `project/*`.
[[repository.name.basePath]]repository.<name>.basePath::
+
Alternate to <<gerrit.basePath,gerrit.basePath>>. The repository will be created
and used from this location instead: ${alternateBasePath}/${projectName}.git.
+
If configuring the basePath for an existing project in gerrit, make sure to stop
gerrit, move the repository in the alternate basePath, configure basePath for
this repository and then start Gerrit.
+
Path must be absolute.
[[repository.name.defaultSubmitType]]repository.<name>.defaultSubmitType::
+
The default submit type for newly created projects. Supported values

View File

@ -314,8 +314,7 @@ class GitwebServlet extends HttpServlet {
p.print("}\n");
}
Path root = repoManager.getBasePath();
p.print("$projectroot = " + quoteForPerl(root) + ";\n");
p.print("$projectroot = $ENV{'GITWEB_PROJECTROOT'};\n");
// Permit exporting only the project we were started for.
// We use the name under $projectroot in case symlinks
@ -546,6 +545,10 @@ class GitwebServlet extends HttpServlet {
env.set("GERRIT_CONTEXT_PATH", req.getContextPath() + "/");
env.set("GERRIT_PROJECT_NAME", project.getProject().getName());
env.set("GITWEB_PROJECTROOT",
repoManager.getBasePath(project.getProject().getNameKey())
.toAbsolutePath().toString());
if (project.forUser(anonymousUserProvider.get()).isVisible()) {
env.set("GERRIT_ANONYMOUS_READ", "1");
}

View File

@ -28,7 +28,7 @@ import com.google.gerrit.metrics.dropwizard.DropWizardMetricMaker;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.GerritServerConfigModule;
import com.google.gerrit.server.config.SitePath;
import com.google.gerrit.server.git.LocalDiskRepositoryManager;
import com.google.gerrit.server.git.GitRepositoryManagerModule;
import com.google.gerrit.server.notedb.ConfigNotesMigration;
import com.google.gerrit.server.schema.DataSourceModule;
import com.google.gerrit.server.schema.DataSourceProvider;
@ -175,7 +175,7 @@ public abstract class SiteProgram extends AbstractProgram {
});
modules.add(new DatabaseModule());
modules.add(new SchemaModule());
modules.add(new LocalDiskRepositoryManager.Module());
modules.add(cfgInjector.getInstance(GitRepositoryManagerModule.class));
modules.add(new ConfigNotesMigration.Module());
try {

View File

@ -223,7 +223,6 @@ public class GerritGlobalModule extends FactoryModule {
.toProvider(AccountVisibilityProvider.class)
.in(SINGLETON);
factory(ProjectOwnerGroupsProvider.Factory.class);
bind(RepositoryConfig.class);
bind(AuthBackend.class).to(UniversalAuthBackend.class).in(SINGLETON);
DynamicSet.setOf(binder(), AuthBackend.class);

View File

@ -21,12 +21,18 @@ import com.google.inject.Singleton;
import org.eclipse.jgit.lib.Config;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
@Singleton
public class RepositoryConfig {
static final String SECTION_NAME = "repository";
static final String OWNER_GROUP_NAME = "ownerGroup";
static final String DEFAULT_SUBMIT_TYPE_NAME = "defaultSubmitType";
static final String BASE_PATH_NAME = "basePath";
private final Config cfg;
@ -45,6 +51,23 @@ public class RepositoryConfig {
OWNER_GROUP_NAME);
}
public Path getBasePath(Project.NameKey project) {
String basePath = cfg.getString(SECTION_NAME, findSubSection(project.get()),
BASE_PATH_NAME);
return basePath != null ? Paths.get(basePath) : null;
}
public List<Path> getAllBasePaths() {
List<Path> basePaths = new ArrayList<>();
for (String subSection : cfg.getSubsections(SECTION_NAME)) {
String basePath = cfg.getString(SECTION_NAME, subSection, BASE_PATH_NAME);
if (basePath != null) {
basePaths.add(Paths.get(basePath));
}
}
return basePaths;
}
/**
* Find the subSection to get repository configuration from.
* <p>

View File

@ -0,0 +1,38 @@
// Copyright (C) 2015 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 com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.server.config.RepositoryConfig;
import com.google.inject.Inject;
public class GitRepositoryManagerModule extends LifecycleModule {
private final RepositoryConfig repoConfig;
@Inject
public GitRepositoryManagerModule(RepositoryConfig repoConfig) {
this.repoConfig = repoConfig;
}
@Override
protected void configure() {
if (repoConfig.getAllBasePaths().isEmpty()) {
install(new LocalDiskRepositoryManager.Module());
} else {
install(new MultiBaseLocalDiskRepositoryManager.Module());
}
}
}

View File

@ -61,7 +61,8 @@ import java.util.concurrent.locks.ReentrantLock;
/** Manages Git repositories stored on the local filesystem. */
@Singleton
public class LocalDiskRepositoryManager implements GitRepositoryManager {
public class LocalDiskRepositoryManager implements GitRepositoryManager,
LifecycleListener {
private static final Logger log =
LoggerFactory.getLogger(LocalDiskRepositoryManager.class);
@ -72,6 +73,7 @@ public class LocalDiskRepositoryManager implements GitRepositoryManager {
@Override
protected void configure() {
bind(GitRepositoryManager.class).to(LocalDiskRepositoryManager.class);
listener().to(LocalDiskRepositoryManager.class);
listener().to(LocalDiskRepositoryManager.Lifecycle.class);
}
}
@ -125,7 +127,7 @@ public class LocalDiskRepositoryManager implements GitRepositoryManager {
private final NotesMigration notesMigration;
private final Path noteDbPath;
private final Lock namesUpdateLock;
private volatile SortedSet<Project.NameKey> names;
private volatile SortedSet<Project.NameKey> names = new TreeSet<>();
@Inject
LocalDiskRepositoryManager(SitePaths site,
@ -140,18 +142,31 @@ public class LocalDiskRepositoryManager implements GitRepositoryManager {
noteDbPath = site.resolve(MoreObjects.firstNonNull(
cfg.getString("gerrit", null, "noteDbPath"), "notedb"));
namesUpdateLock = new ReentrantLock(true /* fair */);
}
@Override
public void start() {
names = list();
}
/** @return base directory under which all projects are stored. */
public Path getBasePath() {
@Override
public void stop() {
}
/**
* Return the basePath under which the specified project is stored.
*
* @param name the name of the project
* @return base directory
*/
public Path getBasePath(Project.NameKey name) {
return basePath;
}
@Override
public Repository openRepository(Project.NameKey name)
throws RepositoryNotFoundException {
return openRepository(basePath, name);
return openRepository(getBasePath(name), name);
}
private Repository openRepository(Path path, Project.NameKey name)
@ -198,7 +213,7 @@ public class LocalDiskRepositoryManager implements GitRepositoryManager {
@Override
public Repository createRepository(Project.NameKey name)
throws RepositoryNotFoundException, RepositoryCaseMismatchException {
Repository repo = createRepository(basePath, name);
Repository repo = createRepository(getBasePath(name), name);
if (notesMigration.writeChanges() && !noteDbPath.equals(basePath)) {
createRepository(noteDbPath, name);
}
@ -374,27 +389,40 @@ public class LocalDiskRepositoryManager implements GitRepositoryManager {
// scanning the filesystem. Don't rely on the cached names collection.
namesUpdateLock.lock();
try {
ProjectVisitor visitor = new ProjectVisitor();
try {
Files.walkFileTree(basePath, EnumSet.of(FileVisitOption.FOLLOW_LINKS),
Integer.MAX_VALUE, visitor);
} catch (IOException e) {
log.error("Error walking repository tree " + basePath.toAbsolutePath(),
e);
}
ProjectVisitor visitor = new ProjectVisitor(basePath);
scanProjects(visitor);
return Collections.unmodifiableSortedSet(visitor.found);
} finally {
namesUpdateLock.unlock();
}
}
private class ProjectVisitor extends SimpleFileVisitor<Path> {
protected void scanProjects(ProjectVisitor visitor) {
try {
Files.walkFileTree(visitor.startFolder,
EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, visitor);
} catch (IOException e) {
log.error("Error walking repository tree "
+ visitor.startFolder.toAbsolutePath(), e);
}
}
protected class ProjectVisitor extends SimpleFileVisitor<Path> {
private final SortedSet<Project.NameKey> found = new TreeSet<>();
private Path startFolder;
public ProjectVisitor(Path startFolder) {
setStartFolder(startFolder);
}
public void setStartFolder(Path startFolder) {
this.startFolder = startFolder;
}
@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs) throws IOException {
if (!dir.equals(basePath) && isRepo(dir)) {
if (!dir.equals(startFolder) && isRepo(dir)) {
addProject(dir);
return FileVisitResult.SKIP_SUBTREE;
}
@ -409,16 +437,18 @@ public class LocalDiskRepositoryManager implements GitRepositoryManager {
private void addProject(Path p) {
Project.NameKey nameKey = getProjectName(p);
if (isUnreasonableName(nameKey)) {
log.warn(
"Ignoring unreasonably named repository " + p.toAbsolutePath());
} else {
found.add(nameKey);
if (getBasePath(nameKey).equals(startFolder)) {
if (isUnreasonableName(nameKey)) {
log.warn(
"Ignoring unreasonably named repository " + p.toAbsolutePath());
} else {
found.add(nameKey);
}
}
}
private Project.NameKey getProjectName(Path p) {
String projectName = basePath.relativize(p).toString();
String projectName = startFolder.relativize(p).toString();
if (File.separatorChar != '/') {
projectName = projectName.replace(File.separatorChar, '/');
}

View File

@ -0,0 +1,78 @@
//Copyright (C) 2015 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.base.Preconditions.checkState;
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.reviewdb.client.Project.NameKey;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.RepositoryConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.Config;
import java.nio.file.Path;
public class MultiBaseLocalDiskRepositoryManager extends
LocalDiskRepositoryManager {
public static class Module extends LifecycleModule {
@Override
protected void configure() {
bind(GitRepositoryManager.class).to(
MultiBaseLocalDiskRepositoryManager.class);
bind(LocalDiskRepositoryManager.class).to(
MultiBaseLocalDiskRepositoryManager.class);
listener().to(MultiBaseLocalDiskRepositoryManager.class);
listener().to(MultiBaseLocalDiskRepositoryManager.Lifecycle.class);
}
}
private final RepositoryConfig config;
@Inject
MultiBaseLocalDiskRepositoryManager(SitePaths site,
@GerritServerConfig Config cfg,
NotesMigration notesMigration,
RepositoryConfig config) {
super(site, cfg, notesMigration);
this.config = config;
for (Path alternateBasePath : config.getAllBasePaths()) {
checkState(alternateBasePath.isAbsolute(),
"repository.<name>.basePath must be absolute: %s", alternateBasePath);
}
}
@Override
public Path getBasePath(NameKey name) {
Path alternateBasePath = config.getBasePath(name);
return alternateBasePath != null
? alternateBasePath
: super.getBasePath(name);
}
@Override
protected void scanProjects(ProjectVisitor visitor) {
super.scanProjects(visitor);
for (Path path : config.getAllBasePaths()) {
visitor.setStartFolder(path);
super.scanProjects(visitor);
}
}
}

View File

@ -24,6 +24,9 @@ import org.eclipse.jgit.lib.Config;
import org.junit.Before;
import org.junit.Test;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
public class RepositoryConfigTest {
@ -144,4 +147,67 @@ public class RepositoryConfigTest {
cfg.setStringList(RepositoryConfig.SECTION_NAME, projectFilter,
RepositoryConfig.OWNER_GROUP_NAME, ownerGroups);
}
@Test
public void testBasePathWhenNotConfigured() {
assertThat((Object)repoCfg.getBasePath(new NameKey("someProject"))).isNull();
}
@Test
public void testBasePathForStarFilter() {
String basePath = "/someAbsolutePath/someDirectory";
configureBasePath("*", basePath);
assertThat(repoCfg.getBasePath(new NameKey("someProject")).toString())
.isEqualTo(basePath);
}
@Test
public void testBasePathForSpecificFilter() {
String basePath = "/someAbsolutePath/someDirectory";
configureBasePath("someProject", basePath);
assertThat((Object) repoCfg.getBasePath(new NameKey("someOtherProject")))
.isNull();
assertThat(repoCfg.getBasePath(new NameKey("someProject")).toString())
.isEqualTo(basePath);
}
@Test
public void testBasePathForStartWithFilter() {
String basePath1 = "/someAbsolutePath1/someDirectory";
String basePath2 = "someRelativeDirectory2";
String basePath3 = "/someAbsolutePath3/someDirectory";
String basePath4 = "/someAbsolutePath4/someDirectory";
configureBasePath("pro*", basePath1);
configureBasePath("project/project/*", basePath2);
configureBasePath("project/*", basePath3);
configureBasePath("*", basePath4);
assertThat(repoCfg.getBasePath(new NameKey("project1")).toString())
.isEqualTo(basePath1);
assertThat(repoCfg.getBasePath(new NameKey("project/project/someProject"))
.toString()).isEqualTo(basePath2);
assertThat(
repoCfg.getBasePath(new NameKey("project/someProject")).toString())
.isEqualTo(basePath3);
assertThat(repoCfg.getBasePath(new NameKey("someProject")).toString())
.isEqualTo(basePath4);
}
@Test
public void testAllBasePath() {
List<Path> allBasePaths = Arrays.asList(Paths.get("/someBasePath1"),
Paths.get("/someBasePath2"), Paths.get("/someBasePath2"));
configureBasePath("*", allBasePaths.get(0).toString());
configureBasePath("project/*", allBasePaths.get(1).toString());
configureBasePath("project/project/*", allBasePaths.get(2).toString());
assertThat(repoCfg.getAllBasePaths()).isEqualTo(allBasePaths);
}
private void configureBasePath(String projectFilter, String basePath) {
cfg.setString(RepositoryConfig.SECTION_NAME, projectFilter,
RepositoryConfig.BASE_PATH_NAME, basePath);
}
}

View File

@ -56,6 +56,7 @@ public class LocalDiskRepositoryManagerTest extends EasyMockSupport {
repoManager =
new LocalDiskRepositoryManager(site, cfg,
createNiceMock(NotesMigration.class));
repoManager.start();
}
@Test(expected = IllegalStateException.class)
@ -169,8 +170,8 @@ public class LocalDiskRepositoryManagerTest extends EasyMockSupport {
@Test
public void testOpenRepositoryCreatedDirectlyOnDisk() throws Exception {
createRepository(repoManager.getBasePath(), "projectA");
Project.NameKey projectA = new Project.NameKey("projectA");
createRepository(repoManager.getBasePath(projectA), projectA.get());
try (Repository repo = repoManager.openRepository(projectA)) {
assertThat(repo).isNotNull();
}
@ -185,17 +186,17 @@ public class LocalDiskRepositoryManagerTest extends EasyMockSupport {
@Test
public void testList() throws Exception {
Project.NameKey projectA = new Project.NameKey("projectA");
createRepository(repoManager.getBasePath(), projectA.get());
createRepository(repoManager.getBasePath(projectA), projectA.get());
Project.NameKey projectB = new Project.NameKey("path/projectB");
createRepository(repoManager.getBasePath(), projectB.get());
createRepository(repoManager.getBasePath(projectB), projectB.get());
Project.NameKey projectC = new Project.NameKey("anotherPath/path/projectC");
createRepository(repoManager.getBasePath(), projectC.get());
createRepository(repoManager.getBasePath(projectC), projectC.get());
// create an invalid git repo named only .git
repoManager.getBasePath().resolve(".git").toFile().mkdir();
repoManager.getBasePath(null).resolve(".git").toFile().mkdir();
// create an invalid repo name
createRepository(repoManager.getBasePath(), "project?A");
createRepository(repoManager.getBasePath(null), "project?A");
assertThat(repoManager.list())
.containsExactly(projectA, projectB, projectC);
}

View File

@ -0,0 +1,194 @@
// Copyright (C) 2015 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 static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.RepositoryConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.testutil.TempFileUtil;
import com.google.gwtorm.client.KeyUtil;
import com.google.gwtorm.server.StandardKeyEncoder;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.util.FS;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.SortedSet;
public class MultiBaseLocalDiskRepositoryManagerTest {
static {
KeyUtil.setEncoderImpl(new StandardKeyEncoder());
}
private Config cfg;
private SitePaths site;
private MultiBaseLocalDiskRepositoryManager repoManager;
private RepositoryConfig configMock;
@Before
public void setUp() throws IOException {
site = new SitePaths(TempFileUtil.createTempDirectory().toPath());
site.resolve("git").toFile().mkdir();
cfg = new Config();
cfg.setString("gerrit", null, "basePath", "git");
configMock = createNiceMock(RepositoryConfig.class);
expect(configMock.getAllBasePaths()).andReturn(new ArrayList<Path>()).anyTimes();
replay(configMock);
NotesMigration notesMigrationMock = createNiceMock(NotesMigration.class);
replay(notesMigrationMock);
repoManager =
new MultiBaseLocalDiskRepositoryManager(site, cfg,
notesMigrationMock, configMock);
}
@After
public void tearDown() throws IOException {
TempFileUtil.cleanup();
}
@Test
public void testDefaultRepositoryLocation()
throws RepositoryCaseMismatchException, RepositoryNotFoundException {
Project.NameKey someProjectKey = new Project.NameKey("someProject");
Repository repo = repoManager.createRepository(someProjectKey);
assertThat(repo.getDirectory()).isNotNull();
assertThat(repo.getDirectory().exists()).isTrue();
assertThat(repo.getDirectory().getParent()).isEqualTo(
repoManager.getBasePath(someProjectKey).toAbsolutePath().toString());
repo = repoManager.openRepository(someProjectKey);
assertThat(repo.getDirectory()).isNotNull();
assertThat(repo.getDirectory().exists()).isTrue();
assertThat(repo.getDirectory().getParent()).isEqualTo(
repoManager.getBasePath(someProjectKey).toAbsolutePath().toString());
assertThat(
repoManager.getBasePath(someProjectKey).toAbsolutePath().toString())
.isEqualTo(
repoManager.getBasePath(someProjectKey).toAbsolutePath().toString());
SortedSet<Project.NameKey> repoList = repoManager.list();
assertThat(repoList.size()).isEqualTo(1);
assertThat(repoList.toArray(new Project.NameKey[repoList.size()]))
.isEqualTo(new Project.NameKey[] {someProjectKey});
}
@Test
public void testAlternateRepositoryLocation() throws IOException {
Path alternateBasePath = TempFileUtil.createTempDirectory().toPath();
Project.NameKey someProjectKey = new Project.NameKey("someProject");
reset(configMock);
expect(configMock.getBasePath(someProjectKey)).andReturn(alternateBasePath)
.anyTimes();
expect(configMock.getAllBasePaths())
.andReturn(Arrays.asList(alternateBasePath)).anyTimes();
replay(configMock);
Repository repo = repoManager.createRepository(someProjectKey);
assertThat(repo.getDirectory()).isNotNull();
assertThat(repo.getDirectory().exists()).isTrue();
assertThat(repo.getDirectory().getParent())
.isEqualTo(alternateBasePath.toString());
repo = repoManager.openRepository(someProjectKey);
assertThat(repo.getDirectory()).isNotNull();
assertThat(repo.getDirectory().exists()).isTrue();
assertThat(repo.getDirectory().getParent())
.isEqualTo(alternateBasePath.toString());
assertThat(
repoManager.getBasePath(someProjectKey).toAbsolutePath().toString())
.isEqualTo(alternateBasePath.toString());
SortedSet<Project.NameKey> repoList = repoManager.list();
assertThat(repoList.size()).isEqualTo(1);
assertThat(repoList.toArray(new Project.NameKey[repoList.size()]))
.isEqualTo(new Project.NameKey[] {someProjectKey});
}
@Test
public void testListReturnRepoFromProperLocation() throws IOException {
Project.NameKey basePathProject = new Project.NameKey("basePathProject");
Project.NameKey altPathProject = new Project.NameKey("altPathProject");
Project.NameKey misplacedProject1 =
new Project.NameKey("misplacedProject1");
Project.NameKey misplacedProject2 =
new Project.NameKey("misplacedProject2");
Path alternateBasePath = TempFileUtil.createTempDirectory().toPath();
reset(configMock);
expect(configMock.getBasePath(altPathProject)).andReturn(alternateBasePath)
.anyTimes();
expect(configMock.getBasePath(misplacedProject2))
.andReturn(alternateBasePath).anyTimes();
expect(configMock.getAllBasePaths())
.andReturn(Arrays.asList(alternateBasePath)).anyTimes();
replay(configMock);
repoManager.createRepository(basePathProject);
repoManager.createRepository(altPathProject);
// create the misplaced ones without the repomanager otherwise they would
// end up at the proper place.
createRepository(repoManager.getBasePath(basePathProject),
misplacedProject2);
createRepository(alternateBasePath, misplacedProject1);
SortedSet<Project.NameKey> repoList = repoManager.list();
assertThat(repoList.size()).isEqualTo(2);
assertThat(repoList.toArray(new Project.NameKey[repoList.size()]))
.isEqualTo(new Project.NameKey[] {altPathProject, basePathProject});
}
private void createRepository(Path directory, Project.NameKey projectName)
throws IOException {
String n = projectName.get() + Constants.DOT_GIT_EXT;
FileKey loc = FileKey.exact(directory.resolve(n).toFile(), FS.DETECTED);
try (Repository db = RepositoryCache.open(loc, false)) {
db.create(true /* bare */);
}
}
@Test(expected = IllegalStateException.class)
public void testRelativeAlternateLocation() {
configMock = createNiceMock(RepositoryConfig.class);
expect(configMock.getAllBasePaths())
.andReturn(Arrays.asList(Paths.get("repos"))).anyTimes();
replay(configMock);
repoManager =
new MultiBaseLocalDiskRepositoryManager(site, cfg,
createNiceMock(NotesMigration.class), configMock);
}
}

View File

@ -44,7 +44,7 @@ import com.google.gerrit.server.config.RestCacheAdminModule;
import com.google.gerrit.server.config.SitePath;
import com.google.gerrit.server.git.ChangeCacheImplModule;
import com.google.gerrit.server.git.GarbageCollectionModule;
import com.google.gerrit.server.git.LocalDiskRepositoryManager;
import com.google.gerrit.server.git.GitRepositoryManagerModule;
import com.google.gerrit.server.git.ReceiveCommitsExecutorModule;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.index.IndexModule;
@ -285,7 +285,6 @@ public class WebAppInitializer extends GuiceServletContextListener
modules.add(new GerritServerConfigModule());
}
modules.add(new SchemaModule());
modules.add(new LocalDiskRepositoryManager.Module());
modules.add(new ConfigNotesMigration.Module());
modules.add(SchemaVersionCheck.module());
modules.add(new AuthConfigModule());
@ -296,6 +295,7 @@ public class WebAppInitializer extends GuiceServletContextListener
final List<Module> modules = new ArrayList<>();
modules.add(new DropWizardMetricMaker.RestModule());
modules.add(new EventBroker.Module());
modules.add(cfgInjector.getInstance(GitRepositoryManagerModule.class));
modules.add(new ChangeHookRunner.Module());
modules.add(new ReceiveCommitsExecutorModule());
modules.add(new DiffExecutorModule());