Merge branch 'stable-2.15'
* stable-2.15: BranchApi: Add missing throws declaration on NotImplemented#reflog FormatUtil: Fix Math#round() truncation error flagged by error-prone ReflogIT: Add test coverage for reflog permissions ChangeIT: Move reflog test to ReflogIT ChangeIT: Fix and expand reflog test BranchApi: Add method to get the branch's reflog GetReflog: Move ReflogEntryInfo to a separate class in extension API Fix http_archive rule in WORKSPACE ConfigInfoImpl: Return raw byte value for effective value TransferConfig: Move getEffectiveMaxObjectSizeLimit to ProjectState ProjectIT: Factor out a method to set the max object size limit Documentation: linux-quickstart - include Java 8 requirement Documentation: Include Java 8 requirement in installation notes Documentation: Remove 'install-quick' page in favour of 'linux-quickstart' Change-Id: I895790a8b2f9e8439e91c15ba4ee9a5a14a4ee94
This commit is contained in:
@@ -16,7 +16,8 @@ corporate installations. This is because there is no easy way to interact
|
|||||||
with the database while Gerrit is offline, it's not easy to backup the data,
|
with the database while Gerrit is offline, it's not easy to backup the data,
|
||||||
and it's not possible to set up H2 in a load balanced/hotswap configuration.
|
and it's not possible to set up H2 in a load balanced/hotswap configuration.
|
||||||
|
|
||||||
If this option interests you, you might want to consider link:install-quick.html[the quick guide].
|
If this option interests you, you might want to consider
|
||||||
|
link:linux-quickstart.html[the quick guide].
|
||||||
|
|
||||||
[[createdb_derby]]
|
[[createdb_derby]]
|
||||||
=== Apache Derby
|
=== Apache Derby
|
||||||
|
|||||||
@@ -1,234 +0,0 @@
|
|||||||
= Gerrit Code Review - Quick get started guide
|
|
||||||
|
|
||||||
****
|
|
||||||
This guide was made with the impatient in mind, ready to try out Gerrit on their
|
|
||||||
own server but not prepared to make the full installation procedure yet.
|
|
||||||
|
|
||||||
Explanation is sparse and you should not use a server installed this way in a
|
|
||||||
live setup, this is made with proof of concept activities in mind.
|
|
||||||
|
|
||||||
It is presumed you install it on a Unix based server such as any of the Linux
|
|
||||||
flavors or BSD.
|
|
||||||
|
|
||||||
It's also presumed that you have access to an OpenID enabled email address.
|
|
||||||
Examples of OpenID enable email providers are Gmail, Yahoo! Mail and Hotmail.
|
|
||||||
It's also possible to register a custom email address with OpenID, but that is
|
|
||||||
outside the scope of this quick installation guide. For testing purposes one of
|
|
||||||
the above providers should be fine. Please note that network access to the
|
|
||||||
OpenID provider you choose is necessary for both you and your Gerrit instance.
|
|
||||||
****
|
|
||||||
|
|
||||||
|
|
||||||
[[requirements]]
|
|
||||||
== Requirements
|
|
||||||
|
|
||||||
Most distributions come with Java today. Do you already have Java installed?
|
|
||||||
|
|
||||||
----
|
|
||||||
$ java -version
|
|
||||||
openjdk version "1.8.0_72"
|
|
||||||
OpenJDK Runtime Environment (build 1.8.0_72-b15)
|
|
||||||
OpenJDK 64-Bit Server VM (build 25.72-b15, mixed mode)
|
|
||||||
----
|
|
||||||
|
|
||||||
If Java isn't installed, get it:
|
|
||||||
|
|
||||||
* JRE, minimum version 1.8 http://www.oracle.com/technetwork/java/javase/downloads/index.html[Download]
|
|
||||||
|
|
||||||
|
|
||||||
[[user]]
|
|
||||||
== Create a user to host the Gerrit service
|
|
||||||
|
|
||||||
We will run the service as a non-privileged user on your system.
|
|
||||||
First create the user and then become the user:
|
|
||||||
|
|
||||||
----
|
|
||||||
$ sudo adduser gerrit
|
|
||||||
$ sudo su gerrit
|
|
||||||
----
|
|
||||||
|
|
||||||
If you don't have root privileges you could skip this step and run Gerrit
|
|
||||||
as your own user as well.
|
|
||||||
|
|
||||||
|
|
||||||
[[download]]
|
|
||||||
== Download Gerrit
|
|
||||||
|
|
||||||
It's time to download the archive that contains the Gerrit web and ssh service.
|
|
||||||
|
|
||||||
You can choose from different versions to download from here:
|
|
||||||
|
|
||||||
* https://www.gerritcodereview.com/download/index.html[A list of releases available]
|
|
||||||
|
|
||||||
This tutorial is based on version 2.2.2, and you can download that from this link
|
|
||||||
|
|
||||||
* https://www.gerritcodereview.com/download/gerrit-2.2.2.war[Link to the 2.2.2 war archive]
|
|
||||||
|
|
||||||
|
|
||||||
[[initialization]]
|
|
||||||
== Initialize the Site
|
|
||||||
|
|
||||||
It's time to run the initialization, and with the batch switch enabled, we don't have to answer any questions at all:
|
|
||||||
|
|
||||||
----
|
|
||||||
gerrit@host:~$ java -jar gerrit.war init --batch -d ~/gerrit_testsite
|
|
||||||
Generating SSH host key ... rsa(simple)... done
|
|
||||||
Initialized /home/gerrit/gerrit_testsite
|
|
||||||
Executing /home/gerrit/gerrit_testsite/bin/gerrit.sh start
|
|
||||||
Starting Gerrit Code Review: OK
|
|
||||||
gerrit@host:~$
|
|
||||||
----
|
|
||||||
|
|
||||||
When the init is complete, you can review your settings in the
|
|
||||||
file `'$site_path/etc/gerrit.config'`.
|
|
||||||
|
|
||||||
Note that initialization also starts the server. If any settings changes are
|
|
||||||
made, the server must be restarted before they will take effect.
|
|
||||||
|
|
||||||
----
|
|
||||||
gerrit@host:~$ ~/gerrit_testsite/bin/gerrit.sh restart
|
|
||||||
Stopping Gerrit Code Review: OK
|
|
||||||
Starting Gerrit Code Review: OK
|
|
||||||
gerrit@host:~$
|
|
||||||
----
|
|
||||||
|
|
||||||
The server can be also stopped and started by passing the `stop` and `start`
|
|
||||||
commands to gerrit.sh.
|
|
||||||
|
|
||||||
----
|
|
||||||
gerrit@host:~$ ~/gerrit_testsite/bin/gerrit.sh stop
|
|
||||||
Stopping Gerrit Code Review: OK
|
|
||||||
gerrit@host:~$
|
|
||||||
gerrit@host:~$ ~/gerrit_testsite/bin/gerrit.sh start
|
|
||||||
Starting Gerrit Code Review: OK
|
|
||||||
gerrit@host:~$
|
|
||||||
----
|
|
||||||
|
|
||||||
include::config-login-register.txt[]
|
|
||||||
|
|
||||||
== Project creation
|
|
||||||
|
|
||||||
Your base Gerrit server is now running and you have a user that's ready
|
|
||||||
to interact with it. You now have two options, either you create a new
|
|
||||||
test project to work with or you already have a git with history that
|
|
||||||
you would like to import into Gerrit and try out code review on.
|
|
||||||
|
|
||||||
=== New project from scratch
|
|
||||||
If you choose to create a new repository from scratch, it's easier for
|
|
||||||
you to create a project with an initial commit in it. That way first
|
|
||||||
time setup between client and server is easier.
|
|
||||||
|
|
||||||
This is done via the SSH port:
|
|
||||||
|
|
||||||
----
|
|
||||||
user@host:~$ ssh -p 29418 user@localhost gerrit create-project demo-project --empty-commit
|
|
||||||
user@host:~$
|
|
||||||
----
|
|
||||||
|
|
||||||
This will create a repository that you can clone to work with.
|
|
||||||
|
|
||||||
=== Already existing project
|
|
||||||
|
|
||||||
The other alternative is if you already have a git project that you
|
|
||||||
want to try out Gerrit on.
|
|
||||||
First you have to create the project. This is done via the SSH port:
|
|
||||||
|
|
||||||
----
|
|
||||||
user@host:~$ ssh -p 29418 user@localhost gerrit create-project demo-project
|
|
||||||
user@host:~$
|
|
||||||
----
|
|
||||||
|
|
||||||
You need to make sure that at least initially your account is granted
|
|
||||||
"Create Reference" privileges for the refs/heads/* reference.
|
|
||||||
This is done via the web interface in the Admin/Projects/Access page
|
|
||||||
that correspond to your project.
|
|
||||||
|
|
||||||
After that it's time to upload the previous history to the server:
|
|
||||||
|
|
||||||
----
|
|
||||||
user@host:~/my-project$ git push ssh://user@localhost:29418/demo-project *:*
|
|
||||||
Counting objects: 2011, done.
|
|
||||||
Writing objects: 100% (2011/2011), 456293 bytes, done.
|
|
||||||
Total 2011 (delta 0), reused 0 (delta 0)
|
|
||||||
To ssh://user@localhost:29418/demo-project
|
|
||||||
* [new branch] master -> master
|
|
||||||
user@host:~/my-project$
|
|
||||||
----
|
|
||||||
|
|
||||||
This will create a repository that you can clone to work with.
|
|
||||||
|
|
||||||
|
|
||||||
== My first change
|
|
||||||
|
|
||||||
Download a local clone of the repository and move into it
|
|
||||||
|
|
||||||
----
|
|
||||||
user@host:~$ git clone ssh://user@localhost:29418/demo-project
|
|
||||||
Cloning into demo-project...
|
|
||||||
remote: Counting objects: 2, done
|
|
||||||
remote: Finding sources: 100% (2/2)
|
|
||||||
remote: Total 2 (delta 0), reused 0 (delta 0)
|
|
||||||
user@host:~$ cd demo-project
|
|
||||||
user@host:~/demo-project$
|
|
||||||
----
|
|
||||||
|
|
||||||
Install the link:user-changeid.html[Change-Id commitmsg hook]
|
|
||||||
|
|
||||||
----
|
|
||||||
scp -p -P 29418 user@localhost:hooks/commit-msg $(git rev-parse --git-dir)/hooks/
|
|
||||||
----
|
|
||||||
|
|
||||||
Then make a change to the repository and upload it as a reviewable change
|
|
||||||
in Gerrit.
|
|
||||||
|
|
||||||
----
|
|
||||||
user@host:~/demo-project$ date > testfile.txt
|
|
||||||
user@host:~/demo-project$ git add testfile.txt
|
|
||||||
user@host:~/demo-project$ git commit -m "My pretty test commit"
|
|
||||||
[master ff643a5] My pretty test commit
|
|
||||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
|
||||||
create mode 100644 testfile.txt
|
|
||||||
user@host:~/demo-project$
|
|
||||||
----
|
|
||||||
|
|
||||||
Usually when you push to a remote git, you push to the reference
|
|
||||||
`'/refs/heads/branch'`, but when working with Gerrit you have to push to a
|
|
||||||
virtual branch representing "code review before submission to branch".
|
|
||||||
This virtual name space is known as /refs/for/<branch>
|
|
||||||
|
|
||||||
----
|
|
||||||
user@host:~/demo-project$ git push origin HEAD:refs/for/master
|
|
||||||
Counting objects: 4, done.
|
|
||||||
Writing objects: 100% (3/3), 293 bytes, done.
|
|
||||||
Total 3 (delta 0), reused 0 (delta 0)
|
|
||||||
remote:
|
|
||||||
remote: New Changes:
|
|
||||||
remote: http://localhost:8080/1
|
|
||||||
remote:
|
|
||||||
To ssh://user@localhost:29418/demo-project
|
|
||||||
* [new branch] HEAD -> refs/for/master
|
|
||||||
user@host:~/demo-project$
|
|
||||||
----
|
|
||||||
|
|
||||||
You should now be able to access your change by browsing to the http URL
|
|
||||||
suggested above, http://localhost:8080/1
|
|
||||||
|
|
||||||
|
|
||||||
== Quick Installation Complete
|
|
||||||
|
|
||||||
This covers the scope of getting Gerrit started and your first change uploaded.
|
|
||||||
It doesn't give any clue as to how the review workflow works, please read
|
|
||||||
link:http://source.android.com/source/life-of-a-patch[Default Workflow] to
|
|
||||||
learn more about the workflow of Gerrit.
|
|
||||||
|
|
||||||
To read more on the installation of Gerrit please see link:install.html[the detailed
|
|
||||||
installation page].
|
|
||||||
|
|
||||||
|
|
||||||
GERRIT
|
|
||||||
------
|
|
||||||
|
|
||||||
Part of link:index.html[Gerrit Code Review]
|
|
||||||
|
|
||||||
SEARCHBOX
|
|
||||||
---------
|
|
||||||
@@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
To run the Gerrit service, the following requirement must be met on the host:
|
To run the Gerrit service, the following requirement must be met on the host:
|
||||||
|
|
||||||
* JRE, minimum version 1.8 http://www.oracle.com/technetwork/java/javase/downloads/index.html[Download]
|
* JRE, version 1.8 http://www.oracle.com/technetwork/java/javase/downloads/index.html[Download]
|
||||||
|
+
|
||||||
|
Gerrit is not yet compatible with Java 9 or newer at this time.
|
||||||
|
|
||||||
By default, Gerrit uses link:note-db.html[NoteDB] as the storage backend. (If
|
By default, Gerrit uses link:note-db.html[NoteDB] as the storage backend. (If
|
||||||
desired, you can _optionally_ use an external database such as MySQL or
|
desired, you can _optionally_ use an external database such as MySQL or
|
||||||
|
|||||||
@@ -16,9 +16,11 @@ link:install.html[Standalone Daemon Installation Guide].
|
|||||||
|
|
||||||
Be sure you have:
|
Be sure you have:
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
. A Unix-based server, including any Linux flavor, MacOS, or Berkeley Software
|
. A Unix-based server, including any Linux flavor, MacOS, or Berkeley Software
|
||||||
Distribution (BSD).
|
Distribution (BSD).
|
||||||
. Java SE Runtime Environment 1.8 (or higher).
|
. Java SE Runtime Environment version 1.8. Gerrit is not compatible with Java
|
||||||
|
9 or newer yet.
|
||||||
|
|
||||||
== Download Gerrit
|
== Download Gerrit
|
||||||
|
|
||||||
|
|||||||
@@ -3435,7 +3435,7 @@ limit] of a project.
|
|||||||
|===============================
|
|===============================
|
||||||
|Field Name ||Description
|
|Field Name ||Description
|
||||||
|`value` |optional|
|
|`value` |optional|
|
||||||
The effective value of the max object size limit as a formatted string. +
|
The effective value in bytes of the max object size limit. +
|
||||||
Not set if there is no limit for the object size.
|
Not set if there is no limit for the object size.
|
||||||
|`configured_value`|optional|
|
|`configured_value`|optional|
|
||||||
The max object size limit that is configured on the project as a
|
The max object size limit that is configured on the project as a
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ http_archive(
|
|||||||
name = "io_bazel_rules_closure",
|
name = "io_bazel_rules_closure",
|
||||||
sha256 = "4dd84dd2bdd6c9f56cb5a475d504ea31d199c34309e202e9379501d01c3067e5",
|
sha256 = "4dd84dd2bdd6c9f56cb5a475d504ea31d199c34309e202e9379501d01c3067e5",
|
||||||
strip_prefix = "rules_closure-3103a773820b59b76345f94c231cb213e0d404e2",
|
strip_prefix = "rules_closure-3103a773820b59b76345f94c231cb213e0d404e2",
|
||||||
url = "https://github.com/bazelbuild/rules_closure/archive/3103a773820b59b76345f94c231cb213e0d404e2.tar.gz",
|
urls = ["https://github.com/bazelbuild/rules_closure/archive/3103a773820b59b76345f94c231cb213e0d404e2.tar.gz"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# File is specific to Polymer and copied from the Closure Github -- should be
|
# File is specific to Polymer and copied from the Closure Github -- should be
|
||||||
|
|||||||
@@ -126,7 +126,25 @@ public class FormatUtil {
|
|||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
return Resources.C.notAvailable();
|
return Resources.C.notAvailable();
|
||||||
}
|
}
|
||||||
int p = Math.abs(Math.round(delta * 100 / size));
|
int p = Math.abs(saturatedCast(delta * 100 / size));
|
||||||
return p + "%";
|
return p + "%";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@code int} nearest in value to {@code value}.
|
||||||
|
*
|
||||||
|
* @param value any {@code long} value
|
||||||
|
* @return the same value cast to {@code int} if it is in the range of the {@code int} type,
|
||||||
|
* {@link Integer#MAX_VALUE} if it is too large, or {@link Integer#MIN_VALUE} if it is too
|
||||||
|
* small
|
||||||
|
*/
|
||||||
|
private static int saturatedCast(long value) {
|
||||||
|
if (value > Integer.MAX_VALUE) {
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
if (value < Integer.MIN_VALUE) {
|
||||||
|
return Integer.MIN_VALUE;
|
||||||
|
}
|
||||||
|
return (int) value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ public interface AdminMessages extends Messages {
|
|||||||
|
|
||||||
String globalMaxObjectSizeLimit(String globalMaxObjectSizeLimit);
|
String globalMaxObjectSizeLimit(String globalMaxObjectSizeLimit);
|
||||||
|
|
||||||
|
String noMaxObjectSizeLimit();
|
||||||
|
|
||||||
String pluginProjectOptionsTitle(String pluginName);
|
String pluginProjectOptionsTitle(String pluginName);
|
||||||
|
|
||||||
String pluginProjectInheritedValue(String value);
|
String pluginProjectInheritedValue(String value);
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ project = Project {0}
|
|||||||
deletedGroup = Deleted Group {0}
|
deletedGroup = Deleted Group {0}
|
||||||
deletedReference = Reference {0} was deleted
|
deletedReference = Reference {0} was deleted
|
||||||
deletedSection = Section {0} was deleted
|
deletedSection = Section {0} was deleted
|
||||||
effectiveMaxObjectSizeLimit = effective: {0}
|
effectiveMaxObjectSizeLimit = effective: {0} bytes
|
||||||
globalMaxObjectSizeLimit = The global max object size limit is set to {0}. The limit cannot be increased on project level.
|
globalMaxObjectSizeLimit = The global max object size limit is set to {0}. The limit cannot be increased on project level.
|
||||||
|
noMaxObjectSizeLimit = No max object size limit is set.
|
||||||
pluginProjectOptionsTitle = {0} Plugin Options
|
pluginProjectOptionsTitle = {0} Plugin Options
|
||||||
pluginProjectOptionsTitle = {0} Plugin
|
pluginProjectOptionsTitle = {0} Plugin
|
||||||
pluginProjectInheritedValue = inherited: {0}
|
pluginProjectInheritedValue = inherited: {0}
|
||||||
|
|||||||
@@ -439,14 +439,15 @@ public class ProjectInfoScreen extends ProjectScreen {
|
|||||||
setSubmitType(result.defaultSubmitType());
|
setSubmitType(result.defaultSubmitType());
|
||||||
setState(result.state());
|
setState(result.state());
|
||||||
maxObjectSizeLimit.setText(result.maxObjectSizeLimit().configuredValue());
|
maxObjectSizeLimit.setText(result.maxObjectSizeLimit().configuredValue());
|
||||||
if (result.maxObjectSizeLimit().inheritedValue() != null) {
|
if (result.maxObjectSizeLimit().value() != null) {
|
||||||
effectiveMaxObjectSizeLimit.setVisible(true);
|
|
||||||
effectiveMaxObjectSizeLimit.setText(
|
effectiveMaxObjectSizeLimit.setText(
|
||||||
AdminMessages.I.effectiveMaxObjectSizeLimit(result.maxObjectSizeLimit().value()));
|
AdminMessages.I.effectiveMaxObjectSizeLimit(result.maxObjectSizeLimit().value()));
|
||||||
|
if (result.maxObjectSizeLimit().inheritedValue() != null) {
|
||||||
effectiveMaxObjectSizeLimit.setTitle(
|
effectiveMaxObjectSizeLimit.setTitle(
|
||||||
AdminMessages.I.globalMaxObjectSizeLimit(result.maxObjectSizeLimit().inheritedValue()));
|
AdminMessages.I.globalMaxObjectSizeLimit(result.maxObjectSizeLimit().inheritedValue()));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
effectiveMaxObjectSizeLimit.setVisible(false);
|
effectiveMaxObjectSizeLimit.setText(AdminMessages.I.noMaxObjectSizeLimit());
|
||||||
}
|
}
|
||||||
|
|
||||||
saveProject.setEnabled(false);
|
saveProject.setEnabled(false);
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ package com.google.gerrit.server.git;
|
|||||||
|
|
||||||
import com.google.gerrit.server.config.ConfigUtil;
|
import com.google.gerrit.server.config.ConfigUtil;
|
||||||
import com.google.gerrit.server.config.GerritServerConfig;
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
import com.google.gerrit.server.project.ProjectState;
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -66,14 +65,4 @@ public class TransferConfig {
|
|||||||
public String getFormattedMaxObjectSizeLimit() {
|
public String getFormattedMaxObjectSizeLimit() {
|
||||||
return maxObjectSizeLimitFormatted;
|
return maxObjectSizeLimitFormatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getEffectiveMaxObjectSizeLimit(ProjectState p) {
|
|
||||||
long global = getMaxObjectSizeLimit();
|
|
||||||
long local = p.getMaxObjectSizeLimit();
|
|
||||||
if (global > 0 && local > 0) {
|
|
||||||
return Math.min(global, local);
|
|
||||||
}
|
|
||||||
// zero means "no limit", in this case the max is more limiting
|
|
||||||
return Math.max(global, local);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ public class AsyncReceiveCommits implements PreReceiveHook {
|
|||||||
receivePack.setAllowNonFastForwards(true);
|
receivePack.setAllowNonFastForwards(true);
|
||||||
receivePack.setRefLogIdent(user.newRefLogIdent());
|
receivePack.setRefLogIdent(user.newRefLogIdent());
|
||||||
receivePack.setTimeout(transferConfig.getTimeout());
|
receivePack.setTimeout(transferConfig.getTimeout());
|
||||||
receivePack.setMaxObjectSizeLimit(transferConfig.getEffectiveMaxObjectSizeLimit(projectState));
|
receivePack.setMaxObjectSizeLimit(projectState.getEffectiveMaxObjectSizeLimit());
|
||||||
receivePack.setCheckReceivedObjects(projectState.getConfig().getCheckReceivedObjects());
|
receivePack.setCheckReceivedObjects(projectState.getConfig().getCheckReceivedObjects());
|
||||||
receivePack.setRefFilter(new ReceiveRefFilter());
|
receivePack.setRefFilter(new ReceiveRefFilter());
|
||||||
receivePack.setAllowPushOptions(true);
|
receivePack.setAllowPushOptions(true);
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import com.google.gerrit.server.config.AllUsersName;
|
|||||||
import com.google.gerrit.server.config.SitePaths;
|
import com.google.gerrit.server.config.SitePaths;
|
||||||
import com.google.gerrit.server.git.BranchOrderSection;
|
import com.google.gerrit.server.git.BranchOrderSection;
|
||||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
|
import com.google.gerrit.server.git.TransferConfig;
|
||||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
@@ -87,6 +88,7 @@ public class ProjectState {
|
|||||||
private final ProjectConfig config;
|
private final ProjectConfig config;
|
||||||
private final Map<String, ProjectLevelConfig> configs;
|
private final Map<String, ProjectLevelConfig> configs;
|
||||||
private final Set<AccountGroup.UUID> localOwners;
|
private final Set<AccountGroup.UUID> localOwners;
|
||||||
|
private final long globalMaxObjectSizeLimit;
|
||||||
|
|
||||||
/** Last system time the configuration's revision was examined. */
|
/** Last system time the configuration's revision was examined. */
|
||||||
private volatile long lastCheckGeneration;
|
private volatile long lastCheckGeneration;
|
||||||
@@ -114,6 +116,7 @@ public class ProjectState {
|
|||||||
GitRepositoryManager gitMgr,
|
GitRepositoryManager gitMgr,
|
||||||
List<CommentLinkInfo> commentLinks,
|
List<CommentLinkInfo> commentLinks,
|
||||||
CapabilityCollection.Factory limitsFactory,
|
CapabilityCollection.Factory limitsFactory,
|
||||||
|
TransferConfig transferConfig,
|
||||||
@Assisted ProjectConfig config) {
|
@Assisted ProjectConfig config) {
|
||||||
this.sitePaths = sitePaths;
|
this.sitePaths = sitePaths;
|
||||||
this.projectCache = projectCache;
|
this.projectCache = projectCache;
|
||||||
@@ -128,6 +131,7 @@ public class ProjectState {
|
|||||||
isAllProjects
|
isAllProjects
|
||||||
? limitsFactory.create(config.getAccessSection(AccessSection.GLOBAL_CAPABILITIES))
|
? limitsFactory.create(config.getAccessSection(AccessSection.GLOBAL_CAPABILITIES))
|
||||||
: null;
|
: null;
|
||||||
|
this.globalMaxObjectSizeLimit = transferConfig.getMaxObjectSizeLimit();
|
||||||
|
|
||||||
if (isAllProjects && !Permission.canBeOnAllProjects(AccessSection.ALL, Permission.OWNER)) {
|
if (isAllProjects && !Permission.canBeOnAllProjects(AccessSection.ALL, Permission.OWNER)) {
|
||||||
localOwners = Collections.emptySet();
|
localOwners = Collections.emptySet();
|
||||||
@@ -260,6 +264,15 @@ public class ProjectState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getEffectiveMaxObjectSizeLimit() {
|
||||||
|
long local = getMaxObjectSizeLimit();
|
||||||
|
if (globalMaxObjectSizeLimit > 0 && local > 0) {
|
||||||
|
return Math.min(globalMaxObjectSizeLimit, local);
|
||||||
|
}
|
||||||
|
// zero means "no limit", in this case the max is more limiting
|
||||||
|
return Math.max(globalMaxObjectSizeLimit, local);
|
||||||
|
}
|
||||||
|
|
||||||
/** Get the sections that pertain only to this project. */
|
/** Get the sections that pertain only to this project. */
|
||||||
List<SectionMatcher> getLocalAccessSections() {
|
List<SectionMatcher> getLocalAccessSections() {
|
||||||
List<SectionMatcher> sm = localAccessSections;
|
List<SectionMatcher> sm = localAccessSections;
|
||||||
|
|||||||
@@ -110,11 +110,8 @@ public class ConfigInfoImpl extends ConfigInfo {
|
|||||||
private MaxObjectSizeLimitInfo getMaxObjectSizeLimit(
|
private MaxObjectSizeLimitInfo getMaxObjectSizeLimit(
|
||||||
ProjectState projectState, TransferConfig transferConfig, Project p) {
|
ProjectState projectState, TransferConfig transferConfig, Project p) {
|
||||||
MaxObjectSizeLimitInfo info = new MaxObjectSizeLimitInfo();
|
MaxObjectSizeLimitInfo info = new MaxObjectSizeLimitInfo();
|
||||||
info.value =
|
long value = projectState.getEffectiveMaxObjectSizeLimit();
|
||||||
transferConfig.getEffectiveMaxObjectSizeLimit(projectState)
|
info.value = value == 0 ? null : String.valueOf(value);
|
||||||
== transferConfig.getMaxObjectSizeLimit()
|
|
||||||
? transferConfig.getFormattedMaxObjectSizeLimit()
|
|
||||||
: p.getMaxObjectSizeLimit();
|
|
||||||
info.configuredValue = p.getMaxObjectSizeLimit();
|
info.configuredValue = p.getMaxObjectSizeLimit();
|
||||||
info.inheritedValue = transferConfig.getFormattedMaxObjectSizeLimit();
|
info.inheritedValue = transferConfig.getFormattedMaxObjectSizeLimit();
|
||||||
return info;
|
return info;
|
||||||
|
|||||||
@@ -422,16 +422,13 @@ public class ProjectIT extends AbstractDaemonTest {
|
|||||||
@Test
|
@Test
|
||||||
public void maxObjectSizeCanBeSetAndCleared() throws Exception {
|
public void maxObjectSizeCanBeSetAndCleared() throws Exception {
|
||||||
// Set a value
|
// Set a value
|
||||||
ConfigInput input = new ConfigInput();
|
ConfigInfo info = setMaxObjectSize("100k");
|
||||||
input.maxObjectSizeLimit = "100k";
|
assertThat(info.maxObjectSizeLimit.value).isEqualTo("102400");
|
||||||
ConfigInfo info = setConfig(input);
|
|
||||||
assertThat(info.maxObjectSizeLimit.value).isEqualTo("100k");
|
|
||||||
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k");
|
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k");
|
||||||
assertThat(info.maxObjectSizeLimit.inheritedValue).isNull();
|
assertThat(info.maxObjectSizeLimit.inheritedValue).isNull();
|
||||||
|
|
||||||
// Clear the value
|
// Clear the value
|
||||||
input.maxObjectSizeLimit = "0";
|
info = setMaxObjectSize("0");
|
||||||
info = setConfig(input);
|
|
||||||
assertThat(info.maxObjectSizeLimit.value).isNull();
|
assertThat(info.maxObjectSizeLimit.value).isNull();
|
||||||
assertThat(info.maxObjectSizeLimit.configuredValue).isNull();
|
assertThat(info.maxObjectSizeLimit.configuredValue).isNull();
|
||||||
assertThat(info.maxObjectSizeLimit.inheritedValue).isNull();
|
assertThat(info.maxObjectSizeLimit.inheritedValue).isNull();
|
||||||
@@ -441,9 +438,8 @@ public class ProjectIT extends AbstractDaemonTest {
|
|||||||
public void maxObjectSizeIsNotInheritedFromParentProject() throws Exception {
|
public void maxObjectSizeIsNotInheritedFromParentProject() throws Exception {
|
||||||
Project.NameKey child = createProject(name("child"), project);
|
Project.NameKey child = createProject(name("child"), project);
|
||||||
|
|
||||||
ConfigInput input = new ConfigInput();
|
ConfigInfo info = setMaxObjectSize("100k");
|
||||||
input.maxObjectSizeLimit = "100k";
|
assertThat(info.maxObjectSizeLimit.value).isEqualTo("102400");
|
||||||
ConfigInfo info = setConfig(input);
|
|
||||||
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k");
|
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k");
|
||||||
assertThat(info.maxObjectSizeLimit.inheritedValue).isNull();
|
assertThat(info.maxObjectSizeLimit.inheritedValue).isNull();
|
||||||
|
|
||||||
@@ -457,7 +453,7 @@ public class ProjectIT extends AbstractDaemonTest {
|
|||||||
@GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k")
|
@GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k")
|
||||||
public void maxObjectSizeIsInheritedFromGlobalConfig() throws Exception {
|
public void maxObjectSizeIsInheritedFromGlobalConfig() throws Exception {
|
||||||
ConfigInfo info = getConfig();
|
ConfigInfo info = getConfig();
|
||||||
assertThat(info.maxObjectSizeLimit.value).isEqualTo("200k");
|
assertThat(info.maxObjectSizeLimit.value).isEqualTo("204800");
|
||||||
assertThat(info.maxObjectSizeLimit.configuredValue).isNull();
|
assertThat(info.maxObjectSizeLimit.configuredValue).isNull();
|
||||||
assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k");
|
assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k");
|
||||||
}
|
}
|
||||||
@@ -465,10 +461,8 @@ public class ProjectIT extends AbstractDaemonTest {
|
|||||||
@Test
|
@Test
|
||||||
@GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k")
|
@GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k")
|
||||||
public void maxObjectSizeOverridesGlobalConfigWhenLower() throws Exception {
|
public void maxObjectSizeOverridesGlobalConfigWhenLower() throws Exception {
|
||||||
ConfigInput input = new ConfigInput();
|
ConfigInfo info = setMaxObjectSize("100k");
|
||||||
input.maxObjectSizeLimit = "100k";
|
assertThat(info.maxObjectSizeLimit.value).isEqualTo("102400");
|
||||||
ConfigInfo info = setConfig(input);
|
|
||||||
assertThat(info.maxObjectSizeLimit.value).isEqualTo("100k");
|
|
||||||
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k");
|
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k");
|
||||||
assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k");
|
assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k");
|
||||||
}
|
}
|
||||||
@@ -476,21 +470,17 @@ public class ProjectIT extends AbstractDaemonTest {
|
|||||||
@Test
|
@Test
|
||||||
@GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k")
|
@GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k")
|
||||||
public void maxObjectSizeDoesNotOverrideGlobalConfigWhenHigher() throws Exception {
|
public void maxObjectSizeDoesNotOverrideGlobalConfigWhenHigher() throws Exception {
|
||||||
ConfigInput input = new ConfigInput();
|
ConfigInfo info = setMaxObjectSize("300k");
|
||||||
input.maxObjectSizeLimit = "300k";
|
assertThat(info.maxObjectSizeLimit.value).isEqualTo("204800");
|
||||||
ConfigInfo info = setConfig(input);
|
|
||||||
assertThat(info.maxObjectSizeLimit.value).isEqualTo("200k");
|
|
||||||
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("300k");
|
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("300k");
|
||||||
assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k");
|
assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void invalidMaxObjectSizeIsRejected() throws Exception {
|
public void invalidMaxObjectSizeIsRejected() throws Exception {
|
||||||
ConfigInput input = new ConfigInput();
|
|
||||||
input.maxObjectSizeLimit = "100 foo";
|
|
||||||
exception.expect(ResourceConflictException.class);
|
exception.expect(ResourceConflictException.class);
|
||||||
exception.expectMessage("100 foo");
|
exception.expectMessage("100 foo");
|
||||||
setConfig(input);
|
setMaxObjectSize("100 foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConfigInfo setConfig(Project.NameKey name, ConfigInput input) throws Exception {
|
private ConfigInfo setConfig(Project.NameKey name, ConfigInput input) throws Exception {
|
||||||
@@ -526,6 +516,12 @@ public class ProjectIT extends AbstractDaemonTest {
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ConfigInfo setMaxObjectSize(String value) throws Exception {
|
||||||
|
ConfigInput input = new ConfigInput();
|
||||||
|
input.maxObjectSizeLimit = value;
|
||||||
|
return setConfig(input);
|
||||||
|
}
|
||||||
|
|
||||||
private static class ProjectIndexedCounter implements ProjectIndexedListener {
|
private static class ProjectIndexedCounter implements ProjectIndexedListener {
|
||||||
private final AtomicLongMap<String> countsByProject = AtomicLongMap.create();
|
private final AtomicLongMap<String> countsByProject = AtomicLongMap.create();
|
||||||
|
|
||||||
|
|||||||
@@ -21,10 +21,15 @@ import static com.google.gerrit.reviewdb.client.RefNames.changeMetaRef;
|
|||||||
import com.google.gerrit.acceptance.AbstractDaemonTest;
|
import com.google.gerrit.acceptance.AbstractDaemonTest;
|
||||||
import com.google.gerrit.acceptance.PushOneCommit;
|
import com.google.gerrit.acceptance.PushOneCommit;
|
||||||
import com.google.gerrit.acceptance.UseLocalDisk;
|
import com.google.gerrit.acceptance.UseLocalDisk;
|
||||||
|
import com.google.gerrit.common.data.Permission;
|
||||||
import com.google.gerrit.extensions.api.changes.ReviewInput;
|
import com.google.gerrit.extensions.api.changes.ReviewInput;
|
||||||
|
import com.google.gerrit.extensions.api.groups.GroupApi;
|
||||||
import com.google.gerrit.extensions.api.projects.BranchApi;
|
import com.google.gerrit.extensions.api.projects.BranchApi;
|
||||||
import com.google.gerrit.extensions.api.projects.ReflogEntryInfo;
|
import com.google.gerrit.extensions.api.projects.ReflogEntryInfo;
|
||||||
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.Change;
|
import com.google.gerrit.reviewdb.client.Change;
|
||||||
|
import com.google.gerrit.server.project.testing.Util;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.eclipse.jgit.lib.ReflogEntry;
|
import org.eclipse.jgit.lib.ReflogEntry;
|
||||||
@@ -74,4 +79,32 @@ public class ReflogIT extends AbstractDaemonTest {
|
|||||||
reflog = branchApi.reflog();
|
reflog = branchApi.reflog();
|
||||||
assertThat(reflog).hasSize(refLogLen + 1);
|
assertThat(reflog).hasSize(refLogLen + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void regularUserIsNotAllowedToGetReflog() throws Exception {
|
||||||
|
setApiUser(user);
|
||||||
|
exception.expect(AuthException.class);
|
||||||
|
gApi.projects().name(project.get()).branch("master").reflog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ownerUserIsAllowedToGetReflog() throws Exception {
|
||||||
|
GroupApi groupApi = gApi.groups().create(name("get-reflog"));
|
||||||
|
groupApi.addMembers("user");
|
||||||
|
|
||||||
|
try (ProjectConfigUpdate u = updateProject(project)) {
|
||||||
|
Util.allow(
|
||||||
|
u.getConfig(), Permission.OWNER, new AccountGroup.UUID(groupApi.get().id), "refs/*");
|
||||||
|
u.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
setApiUser(user);
|
||||||
|
gApi.projects().name(project.get()).branch("master").reflog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void adminUserIsAllowedToGetReflog() throws Exception {
|
||||||
|
setApiUser(admin);
|
||||||
|
gApi.projects().name(project.get()).branch("master").reflog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ import com.google.gerrit.server.config.AllProjectsNameProvider;
|
|||||||
import com.google.gerrit.server.config.AllUsersName;
|
import com.google.gerrit.server.config.AllUsersName;
|
||||||
import com.google.gerrit.server.config.AllUsersNameProvider;
|
import com.google.gerrit.server.config.AllUsersNameProvider;
|
||||||
import com.google.gerrit.server.config.SitePaths;
|
import com.google.gerrit.server.config.SitePaths;
|
||||||
|
import com.google.gerrit.server.git.TransferConfig;
|
||||||
import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener;
|
import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener;
|
||||||
import com.google.gerrit.server.project.ProjectCache;
|
import com.google.gerrit.server.project.ProjectCache;
|
||||||
import com.google.gerrit.server.project.ProjectConfig;
|
import com.google.gerrit.server.project.ProjectConfig;
|
||||||
@@ -204,6 +205,7 @@ public class RefControlTest {
|
|||||||
@Inject private ThreadLocalRequestContext requestContext;
|
@Inject private ThreadLocalRequestContext requestContext;
|
||||||
@Inject private DefaultRefFilter.Factory refFilterFactory;
|
@Inject private DefaultRefFilter.Factory refFilterFactory;
|
||||||
@Inject private IdentifiedUser.GenericFactory identifiedUserFactory;
|
@Inject private IdentifiedUser.GenericFactory identifiedUserFactory;
|
||||||
|
@Inject private TransferConfig transferConfig;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
@@ -971,6 +973,7 @@ public class RefControlTest {
|
|||||||
repoManager,
|
repoManager,
|
||||||
commentLinks,
|
commentLinks,
|
||||||
capabilityCollectionFactory,
|
capabilityCollectionFactory,
|
||||||
|
transferConfig,
|
||||||
pc));
|
pc));
|
||||||
return repo;
|
return repo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ One-time setup:
|
|||||||
|
|
||||||
1. [Build Gerrit](https://gerrit-review.googlesource.com/Documentation/dev-bazel.html#_gerrit_development_war_file)
|
1. [Build Gerrit](https://gerrit-review.googlesource.com/Documentation/dev-bazel.html#_gerrit_development_war_file)
|
||||||
2. Set up a local test site. Docs
|
2. Set up a local test site. Docs
|
||||||
[here](https://gerrit-review.googlesource.com/Documentation/install-quick.html) and
|
[here](https://gerrit-review.googlesource.com/Documentation/linux-quickstart.html) and
|
||||||
[here](https://gerrit-review.googlesource.com/Documentation/dev-readme.html#init).
|
[here](https://gerrit-review.googlesource.com/Documentation/dev-readme.html#init).
|
||||||
|
|
||||||
When your project is set up and works using the classic UI, run a test server
|
When your project is set up and works using the classic UI, run a test server
|
||||||
|
|||||||
Reference in New Issue
Block a user