diff --git a/Documentation/cmd-create-project.txt b/Documentation/cmd-create-project.txt index d0e56fd714..666fe91b01 100644 --- a/Documentation/cmd-create-project.txt +++ b/Documentation/cmd-create-project.txt @@ -21,6 +21,7 @@ SYNOPSIS [--require-change-id | --id] [[--branch | -b ] ...] [--empty-commit] + [--max-object-size-limit ] { | --name } DESCRIPTION @@ -144,6 +145,15 @@ link:project-setup.html#submit_type[Change Submit Actions]. Creates an initial empty commit for the Git repository of the project that is newly created. +--max-object-size-limit:: + Define maximum Git object size for this project. Pushes containing an + object larger than this limit will be rejected. This can be used to + further limit the global + link:config-gerrit.html#receive.maxObjectSizeLimit[receive.maxObjectSizeLimit] + and cannot be used to increase that globally set limit. ++ +Common unit suffixes of 'k', 'm', or 'g' are supported. + EXAMPLES -------- diff --git a/Documentation/cmd-set-project.txt b/Documentation/cmd-set-project.txt index a0af9108bc..7ff534bfe3 100644 --- a/Documentation/cmd-set-project.txt +++ b/Documentation/cmd-set-project.txt @@ -16,6 +16,7 @@ SYNOPSIS [--content-merge ] [--change-id ] [--project-state | --ps ] + [--max-object-size-limit ] DESCRIPTION @@ -93,6 +94,15 @@ link:project-setup.html#submit_type[Change Submit Actions]. is granted, but all modification operations are disabled. * HIDDEN: the project is not visible for those who are not owners +--max-object-size-limit:: + Define maximum Git object size for this project. Pushes containing an + object larger than this limit will be rejected. This can be used to + further limit the global + link:config-gerrit.html#receive.maxObjectSizeLimit[receive.maxObjectSizeLimit] + and cannot be used to increase that globally set limit. ++ +Common unit suffixes of 'k', 'm', or 'g' are supported. + EXAMPLES -------- Change project `example` to be hidden, require change id, don't use content merge @@ -105,4 +115,4 @@ and use 'merge if necessary' as merge strategy: GERRIT ------ -Part of link:index.html[Gerrit Code Review] \ No newline at end of file +Part of link:index.html[Gerrit Code Review] diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java index d2434964a9..f3cf47194d 100644 --- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java +++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java @@ -107,6 +107,8 @@ public final class Project { protected InheritableBoolean requireChangeID; + protected String maxObjectSizeLimit; + protected InheritableBoolean useContentMerge; protected String defaultDashboardId; @@ -160,6 +162,10 @@ public final class Project { return requireChangeID; } + public String getMaxObjectSizeLimit() { + return maxObjectSizeLimit; + } + public void setUseContributorAgreements(final InheritableBoolean u) { useContributorAgreements = u; } @@ -176,6 +182,10 @@ public final class Project { requireChangeID = cid; } + public void setMaxObjectSizeLimit(final String limit) { + maxObjectSizeLimit = limit; + } + public SubmitType getSubmitType() { return submitType; } @@ -224,6 +234,7 @@ public final class Project { requireChangeID = update.requireChangeID; submitType = update.submitType; state = update.state; + maxObjectSizeLimit = update.maxObjectSizeLimit; } /** diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java index a12b9489fa..a2f392d2f7 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java @@ -382,6 +382,7 @@ public class ProjectConfig extends VersionedMetaData { p.setUseContributorAgreements(getEnum(rc, RECEIVE, null, KEY_REQUIRE_CONTRIBUTOR_AGREEMENT, Project.InheritableBoolean.INHERIT)); p.setUseSignedOffBy(getEnum(rc, RECEIVE, null, KEY_REQUIRE_SIGNED_OFF_BY, Project.InheritableBoolean.INHERIT)); p.setRequireChangeID(getEnum(rc, RECEIVE, null, KEY_REQUIRE_CHANGE_ID, Project.InheritableBoolean.INHERIT)); + p.setMaxObjectSizeLimit(rc.getString(RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT)); p.setSubmitType(getEnum(rc, SUBMIT, null, KEY_ACTION, defaultSubmitAction)); p.setUseContentMerge(getEnum(rc, SUBMIT, null, KEY_MERGE_CONTENT, Project.InheritableBoolean.INHERIT)); @@ -723,6 +724,7 @@ public class ProjectConfig extends VersionedMetaData { set(rc, RECEIVE, null, KEY_REQUIRE_CONTRIBUTOR_AGREEMENT, p.getUseContributorAgreements(), Project.InheritableBoolean.INHERIT); set(rc, RECEIVE, null, KEY_REQUIRE_SIGNED_OFF_BY, p.getUseSignedOffBy(), Project.InheritableBoolean.INHERIT); set(rc, RECEIVE, null, KEY_REQUIRE_CHANGE_ID, p.getRequireChangeID(), Project.InheritableBoolean.INHERIT); + set(rc, RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT, validMaxObjectSizeLimit(p.getMaxObjectSizeLimit())); set(rc, SUBMIT, null, KEY_ACTION, p.getSubmitType(), defaultSubmitAction); set(rc, SUBMIT, null, KEY_MERGE_CONTENT, p.getUseContentMerge(), Project.InheritableBoolean.INHERIT); @@ -744,6 +746,31 @@ public class ProjectConfig extends VersionedMetaData { saveGroupList(); } + private static final String validMaxObjectSizeLimit(String value) + throws ConfigInvalidException { + if (value == null) { + return null; + } + Config cfg = new Config(); + cfg.fromText("[s]\nn=" + value); + try { + long s = cfg.getLong("s", "n", 0); + if (s < 0) { + throw new ConfigInvalidException(String.format( + "Negative value '%s' not allowed as %s", value, + KEY_MAX_OBJECT_SIZE_LIMIT)); + } + if (s == 0) { + // return null for the default so that it is not persisted + return null; + } + return value; + } catch (IllegalArgumentException e) { + throw new ConfigInvalidException( + String.format("Value '%s' not parseable as a Long", value), e); + } + } + private void saveAccountsSection(Config rc, Set keepGroups) { if (accountsSection != null) { rc.setStringList(ACCOUNTS, null, KEY_SAME_GROUP_VISIBILITY, diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProjectArgs.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProjectArgs.java index 7bbd2e7d2c..ea20ceac06 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProjectArgs.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/CreateProjectArgs.java @@ -35,6 +35,7 @@ public class CreateProjectArgs { public InheritableBoolean contentMerge; public InheritableBoolean changeIdRequired; public boolean createEmptyCommit; + public String maxObjectSizeLimit; public CreateProjectArgs() { contributorAgreements = InheritableBoolean.INHERIT; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/PerformCreateProject.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/PerformCreateProject.java index d68725ff37..29317440d6 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/PerformCreateProject.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/PerformCreateProject.java @@ -181,6 +181,7 @@ public class PerformCreateProject { newProject.setUseSignedOffBy(createProjectArgs.signedOffBy); newProject.setUseContentMerge(createProjectArgs.contentMerge); newProject.setRequireChangeID(createProjectArgs.changeIdRequired); + newProject.setMaxObjectSizeLimit(createProjectArgs.maxObjectSizeLimit); if (createProjectArgs.newParent != null) { newProject.setParentName(createProjectArgs.newParent.getProject() .getNameKey()); diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java index bd624ae747..89bb973f47 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java @@ -106,6 +106,9 @@ final class CreateProjectCommand extends SshCommand { @Option(name = "--empty-commit", usage = "to create initial empty commit") private boolean createEmptyCommit; + @Option(name = "--max-object-size-limit", usage = "max Git object size for this project") + private String maxObjectSizeLimit; + private String projectName; @Argument(index = 0, metaVar = "NAME", usage = "name of project to be created") @@ -143,6 +146,7 @@ final class CreateProjectCommand extends SshCommand { args.changeIdRequired = requireChangeID; args.branch = branch; args.createEmptyCommit = createEmptyCommit; + args.maxObjectSizeLimit = maxObjectSizeLimit; final PerformCreateProject createProject = factory.create(args); createProject.createProject(); diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java index 8c06c97d41..d512fd5566 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java @@ -108,6 +108,9 @@ final class SetProjectCommand extends SshCommand { @Option(name = "--project-state", aliases = {"--ps"}, usage = "project's visibility state") private State state; + @Option(name = "--max-object-size-limit", usage = "max Git object size for this project") + private String maxObjectSizeLimit; + @Inject private MetaDataUpdate.User metaDataUpdateFactory; @@ -148,6 +151,9 @@ final class SetProjectCommand extends SshCommand { if (state != null) { project.setState(state); } + if (maxObjectSizeLimit != null) { + project.setMaxObjectSizeLimit(maxObjectSizeLimit); + } md.setMessage("Project settings updated"); config.commit(md); } finally {