summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Milanesio <luca.milanesio@gmail.com>2022-10-21 11:51:51 +0100
committerLuca Milanesio <luca.milanesio@gmail.com>2022-10-21 12:07:52 +0100
commit251ba39ae911c8ab79ce91f4fe32aa0726fa7963 (patch)
tree6833395b773c0e067e33cb4c4015506cd44c5660
parent6973e18264658b3990b5f823f747d08f2b7b54f5 (diff)
parent353a005f8e6abf047ad16b64978636d225861d81 (diff)
Merge branch 'stable-3.2' into stable-3.3
* stable-3.2: Limit the number of changes that can be submitted together GitwebServlet: Retrieve git path from FileRepository Make delegate() method public Release-Notes: skip Change-Id: I56968d4a2cf9800e78e673042a1cc250879b3fd8
-rw-r--r--Documentation/config-gerrit.txt7
-rw-r--r--java/com/google/gerrit/httpd/gitweb/GitwebServlet.java41
-rw-r--r--java/com/google/gerrit/server/git/DelegateRepository.java3
-rw-r--r--java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java35
-rw-r--r--javatests/com/google/gerrit/acceptance/server/change/SubmittedTogetherIT.java22
5 files changed, 92 insertions, 16 deletions
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 085a5d5c70..d4382a7922 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -1391,6 +1391,13 @@ This config can have the following states:
Default is `REF_UPDATED_AND_CHANGE_REINDEX`.
+[[change.maxSubmittableAtOnce]]change.maxSubmittableAtOnce::
++
+Maximum number of changes that can be chained together in the same repository
+to be submitted at once.
++
+Default is 32767.
+
[[change.move]]change.move::
+
Whether the link:rest-api-changes.html#move-change[Move Change] REST
diff --git a/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java b/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java
index 897d96f1b5..0875317542 100644
--- a/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java
+++ b/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java
@@ -43,12 +43,13 @@ import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.GitwebCgiConfig;
import com.google.gerrit.server.config.GitwebConfig;
import com.google.gerrit.server.config.SitePaths;
+import com.google.gerrit.server.git.DelegateRepository;
import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.git.LocalDiskRepositoryManager;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
@@ -85,6 +86,7 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
@@ -101,7 +103,7 @@ class GitwebServlet extends HttpServlet {
private final Set<String> deniedActions;
private final Path gitwebCgi;
private final URI gitwebUrl;
- private final LocalDiskRepositoryManager repoManager;
+ private final GitRepositoryManager repoManager;
private final ProjectCache projectCache;
private final PermissionBackend permissionBackend;
private final Provider<AnonymousUser> anonymousUserProvider;
@@ -119,12 +121,10 @@ class GitwebServlet extends HttpServlet {
SshInfo sshInfo,
Provider<AnonymousUser> anonymousUserProvider,
GitwebConfig gitwebConfig,
- GitwebCgiConfig gitwebCgiConfig)
+ GitwebCgiConfig gitwebCgiConfig,
+ AllProjectsName allProjects)
throws IOException {
- if (!(repoManager instanceof LocalDiskRepositoryManager)) {
- throw new ProvisionException("Gitweb can only be used with LocalDiskRepositoryManager");
- }
- this.repoManager = (LocalDiskRepositoryManager) repoManager;
+ this.repoManager = repoManager;
this.projectCache = projectCache;
this.permissionBackend = permissionBackend;
this.anonymousUserProvider = anonymousUserProvider;
@@ -132,6 +132,9 @@ class GitwebServlet extends HttpServlet {
this.gitwebCgi = gitwebCgiConfig.getGitwebCgi();
this.deniedActions = new HashSet<>();
+ // ensure that Gitweb works on supported repository type by checking All-Projects project
+ getProjectRoot(allProjects);
+
final String url = gitwebConfig.getUrl();
if ((url != null) && (!url.equals("gitweb"))) {
URI uri = null;
@@ -537,7 +540,8 @@ class GitwebServlet extends HttpServlet {
}
}
- private String[] makeEnv(HttpServletRequest req, ProjectState projectState) {
+ private String[] makeEnv(HttpServletRequest req, ProjectState projectState)
+ throws RepositoryNotFoundException, IOException {
final EnvList env = new EnvList(_env);
final int contentLength = Math.max(0, req.getContentLength());
@@ -579,7 +583,7 @@ class GitwebServlet extends HttpServlet {
env.set("GERRIT_CONTEXT_PATH", req.getContextPath() + "/");
env.set("GERRIT_PROJECT_NAME", nameKey.get());
- env.set("GITWEB_PROJECTROOT", repoManager.getBasePath(nameKey).toAbsolutePath().toString());
+ env.set("GITWEB_PROJECTROOT", getProjectRoot(nameKey));
if (projectState.statePermitsRead()
&& permissionBackend
@@ -636,6 +640,25 @@ class GitwebServlet extends HttpServlet {
return env.getEnvArray();
}
+ private String getProjectRoot(Project.NameKey nameKey)
+ throws RepositoryNotFoundException, IOException {
+ try (Repository repo = repoManager.openRepository(nameKey)) {
+ return getProjectRoot(repo);
+ }
+ }
+
+ private String getProjectRoot(Repository repo) {
+ if (repo instanceof DelegateRepository) {
+ return getProjectRoot(((DelegateRepository) repo).delegate());
+ }
+
+ if (repo instanceof FileRepository) {
+ return repo.getDirectory().getAbsolutePath();
+ }
+
+ throw new ProvisionException("Gitweb can only be used with FileRepository");
+ }
+
private void copyContentToCGI(HttpServletRequest req, OutputStream dst) throws IOException {
final int contentLength = req.getContentLength();
final InputStream src = req.getInputStream();
diff --git a/java/com/google/gerrit/server/git/DelegateRepository.java b/java/com/google/gerrit/server/git/DelegateRepository.java
index 5ebe358608..d45a31ed87 100644
--- a/java/com/google/gerrit/server/git/DelegateRepository.java
+++ b/java/com/google/gerrit/server/git/DelegateRepository.java
@@ -62,7 +62,8 @@ public class DelegateRepository extends Repository {
this.delegate = delegate;
}
- Repository delegate() {
+ /** Returns the wrapped {@link Repository} instance. */
+ public Repository delegate() {
return delegate;
}
diff --git a/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java b/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java
index 0b05607a56..5d81ae2aac 100644
--- a/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java
+++ b/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java
@@ -30,6 +30,7 @@ import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
@@ -53,6 +54,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;
@@ -64,6 +66,8 @@ import org.eclipse.jgit.revwalk.RevSort;
public class LocalMergeSuperSetComputation implements MergeSuperSetComputation {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+ public static final int MAX_SUBMITTABLE_CHANGES_AT_ONCE_DEFAULT = 1024;
+
public static class Module extends AbstractModule {
@Override
protected void configure() {
@@ -90,19 +94,24 @@ public class LocalMergeSuperSetComputation implements MergeSuperSetComputation {
private final Map<BranchNameKey, Optional<RevCommit>> heads;
private final ProjectCache projectCache;
private final ChangeIsVisibleToPredicate.Factory changeIsVisibleToPredicateFactory;
+ private final int maxSubmittableChangesAtOnce;
@Inject
LocalMergeSuperSetComputation(
PermissionBackend permissionBackend,
Provider<InternalChangeQuery> queryProvider,
ProjectCache projectCache,
- ChangeIsVisibleToPredicate.Factory changeIsVisibleToPredicateFactory) {
+ ChangeIsVisibleToPredicate.Factory changeIsVisibleToPredicateFactory,
+ @GerritServerConfig Config gerritConfig) {
this.projectCache = projectCache;
this.permissionBackend = permissionBackend;
this.queryProvider = queryProvider;
this.queryCache = new HashMap<>();
this.heads = new HashMap<>();
this.changeIsVisibleToPredicateFactory = changeIsVisibleToPredicateFactory;
+ this.maxSubmittableChangesAtOnce =
+ gerritConfig.getInt(
+ "change", "maxSubmittableAtOnce", MAX_SUBMITTABLE_CHANGES_AT_ONCE_DEFAULT);
}
@Override
@@ -147,8 +156,10 @@ public class LocalMergeSuperSetComputation implements MergeSuperSetComputation {
}
Set<String> visibleHashes =
- walkChangesByHashes(visibleCommits, Collections.emptySet(), or, b);
- Set<String> nonVisibleHashes = walkChangesByHashes(nonVisibleCommits, visibleHashes, or, b);
+ walkChangesByHashes(
+ visibleCommits, Collections.emptySet(), or, b, maxSubmittableChangesAtOnce);
+ Set<String> nonVisibleHashes =
+ walkChangesByHashes(nonVisibleCommits, visibleHashes, or, b, maxSubmittableChangesAtOnce);
ChangeSet partialSet =
byCommitsOnBranchNotMerged(or, b, visibleHashes, nonVisibleHashes, user);
@@ -248,7 +259,11 @@ public class LocalMergeSuperSetComputation implements MergeSuperSetComputation {
}
private Set<String> walkChangesByHashes(
- Collection<RevCommit> sourceCommits, Set<String> ignoreHashes, OpenRepo or, BranchNameKey b)
+ Collection<RevCommit> sourceCommits,
+ Set<String> ignoreHashes,
+ OpenRepo or,
+ BranchNameKey b,
+ int limit)
throws IOException {
Set<String> destHashes = new HashSet<>();
or.rw.reset();
@@ -258,7 +273,11 @@ public class LocalMergeSuperSetComputation implements MergeSuperSetComputation {
if (ignoreHashes.contains(name)) {
continue;
}
- destHashes.add(name);
+ if (destHashes.size() < limit) {
+ destHashes.add(name);
+ } else {
+ break;
+ }
or.rw.markStart(c);
}
for (RevCommit c : or.rw) {
@@ -266,7 +285,11 @@ public class LocalMergeSuperSetComputation implements MergeSuperSetComputation {
if (ignoreHashes.contains(name)) {
continue;
}
- destHashes.add(name);
+ if (destHashes.size() < limit) {
+ destHashes.add(name);
+ } else {
+ break;
+ }
}
return destHashes;
diff --git a/javatests/com/google/gerrit/acceptance/server/change/SubmittedTogetherIT.java b/javatests/com/google/gerrit/acceptance/server/change/SubmittedTogetherIT.java
index a97fb499ef..a2a6caaf03 100644
--- a/javatests/com/google/gerrit/acceptance/server/change/SubmittedTogetherIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/change/SubmittedTogetherIT.java
@@ -20,7 +20,9 @@ import static com.google.gerrit.extensions.api.changes.SubmittedTogetherOption.N
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GitUtil;
+import com.google.gerrit.acceptance.Sandboxed;
import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.entities.Project;
@@ -184,6 +186,26 @@ public class SubmittedTogetherIT extends AbstractDaemonTest {
}
@Test
+ @Sandboxed
+ @GerritConfig(name = "change.maxSubmittableAtOnce", value = "2")
+ public void submittedTogetherWithMaxChangesLimit() throws Exception {
+ String targetRef = "refs/for/master";
+
+ commitBuilder().add("a.txt", "1").message("subject: 1").create();
+ pushHead(testRepo, targetRef, false);
+
+ RevCommit c2_1 = commitBuilder().add("b.txt", "2").message("subject: 2").create();
+ String id2 = getChangeId(c2_1);
+ pushHead(testRepo, targetRef, false);
+
+ RevCommit c3_1 = commitBuilder().add("b.txt", "3").message("subject: 3").create();
+ String id3 = getChangeId(c3_1);
+ pushHead(testRepo, targetRef, false);
+
+ assertSubmittedTogether(id3, id3, id2);
+ }
+
+ @Test
public void respectTopicsOnAncestors() throws Exception {
RevCommit initialHead = projectOperations.project(project).getHead("master");