Allow filter for Git repositories

The line `allowfilter = true` is inserted both in new Git repositories
and existing ones (via an UpdateStep). This enables clones with
`--filter` parameters.

Co-authored-by: René Pfeuffer<rene.pfeuffer@cloudogu.com>
This commit is contained in:
Till-André Diegeler
2025-01-09 15:27:22 +01:00
parent a4e30b94a2
commit 08e57b9a19
17 changed files with 438 additions and 35 deletions

View File

@@ -25,10 +25,11 @@ public class GitConfigHelper {
private static final String CONFIG_SECTION_SCMM = "scmm";
private static final String CONFIG_KEY_REPOSITORY_ID = "repositoryid";
public void createScmmConfig(Repository repository, org.eclipse.jgit.lib.Repository gitRepository) throws IOException {
StoredConfig config = gitRepository.getConfig();
config.setString(CONFIG_SECTION_SCMM, null, CONFIG_KEY_REPOSITORY_ID, repository.getId());
config.save();
public void createScmmConfig(Repository scmmRepository, org.eclipse.jgit.lib.Repository gitRepository) throws IOException {
StoredConfig gitConfig = gitRepository.getConfig();
gitConfig.setString(CONFIG_SECTION_SCMM, null, CONFIG_KEY_REPOSITORY_ID, scmmRepository.getId());
gitConfig.setBoolean("uploadpack", null, "allowFilter", true);
gitConfig.save();
}
public String getRepositoryId(StoredConfig gitConfig) {

View File

@@ -30,13 +30,13 @@ import sonia.scm.plugin.Extension;
*/
@Extension
@EagerSingleton
public class GitRepositoryModifyListener {
public class GitRepositoryConfigChangeListener {
private final GitHeadModifier headModifier;
private final GitRepositoryConfigStoreProvider storeProvider;
@Inject
public GitRepositoryModifyListener(GitHeadModifier headModifier, GitRepositoryConfigStoreProvider storeProvider) {
public GitRepositoryConfigChangeListener(GitHeadModifier headModifier, GitRepositoryConfigStoreProvider storeProvider) {
this.headModifier = headModifier;
this.storeProvider = storeProvider;
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2020 - present Cloudogu GmbH
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
package sonia.scm.repository.update;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.Repository;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
class GitUpdateStepHelper {
private GitUpdateStepHelper() {}
static Path determineEffectiveGitFolder(Path path) {
Path bareGitFolder = path.resolve("data");
Path nonBareGitFolder = bareGitFolder.resolve(".git");
final Path effectiveGitPath;
if (Files.exists(nonBareGitFolder)) {
effectiveGitPath = nonBareGitFolder;
} else {
effectiveGitPath = bareGitFolder;
}
return effectiveGitPath;
}
static org.eclipse.jgit.lib.Repository build(File directory) throws IOException {
return new FileRepositoryBuilder().setGitDir(directory).readEnvironment().findGitDir().build();
}
static boolean isGitDirectory(Repository repository) {
return GitRepositoryHandler.TYPE_NAME.equals(repository.getType());
}
}

View File

@@ -17,22 +17,21 @@
package sonia.scm.repository.update;
import jakarta.inject.Inject;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import sonia.scm.migration.UpdateException;
import sonia.scm.migration.UpdateStep;
import sonia.scm.plugin.Extension;
import sonia.scm.repository.GitConfigHelper;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryLocationResolver;
import sonia.scm.update.UpdateStepRepositoryMetadataAccess;
import sonia.scm.version.Version;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static sonia.scm.repository.update.GitUpdateStepHelper.build;
import static sonia.scm.repository.update.GitUpdateStepHelper.determineEffectiveGitFolder;
import static sonia.scm.repository.update.GitUpdateStepHelper.isGitDirectory;
import static sonia.scm.version.Version.parse;
@Extension
@@ -64,30 +63,6 @@ public class GitV2UpdateStep implements UpdateStep {
);
}
public Path determineEffectiveGitFolder(Path path) {
Path bareGitFolder = path.resolve("data");
Path nonBareGitFolder = bareGitFolder.resolve(".git");
final Path effectiveGitPath;
if (Files.exists(nonBareGitFolder)) {
effectiveGitPath = nonBareGitFolder;
} else {
effectiveGitPath = bareGitFolder;
}
return effectiveGitPath;
}
private org.eclipse.jgit.lib.Repository build(File directory) throws IOException {
return new FileRepositoryBuilder()
.setGitDir(directory)
.readEnvironment()
.findGitDir()
.build();
}
private boolean isGitDirectory(Repository repository) {
return GitRepositoryHandler.TYPE_NAME.equals(repository.getType());
}
@Override
public Version getTargetVersion() {
return parse("2.0.0");

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2020 - present Cloudogu GmbH
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
package sonia.scm.repository.update;
import jakarta.inject.Inject;
import sonia.scm.migration.RepositoryUpdateContext;
import sonia.scm.migration.RepositoryUpdateStep;
import sonia.scm.plugin.Extension;
import sonia.scm.repository.GitConfigHelper;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryLocationResolver;
import sonia.scm.update.UpdateStepRepositoryMetadataAccess;
import sonia.scm.version.Version;
import java.io.File;
import java.nio.file.Path;
import static sonia.scm.repository.update.GitUpdateStepHelper.build;
import static sonia.scm.repository.update.GitUpdateStepHelper.determineEffectiveGitFolder;
import static sonia.scm.repository.update.GitUpdateStepHelper.isGitDirectory;
import static sonia.scm.version.Version.parse;
@Extension
public class UpdatePackFilterUpdateStep implements RepositoryUpdateStep {
private final RepositoryLocationResolver locationResolver;
private final UpdateStepRepositoryMetadataAccess<Path> repositoryMetadataAccess;
@Inject
public UpdatePackFilterUpdateStep(RepositoryLocationResolver locationResolver, UpdateStepRepositoryMetadataAccess<Path> repositoryMetadataAccess) {
this.locationResolver = locationResolver;
this.repositoryMetadataAccess = repositoryMetadataAccess;
}
@Override
public void doUpdate(RepositoryUpdateContext repositoryUpdateContext) throws Exception {
Path scmmRepositoryLocation = locationResolver.forClass(Path.class).getLocation(repositoryUpdateContext.getRepositoryId());
Repository scmmRepository = repositoryMetadataAccess.read(scmmRepositoryLocation);
if (isGitDirectory(scmmRepository)) {
File gitFile = determineEffectiveGitFolder(scmmRepositoryLocation).toFile();
org.eclipse.jgit.lib.Repository gitRepository = build(gitFile);
GitConfigHelper gitConfigHelper = new GitConfigHelper();
gitConfigHelper.createScmmConfig(scmmRepository, gitRepository);
}
}
@Override
public Version getTargetVersion() {
return parse("3.7.0");
}
@Override
public String getAffectedDataType() {
return "sonia.scm.plugin.git";
}
}