Merge "Permit plugins to implement AllRequestFilter"
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 5522239..4c64dfe 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -76,6 +76,7 @@
@$(ASCIIDOC) -a toc \
-a data-uri \
-a 'revision=$(REVISION)' \
+ -a 'newline=\n' \
-b xhtml11 \
-f asciidoc.conf \
$(ASCIIDOC_EXTRA) \
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
index 23f6e72..7027562 100644
--- a/Documentation/access-control.txt
+++ b/Documentation/access-control.txt
@@ -452,6 +452,9 @@
to projects in Gerrit. It can give permission to abandon a specific
change to a given ref.
+This also grants the permission to restore a change if the change
+can be uploaded.
+
[[category_create]]
Create reference
~~~~~~~~~~~~~~~~
diff --git a/Documentation/cmd-cherry-pick.txt b/Documentation/cmd-cherry-pick.txt
index 568c872..d051a9a 100644
--- a/Documentation/cmd-cherry-pick.txt
+++ b/Documentation/cmd-cherry-pick.txt
@@ -39,7 +39,7 @@
====
$ scp -p -P 29418 john.doe@review.example.com:bin/gerrit-cherry-pick ~/bin/
- $ curl http://review.example.com/tools/bin/gerrit-cherry-pick
+ $ curl -o ~/bin/gerrit-cherry-pick http://review.example.com/tools/bin/gerrit-cherry-pick
====
GERRIT
diff --git a/Documentation/cmd-create-group.txt b/Documentation/cmd-create-group.txt
index 8d404ec..8dc6dcc 100644
--- a/Documentation/cmd-create-group.txt
+++ b/Documentation/cmd-create-group.txt
@@ -9,8 +9,8 @@
--------
[verse]
'ssh' -p <port> <host> 'gerrit create-group'
- [--owner <GROUP>]
- [--description <DESC>]
+ [--owner <GROUP> | -o <GROUP>]
+ [--description <DESC> | -d <DESC>]
[--member <USERNAME>]
[--group <GROUP>]
[--visible-to-all]
diff --git a/Documentation/cmd-create-project.txt b/Documentation/cmd-create-project.txt
index 02aa078..d0e56fd 100644
--- a/Documentation/cmd-create-project.txt
+++ b/Documentation/cmd-create-project.txt
@@ -14,7 +14,7 @@
[--suggest-parents | -S ]
[--permissions-only]
[--description <DESC> | -d <DESC>]
- [--submit-type <TYPE> | -t <TYPE>]
+ [--submit-type <TYPE> | -t <TYPE>]
[--use-contributor-agreements | --ca]
[--use-signed-off-by | --so]
[--use-content-merge]
diff --git a/Documentation/cmd-index.txt b/Documentation/cmd-index.txt
index 4c0560e..c4f222b 100644
--- a/Documentation/cmd-index.txt
+++ b/Documentation/cmd-index.txt
@@ -12,8 +12,8 @@
$ scp -p -P 29418 john.doe@review.example.com:bin/gerrit-cherry-pick ~/bin/
$ scp -p -P 29418 john.doe@review.example.com:hooks/commit-msg .git/hooks/
- $ curl http://review.example.com/tools/bin/gerrit-cherry-pick
- $ curl http://review.example.com/tools/hooks/commit-msg
+ $ curl -o ~/bin/gerrit-cherry-pick http://review.example.com/tools/bin/gerrit-cherry-pick
+ $ curl -o .git/hooks/commit-msg http://review.example.com/tools/hooks/commit-msg
For more details on how to determine the correct SSH port number,
see link:user-upload.html#test_ssh[Testing Your SSH Connection].
diff --git a/Documentation/cmd-ls-groups.txt b/Documentation/cmd-ls-groups.txt
index a50657b..306bb92 100644
--- a/Documentation/cmd-ls-groups.txt
+++ b/Documentation/cmd-ls-groups.txt
@@ -9,10 +9,11 @@
--------
[verse]
'ssh' -p <port> <host> 'gerrit ls-groups'
- [--project <NAME>]
- [--user <NAME>]
+ [--project <NAME> | -p <NAME>]
+ [--user <NAME> | -u <NAME>]
[--visible-to-all]
- [--type {internal | ldap | system}]
+ [--type {internal | system}]
+ [--verbose | -v]
DESCRIPTION
-----------
diff --git a/Documentation/cmd-ls-projects.txt b/Documentation/cmd-ls-projects.txt
index 25cd9a9..d7d5aa5 100644
--- a/Documentation/cmd-ls-projects.txt
+++ b/Documentation/cmd-ls-projects.txt
@@ -10,8 +10,12 @@
[verse]
'ssh' -p <port> <host> 'gerrit ls-projects'
[--show-branch <BRANCH> ...]
- [--tree]
+ [--description | -d]
+ [--tree | -t]
[--type {code | permissions | all}]
+ [--format {text | json | json_compact}]
+ [--all]
+ [--limit <N>]
DESCRIPTION
-----------
@@ -42,7 +46,7 @@
whole project is not shown.
--description::
---d::
+-d::
Allows listing of projects together with their respective
description.
+
diff --git a/Documentation/cmd-receive-pack.txt b/Documentation/cmd-receive-pack.txt
index 7e5ca09..68f686d 100644
--- a/Documentation/cmd-receive-pack.txt
+++ b/Documentation/cmd-receive-pack.txt
@@ -8,7 +8,10 @@
SYNOPSIS
--------
[verse]
-'git receive-pack' [--reviewer <address>] [--cc <address>] <project>
+'git receive-pack'
+ [--reviewer <address> | --re <address>]
+ [--cc <address>]
+ <project>
DESCRIPTION
-----------
diff --git a/Documentation/cmd-review.txt b/Documentation/cmd-review.txt
index ac613e5..fdb5273 100644
--- a/Documentation/cmd-review.txt
+++ b/Documentation/cmd-review.txt
@@ -9,10 +9,10 @@
--------
[verse]
'ssh' -p <port> <host> 'gerrit review'
- [--project <PROJECT>]
- [--message <MESSAGE>]
+ [--project <PROJECT> | -p <PROJECT>]
+ [--message <MESSAGE> | -m <MESSAGE>]
[--force-message]
- [--submit]
+ [--submit | -s]
[--abandon | --restore]
[--publish]
[--delete]
@@ -52,7 +52,7 @@
--force-message::
Option which allows Gerrit to publish the --message, even
- when the labels could not be applied due to change being
+ when the labels could not be applied due to the change being
closed).
+
Used by some scripts/CI-systems, where the results (or links
@@ -69,11 +69,11 @@
complete listing of supported approval categories and values.
--abandon::
- Abandon the specified patch set(s).
+ Abandon the specified change(s).
(option is mutually exclusive with --submit and --restore)
--restore::
- Restore the specified abandoned patch set(s).
+ Restore the specified abandoned change(s).
(option is mutually exclusive with --abandon)
--submit::
diff --git a/Documentation/cmd-set-project.txt b/Documentation/cmd-set-project.txt
index c4b9b4f..059f063 100644
--- a/Documentation/cmd-set-project.txt
+++ b/Documentation/cmd-set-project.txt
@@ -10,7 +10,7 @@
[verse]
'ssh' -p <port> <host> 'gerrit set-project'
[--description <DESC> | -d <DESC>]
- [--submit-type <TYPE> | -t <TYPE>]
+ [--submit-type <TYPE> | -t <TYPE>]
[--use|no-contributor-agreements | --ca|nca]
[--use|no-signed-off-by | --so|nso]
[--use|no-content-merge]
diff --git a/Documentation/cmd-set-reviewers.txt b/Documentation/cmd-set-reviewers.txt
index 9e08e39..32fd35e 100644
--- a/Documentation/cmd-set-reviewers.txt
+++ b/Documentation/cmd-set-reviewers.txt
@@ -9,9 +9,9 @@
--------
[verse]
'ssh' -p <port> <host> 'gerrit set-reviewers'
- [--project <PROJECT>]
- [--add REVIEWER ...]
- [--remove REVIEWER ...]
+ [--project <PROJECT> | -p <PROJECT>]
+ [--add <REVIEWER> ... | -a <REVIEWER> ...]
+ [--remove <REVIEWER> ... | -r <REVIEWER> ...]
[--]
{COMMIT | CHANGE-ID}...
diff --git a/Documentation/cmd-show-connections.txt b/Documentation/cmd-show-connections.txt
index b5d41bd..8404a97 100644
--- a/Documentation/cmd-show-connections.txt
+++ b/Documentation/cmd-show-connections.txt
@@ -8,7 +8,7 @@
SYNOPSIS
--------
[verse]
-'ssh' -p <port> <host> 'gerrit show-connections' [-n]
+'ssh' -p <port> <host> 'gerrit show-connections' [--numeric | -n]
DESCRIPTION
-----------
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index cb70254..8610dba 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -88,6 +88,12 @@
provider chosen by the end-user. For more information see
http://openid.net/[openid.net].
+
+* `OpenID_SSO`
++
+Supports OpenID from a single provider. There is no registration
+link, and the "Sign In" link sends the user directly to the provider's
+SSO entry point.
++
* `HTTP`
+
Gerrit relies upon data presented in the HTTP request. This includes
@@ -229,6 +235,13 @@
+
Default is 12 hours.
+[[auth.openIdSsoUrl]]auth.openIdSsoUrl::
++
+The SSO entry point URL. Only used if `auth.type` was set to
+OpenID_SSO.
++
+The "Sign In" link will send users directly to this URL.
+
[[auth.httpHeader]]auth.httpHeader::
+
HTTP header to trust the username from, or unset to select HTTP basic
@@ -2237,6 +2250,31 @@
+
By default a shade of yellow, `FFFFCC`.
+[[theme.changeTableOutdatedColor]]theme.changeTableOutdatedColor::
++
+Background color used for patch outdated messages. The value must be
+a valid HTML hex color code, or standard color name.
++
+By default a shade of red, `FF0000`.
+
+[[theme.tableOddRowColor]]theme.tableOddRowColor::
++
+Background color for tables such as lists of open reviews for odd
+rows. This is so you can have a different color for odd and even
+rows of the table. The value must be a valid HTML hex color code,
+or standard color name.
++
+By default transparent.
+
+[[theme.tableEvenRowColor]]theme.tableEvenRowColor::
++
+Background color for tables such as lists of open reviews for even
+rows. This is so you can have a different color for odd and even
+rows of the table. The value must be a valid HTML hex color code,
+or standard color name.
++
+By default transparent.
+
A different theme may be used for signed-in vs. signed-out user status
by using the "signed-in" and "signed-out" theme sections. Variables
not specified in a section are inherited from the default theme.
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index 586ae07..e6c332e 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -1,6 +1,12 @@
Gerrit Code Review - Plugin Development
=======================================
+The Gerrit server functionality can be extended by installing plugins.
+This page describes how plugins for Gerrit can be developed.
+
+Depending on how tightly the extension code is coupled with the Gerrit
+server code, there is a distinction between `plugins` and `extensions`.
+
A plugin in Gerrit is tightly coupled code that runs in the same
JVM as Gerrit. It has full access to all server internals. Plugins
are tightly coupled to a specific major.minor server version and
@@ -9,8 +15,8 @@
An extension in Gerrit runs inside of the same JVM as Gerrit
in the same way as a plugin, but has limited visibility to the
-server's internals. The limited visiblity reduces the extension's
-dependencies, enabling it to be compatiable across a wider range
+server's internals. The limited visibility reduces the extension's
+dependencies, enabling it to be compatible across a wider range
of server versions.
Most of this documentation refers to either type as a plugin.
@@ -18,7 +24,7 @@
Requirements
------------
-To start development, clone the sample maven project:
+To start development, clone the sample Maven project:
----
$ git clone https://gerrit.googlesource.com/plugins/helloworld
@@ -160,7 +166,7 @@
====
If no Guice modules are declared in the manifest, SSH commands may
-use auto-registration by providing an @Export annotatation:
+use auto-registration by providing an @Export annotation:
====
import com.google.gerrit.extensions.annotations.Export;
@@ -192,7 +198,7 @@
by PrintHello class will be available to users as:
----
-$ ssh -P 29418 review.example.com helloworld print
+$ ssh -p 29418 review.example.com helloworld print
----
HTTP Servlets
@@ -260,6 +266,27 @@
if the file name ends with `.md`. Gerrit will automatically convert
Markdown to HTML if accessed with extension `.html`.
+Within the Markdown documentation files macros can be used that allow
+to write documentation with reasonably accurate examples that adjust
+automatically based on the installation.
+
+The following macros are supported:
+
+[width="40%",options="header"]
+|===================================================
+|Macro | Replacement
+|@PLUGIN@ | name of the plugin
+|@URL@ | Gerrit Web URL
+|@SSH_HOST@ | SSH Host
+|@SSH_PORT@ | SSH Port
+|===================================================
+
+The macros will be replaced when the documentation files are rendered
+from Markdown to HTML.
+
+Macros that start with `\` such as `\@KEEP@` will render as `@KEEP@`
+even if there is an expansion for `KEEP` in the future.
+
Automatic Index
~~~~~~~~~~~~~~~
@@ -312,7 +339,7 @@
the plugin from this location to its own site path.
+
----
-$ ssh -P 29418 localhost gerrit plugin install -n name $(pwd)/my-plugin.jar
+$ ssh -p 29418 localhost gerrit plugin install -n name $(pwd)/my-plugin.jar
----
* Valid URL, including any HTTP or FTP site reachable by the
@@ -320,14 +347,14 @@
its own site path.
+
----
-$ ssh -P 29418 localhost gerrit plugin install -n name http://build-server/output/our-plugin.jar
+$ ssh -p 29418 localhost gerrit plugin install -n name http://build-server/output/our-plugin.jar
----
* As piped input to the plugin install command. The server will
copy input until EOF, and save a copy under its own site path.
+
----
-$ ssh -P 29418 localhost gerrit plugin install -n name - <target/name-0.1.jar
+$ ssh -p 29418 localhost gerrit plugin install -n name - <target/name-0.1.jar
----
Plugins can also be copied directly into the server's
diff --git a/Documentation/error-change-closed.txt b/Documentation/error-change-closed.txt
index 74e7c48..3244fb3 100644
--- a/Documentation/error-change-closed.txt
+++ b/Documentation/error-change-closed.txt
@@ -1,8 +1,11 @@
change ... closed
=================
-With this error message Gerrit rejects to push a commit to a change
-that is already closed.
+With this error message Gerrit rejects to push a commit or submit a
+review label (approval) to a change that is already closed.
+
+When Pushing a Commit
+---------------------
This error occurs if you are trying to push a commit that contains
the Change-Id of a closed change in its commit message. A change can
@@ -24,6 +27,14 @@
'Restore Change' button). Afterwards the push should succeed and a
new patch set for this change will be created.
+When Submitting a Review Label
+------------------------------
+
+This error occurs if you are trying to submit a review label (approval) using
+the link:cmd-review.html[ssh review command] after the change has been closed.
+A change can be closed because it was submitted and merged, because it was abandoned,
+or because the patchset to which you are submitting the review has been replaced
+by a newer patchset.
GERRIT
------
diff --git a/Documentation/error-messages.txt b/Documentation/error-messages.txt
index 4b62795..c9df883 100644
--- a/Documentation/error-messages.txt
+++ b/Documentation/error-messages.txt
@@ -15,7 +15,9 @@
* link:error-change-not-found.html[change ... not found]
* link:error-contains-banned-commit.html[contains banned commit ...]
* link:error-has-duplicates.html[... has duplicates]
+* link:error-invalid-author.html[invalid author]
* link:error-invalid-changeid-line.html[invalid Change-Id line format in commit message]
+* link:error-invalid-committer.html[invalid committer]
* link:error-missing-changeid.html[missing Change-Id in commit message]
* link:error-multiple-changeid-lines.html[multiple Change-Id lines in commit message]
* link:error-no-changes-made.html[no changes made]
@@ -33,8 +35,6 @@
* link:error-squash-commits-first.html[squash commits first]
* link:error-upload-denied.html[Upload denied for project \'...']
* link:error-not-allowed-to-upload-merges.html[you are not allowed to upload merges]
-* link:error-invalid-author.html[invalid author]
-* link:error-invalid-committer.html[invalid committer]
General Hints
diff --git a/Documentation/index.txt b/Documentation/index.txt
index 2b53772..c99d26c 100644
--- a/Documentation/index.txt
+++ b/Documentation/index.txt
@@ -48,6 +48,7 @@
* link:dev-readme.html[Developer Setup]
* link:dev-eclipse.html[Eclipse Setup]
* link:dev-contributing.html[Contributing to Gerrit]
+* link:dev-plugins.html[Developing Plugins]
* link:dev-design.html[System Design]
* link:i18n-readme.html[i18n Support]
* link:dev-release.html[Developer Release]
diff --git a/Documentation/user-changeid.txt b/Documentation/user-changeid.txt
index 409bb32..a3015e1 100644
--- a/Documentation/user-changeid.txt
+++ b/Documentation/user-changeid.txt
@@ -46,11 +46,13 @@
Gerrit Code Review provides a standard 'commit-msg' hook which
can be installed in the local Git repository to automatically
create and insert a unique Change-Id line during `git commit`.
-To install the hook, copy it from Gerrit's daemon:
+To install the hook, copy it from Gerrit's daemon by executing
+one of the following commands while being in the root directory
+of the local Git repository:
$ scp -p -P 29418 john.doe@review.example.com:hooks/commit-msg .git/hooks/
- $ curl http://review.example.com/tools/hooks/commit-msg
+ $ curl -o .git/hooks/commit-msg http://review.example.com/tools/hooks/commit-msg
For more details, see link:cmd-hook-commit-msg.html[commit-msg].
diff --git a/ReleaseNotes/index.txt b/ReleaseNotes/index.txt
index 5f8de28..2e4865f 100644
--- a/ReleaseNotes/index.txt
+++ b/ReleaseNotes/index.txt
@@ -11,26 +11,26 @@
[[2_3]]
Version 2.3.x
-------------
-* link:ReleaseNotes-2.3.html[2.3]
* link:ReleaseNotes-2.3.1.html[2.3.1]
+* link:ReleaseNotes-2.3.html[2.3]
[[2_2]]
Version 2.2.x
-------------
-* link:ReleaseNotes-2.2.2.html[2.2.2],
-* link:ReleaseNotes-2.2.2.2.html[2.2.2.2],
-* link:ReleaseNotes-2.2.2.1.html[2.2.2.1],
-* link:ReleaseNotes-2.2.1.html[2.2.1],
+* link:ReleaseNotes-2.2.2.2.html[2.2.2.2]
+* link:ReleaseNotes-2.2.2.1.html[2.2.2.1]
+* link:ReleaseNotes-2.2.2.html[2.2.2]
+* link:ReleaseNotes-2.2.1.html[2.2.1]
* link:ReleaseNotes-2.2.0.html[2.2.0]
[[2_1]]
Version 2.1.x
-------------
-* link:ReleaseNotes-2.1.8.html[2.1.8],
-* link:ReleaseNotes-2.1.7.2.html[2.1.7.2],
-* link:ReleaseNotes-2.1.7.html[2.1.7],
-* link:ReleaseNotes-2.1.6.html[2.1.6],
- link:ReleaseNotes-2.1.6.1.html[2.1.6.1]
+* link:ReleaseNotes-2.1.8.html[2.1.8]
+* link:ReleaseNotes-2.1.7.2.html[2.1.7.2]
+* link:ReleaseNotes-2.1.7.html[2.1.7]
+* link:ReleaseNotes-2.1.6.1.html[2.1.6.1]
+* link:ReleaseNotes-2.1.6.html[2.1.6]
* link:ReleaseNotes-2.1.5.html[2.1.5]
* link:ReleaseNotes-2.1.4.html[2.1.4]
* link:ReleaseNotes-2.1.3.html[2.1.3]
@@ -40,31 +40,31 @@
* link:ReleaseNotes-2.1.2.2.html[2.1.2.2]
* link:ReleaseNotes-2.1.2.1.html[2.1.2.1]
* link:ReleaseNotes-2.1.2.html[2.1.2]
-* link:ReleaseNotes-2.1.1.html[2.1.1],
- link:ReleaseNotes-2.1.1.html[2.1.1.1]
+* link:ReleaseNotes-2.1.1.html[2.1.1.1]
+* link:ReleaseNotes-2.1.1.html[2.1.1]
* link:ReleaseNotes-2.1.html[2.1]
[[2_0]]
Version 2.0.x
-------------
-* link:ReleaseNotes-2.0.24.html[2.0.24],
- link:ReleaseNotes-2.0.24.html[2.0.24.1],
- link:ReleaseNotes-2.0.24.html[2.0.24.2]
+* link:ReleaseNotes-2.0.24.html[2.0.24.2]
+* link:ReleaseNotes-2.0.24.html[2.0.24.1]
+* link:ReleaseNotes-2.0.24.html[2.0.24]
* link:ReleaseNotes-2.0.23.html[2.0.23]
* link:ReleaseNotes-2.0.22.html[2.0.22]
* link:ReleaseNotes-2.0.21.html[2.0.21]
* link:ReleaseNotes-2.0.20.html[2.0.20]
-* link:ReleaseNotes-2.0.19.html[2.0.19],
- link:ReleaseNotes-2.0.19.html[2.0.19.1],
- link:ReleaseNotes-2.0.19.html[2.0.19.2]
+* link:ReleaseNotes-2.0.19.html[2.0.19.2]
+* link:ReleaseNotes-2.0.19.html[2.0.19.1]
+* link:ReleaseNotes-2.0.19.html[2.0.19]
* link:ReleaseNotes-2.0.18.html[2.0.18]
* link:ReleaseNotes-2.0.17.html[2.0.17]
* link:ReleaseNotes-2.0.16.html[2.0.16]
* link:ReleaseNotes-2.0.15.html[2.0.15]
-* link:ReleaseNotes-2.0.14.html[2.0.14],
- link:ReleaseNotes-2.0.14.html[2.0.14.1]
-* link:ReleaseNotes-2.0.13.html[2.0.13],
- link:ReleaseNotes-2.0.13.html[2.0.13.1]
+* link:ReleaseNotes-2.0.14.html[2.0.14.1]
+* link:ReleaseNotes-2.0.14.html[2.0.14]
+* link:ReleaseNotes-2.0.13.html[2.0.13.1]
+* link:ReleaseNotes-2.0.13.html[2.0.13]
* link:ReleaseNotes-2.0.12.html[2.0.12]
* link:ReleaseNotes-2.0.11.html[2.0.11]
* link:ReleaseNotes-2.0.10.html[2.0.10]
diff --git a/gerrit-antlr/.settings/org.eclipse.core.resources.prefs b/gerrit-antlr/.settings/org.eclipse.core.resources.prefs
index 589908f..e9441bb 100644
--- a/gerrit-antlr/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-antlr/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:35 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding/<project>=UTF-8
diff --git a/gerrit-cache-h2/.settings/org.eclipse.core.resources.prefs b/gerrit-cache-h2/.settings/org.eclipse.core.resources.prefs
index fc11c3f..f9fe345 100644
--- a/gerrit-cache-h2/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-cache-h2/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:36 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
diff --git a/gerrit-common/.settings/org.eclipse.core.resources.prefs b/gerrit-common/.settings/org.eclipse.core.resources.prefs
index fc11c3f..f9fe345 100644
--- a/gerrit-common/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-common/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:36 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
index 07a8534..89de3b4 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
@@ -28,6 +28,7 @@
public class GerritConfig implements Cloneable {
protected String registerUrl;
protected String httpPasswordUrl;
+ protected String openIdSsoUrl;
protected List<OpenIdProviderPattern> allowedOpenIDs;
protected GitwebConfig gitweb;
@@ -72,6 +73,14 @@
httpPasswordUrl = url;
}
+ public String getOpenIdSsoUrl() {
+ return openIdSsoUrl;
+ }
+
+ public void setOpenIdSsoUrl(final String u) {
+ openIdSsoUrl = u;
+ }
+
public List<OpenIdProviderPattern> getAllowedOpenIDs() {
return allowedOpenIDs;
}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java
index c3d3f1e..f991f4c 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java
@@ -31,5 +31,8 @@
public String textColor;
public String trimColor;
public String selectionColor;
+ public String changeTableOutdatedColor;
+ public String tableOddRowColor;
+ public String tableEvenRowColor;
}
}
diff --git a/gerrit-extension-api/.settings/org.eclipse.core.resources.prefs b/gerrit-extension-api/.settings/org.eclipse.core.resources.prefs
index fc11c3f..f9fe345 100644
--- a/gerrit-extension-api/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-extension-api/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:36 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
diff --git a/gerrit-gwtdebug/.settings/org.eclipse.core.resources.prefs b/gerrit-gwtdebug/.settings/org.eclipse.core.resources.prefs
index 36e1448..e9441bb 100644
--- a/gerrit-gwtdebug/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-gwtdebug/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:38 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding/<project>=UTF-8
diff --git a/gerrit-gwtui/.settings/org.eclipse.core.resources.prefs b/gerrit-gwtui/.settings/org.eclipse.core.resources.prefs
index c780f44..e9441bb 100644
--- a/gerrit-gwtui/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-gwtui/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:36 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding/<project>=UTF-8
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
index fcc2db1..267419f 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
@@ -18,6 +18,7 @@
import com.google.gerrit.client.account.AccountCapabilities;
import com.google.gerrit.client.auth.openid.OpenIdSignInDialog;
+import com.google.gerrit.client.auth.openid.OpenIdSsoPanel;
import com.google.gerrit.client.auth.userpass.UserPassSignInDialog;
import com.google.gerrit.client.changes.ChangeConstants;
import com.google.gerrit.client.changes.ChangeListScreen;
@@ -258,6 +259,13 @@
Location.assign(selfRedirect("/become"));
break;
+ case OPENID_SSO:
+ final RootPanel gBody = RootPanel.get("gerrit_body");
+ OpenIdSsoPanel singleSignOnPanel = new OpenIdSsoPanel();
+ gBody.add(singleSignOnPanel);
+ singleSignOnPanel.authenticate(SignInMode.SIGN_IN, token);
+ break;
+
case OPENID:
new OpenIdSignInDialog(SignInMode.SIGN_IN, token, null).center();
break;
@@ -627,6 +635,14 @@
});
break;
+ case OPENID_SSO:
+ menuRight.addItem(C.menuSignIn(), new Command() {
+ public void execute() {
+ doSignIn(History.getToken());
+ }
+ });
+ break;
+
case LDAP:
case LDAP_BIND:
case CUSTOM_EXTENSION:
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyWatchedProjectsScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyWatchedProjectsScreen.java
index 8d4a767..d38015c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyWatchedProjectsScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyWatchedProjectsScreen.java
@@ -15,12 +15,11 @@
package com.google.gerrit.client.account;
import com.google.gerrit.client.Gerrit;
-import com.google.gerrit.client.projects.ProjectMap;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.HintTextBox;
+import com.google.gerrit.client.ui.ProjectListPopup;
import com.google.gerrit.client.ui.ProjectNameSuggestOracle;
-import com.google.gerrit.client.ui.ProjectsTable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.AccountProjectWatchInfo;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -30,19 +29,13 @@
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
-import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
-import com.google.gwt.user.client.ui.PopupPanel;
-import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.SuggestBox.DefaultSuggestionDisplay;
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
-import com.google.gwtexpui.globalkey.client.GlobalKey;
-import com.google.gwtexpui.globalkey.client.HidePopupPanelCommand;
-import com.google.gwtexpui.user.client.PluginSafeDialogBox;
import java.util.List;
@@ -53,15 +46,10 @@
private HintTextBox filterTxt;
private MyWatchesTable watchesTab;
private Button browse;
- private PluginSafeDialogBox popup;
- private Button close;
- private ProjectsTable projectsTab;
private Button delSel;
- private PopupPanel.PositionCallback popupPosition;
private boolean submitOnSelection;
- private boolean firstPopupLoad = true;
- private boolean popingUp;
- private ScrollPanel sp;
+ private Grid grid;
+ private ProjectListPopup projectsPopup;
@Override
protected void onInitUI() {
@@ -69,7 +57,7 @@
createWidgets();
/* top table */
- final Grid grid = new Grid(2, 2);
+ grid = new Grid(2, 2);
grid.setStyleName(Gerrit.RESOURCES.css().infoBlock());
grid.setText(0, 0, Util.C.watchedProjectName());
grid.setWidget(0, 1, nameTxt);
@@ -98,41 +86,22 @@
/* popup */
- final FlowPanel pfp = new FlowPanel();
- sp = new ScrollPanel(projectsTab);
- sp.setSize("100%", "100%");
- pfp.add(sp);
- pfp.add(close);
- popup.setWidget(pfp);
- popup.setHeight("100%");
- popupPosition = new PopupPanel.PositionCallback() {
+ projectsPopup = new ProjectListPopup() {
+ @Override
+ protected void onMovePointerTo(String projectName) {
+ // prevent user input from being overwritten by simply poping up
+ if (!projectsPopup.isPopingUp() || "".equals(nameBox.getText())) {
+ nameBox.setText(projectName);
+ }
+ }
- public void setPosition(int offsetWidth, int offsetHeight) {
- int top = grid.getAbsoluteTop() - 50; // under page header
- // Try to place it to the right of everything else, but not
- // right justified
- int left =
- 5 + Math.max(grid.getAbsoluteLeft() + grid.getOffsetWidth(),
- watchesTab.getAbsoluteLeft() + watchesTab.getOffsetWidth());
- if (top + offsetHeight > Window.getClientHeight()) {
- top = Window.getClientHeight() - offsetHeight;
- }
- if (left + offsetWidth > Window.getClientWidth()) {
- left = Window.getClientWidth() - offsetWidth;
- }
-
- if (top < 0) {
- sp.setHeight((sp.getOffsetHeight() + top) + "px");
- top = 0;
- }
- if (left < 0) {
- sp.setWidth((sp.getOffsetWidth() + left) + "px");
- left = 0;
- }
-
- popup.setPopupPosition(left, top);
+ @Override
+ protected void openRow(String projectName) {
+ nameBox.setText(projectName);
+ doAddNew();
}
};
+ projectsPopup.initPopup(Util.C.projects(), PageLinks.SETTINGS_PROJECTS);
}
protected void createWidgets() {
@@ -185,49 +154,18 @@
}
});
- projectsTab = new ProjectsTable() {
- {
- keysNavigation.add(new OpenKeyCommand(0, 'o', Util.C.projectListOpen()));
- keysNavigation.add(new OpenKeyCommand(0, KeyCodes.KEY_ENTER,
- Util.C.projectListOpen()));
- }
-
- @Override
- protected void movePointerTo(final int row, final boolean scroll) {
- super.movePointerTo(row, scroll);
-
- // prevent user input from being overwritten by simply poping up
- if (! popingUp || "".equals(nameBox.getText()) ) {
- nameBox.setText(getRowItem(row).name());
- }
- }
-
- @Override
- protected void onOpenRow(final int row) {
- super.onOpenRow(row);
- nameBox.setText(getRowItem(row).name());
- doAddNew();
- }
- };
- projectsTab.setSavePointerId(PageLinks.SETTINGS_PROJECTS);
-
- close = new Button(Util.C.projectsClose());
- close.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(final ClickEvent event) {
- closePopup();
- }
- });
-
- popup = new PluginSafeDialogBox();
- popup.setModal(false);
- popup.setText(Util.C.projects());
-
browse = new Button(Util.C.buttonBrowseProjects());
browse.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
- displayPopup();
+ int top = grid.getAbsoluteTop() - 50; // under page header
+ // Try to place it to the right of everything else, but not
+ // right justified
+ int left =
+ 5 + Math.max(grid.getAbsoluteLeft() + grid.getOffsetWidth(),
+ watchesTab.getAbsoluteLeft() + watchesTab.getOffsetWidth());
+ projectsPopup.setPreferredCoordinates(top, left);
+ projectsPopup.displayPopup();
}
});
@@ -251,27 +189,7 @@
@Override
protected void onUnload() {
super.onUnload();
- closePopup();
- }
-
- protected void displayPopup() {
- popingUp = true;
- if (firstPopupLoad) { // For sizing/positioning, delay display until loaded
- populateProjects();
- } else {
- popup.setPopupPositionAndShow(popupPosition);
-
- GlobalKey.dialog(popup);
- GlobalKey.addApplication(popup, new HidePopupPanelCommand(0,
- KeyCodes.KEY_ESCAPE, popup));
- projectsTab.setRegisterKeys(true);
- projectsTab.finishDisplay();
- popingUp = false;
- }
- }
-
- protected void closePopup() {
- popup.hide();
+ projectsPopup.closePopup();
}
protected void doAddNew() {
@@ -321,17 +239,4 @@
}
});
}
-
- protected void populateProjects() {
- ProjectMap.all(new GerritCallback<ProjectMap>() {
- @Override
- public void onSuccess(final ProjectMap result) {
- projectsTab.display(result);
- if (firstPopupLoad) { // Display was delayed until table was loaded
- firstPopupLoad = false;
- displayPopup();
- }
- }
- });
- }
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
index 49bb5dc3..a9ad519 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
@@ -48,6 +48,8 @@
String suggestedGroupLabel();
String parentSuggestions();
+ String buttonBrowseProjects();
+ String projects();
String headingGroupUUID();
String headingOwner();
String headingDescription();
@@ -106,9 +108,11 @@
String plugins();
String pluginTabInstalled();
+ String pluginDisabled();
String columnPluginName();
String columnPluginVersion();
+ String columnPluginStatus();
String noGroupSelected();
String errorNoMatchingGroups();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
index 89fc195..e20d544 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
@@ -17,6 +17,8 @@
buttonSaveChanges = Save Changes
checkBoxEmptyCommit = Create initial empty commit
checkBoxPermissionsOnly = Only serve as parent for other projects
+buttonBrowseProjects = Browse
+projects = All projects
useContentMerge = Automatically resolve conflicts
useContributorAgreements = Require a valid contributor agreement to upload
useSignedOffBy = Require <a href="http://gerrit.googlecode.com/svn/documentation/2.0/user-signedoffby.html#Signed-off-by" target="_blank"><code>Signed-off-by</code></a> in commit message
@@ -86,8 +88,10 @@
plugins = Plugins
pluginTabInstalled = Installed
+pluginDisabled = Disabled
columnPluginName = Plugin Name
columnPluginVersion = Version
+columnPluginStatus = Status
noGroupSelected = (No group selected)
errorNoMatchingGroups = No Matching Groups
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/CreateProjectScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/CreateProjectScreen.java
index 43558be..b4950d8 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/CreateProjectScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/CreateProjectScreen.java
@@ -14,16 +14,22 @@
package com.google.gerrit.client.admin;
+import static com.google.gerrit.common.data.GlobalCapability.CREATE_PROJECT;
+
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.NotFoundScreen;
+import com.google.gerrit.client.account.AccountCapabilities;
import com.google.gerrit.client.projects.ProjectInfo;
import com.google.gerrit.client.projects.ProjectMap;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.HintTextBox;
+import com.google.gerrit.client.ui.ProjectListPopup;
import com.google.gerrit.client.ui.ProjectNameSuggestOracle;
import com.google.gerrit.client.ui.ProjectsTable;
import com.google.gerrit.client.ui.Screen;
+import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
@@ -41,13 +47,16 @@
import com.google.gwtjsonrpc.common.VoidResult;
public class CreateProjectScreen extends Screen {
+ private Grid grid;
private NpTextBox project;
private Button create;
+ private Button browse;
private HintTextBox parent;
private SuggestBox sugestParent;
private CheckBox emptyCommit;
private CheckBox permissionsOnly;
private ProjectsTable suggestedParentsTab;
+ private ProjectListPopup projectsPopup;
public CreateProjectScreen() {
super();
@@ -57,7 +66,22 @@
@Override
protected void onLoad() {
super.onLoad();
- display();
+ AccountCapabilities.all(new GerritCallback<AccountCapabilities>() {
+ @Override
+ public void onSuccess(AccountCapabilities ac) {
+ if (ac.canPerform(CREATE_PROJECT)) {
+ display();
+ } else {
+ Gerrit.display(PageLinks.ADMIN_CREATE_PROJECT, new NotFoundScreen());
+ }
+ }
+ }, CREATE_PROJECT);
+ }
+
+ @Override
+ protected void onUnload() {
+ super.onUnload();
+ projectsPopup.closePopup();
}
@Override
@@ -65,6 +89,18 @@
super.onInitUI();
setPageTitle(Util.C.createProjectTitle());
addCreateProjectPanel();
+
+ /* popup */
+ projectsPopup = new ProjectListPopup() {
+ @Override
+ protected void onMovePointerTo(String projectName) {
+ // prevent user input from being overwritten by simply poping up
+ if (!projectsPopup.isPopingUp() || "".equals(sugestParent.getText())) {
+ sugestParent.setText(projectName);
+ }
+ }
+ };
+ projectsPopup.initPopup(Util.C.projects(), PageLinks.ADMIN_PROJECTS);
}
private void addCreateProjectPanel() {
@@ -82,12 +118,11 @@
fp.add(emptyCommit);
fp.add(permissionsOnly);
fp.add(create);
- VerticalPanel vp=new VerticalPanel();
+ VerticalPanel vp = new VerticalPanel();
vp.add(fp);
initSuggestedParents();
vp.add(suggestedParentsTab);
add(vp);
-
}
private void initCreateTxt() {
@@ -111,6 +146,23 @@
doCreateProject();
}
});
+
+ browse = new Button(Util.C.buttonBrowseProjects());
+ browse.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(final ClickEvent event) {
+ int top = grid.getAbsoluteTop() - 50; // under page header
+ // Try to place it to the right of everything else, but not
+ // right justified
+ int left =
+ 5 + Math.max(
+ grid.getAbsoluteLeft() + grid.getOffsetWidth(),
+ suggestedParentsTab.getAbsoluteLeft()
+ + suggestedParentsTab.getOffsetWidth());
+ projectsPopup.setPreferredCoordinates(top, left);
+ projectsPopup.displayPopup();
+ }
+ });
}
private void initParentBox() {
@@ -145,26 +197,26 @@
};
suggestedParentsTab.setVisible(false);
- ProjectMap.permissions(new GerritCallback<ProjectMap>() {
- @Override
- public void onSuccess(ProjectMap list) {
- if (!list.isEmpty()) {
- suggestedParentsTab.setVisible(true);
- suggestedParentsTab.display(list);
- suggestedParentsTab.finishDisplay();
- }
- }
- });
+ ProjectMap.parentCandidates(new GerritCallback<ProjectMap>() {
+ @Override
+ public void onSuccess(ProjectMap list) {
+ if (!list.isEmpty()) {
+ suggestedParentsTab.setVisible(true);
+ suggestedParentsTab.display(list);
+ suggestedParentsTab.finishDisplay();
+ }
+ }
+ });
}
private void addGrid(final VerticalPanel fp) {
- final Grid grid = new Grid(2, 2);
+ grid = new Grid(2, 3);
grid.setStyleName(Gerrit.RESOURCES.css().infoBlock());
grid.setText(0, 0, Util.C.columnProjectName() + ":");
grid.setWidget(0, 1, project);
grid.setText(1, 0, Util.C.headingParentProjectName() + ":");
grid.setWidget(1, 1, sugestParent);
-
+ grid.setWidget(1, 2, browse);
fp.add(grid);
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java
index 814ae51..3948b35 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java
@@ -60,10 +60,12 @@
PluginTable() {
table.setText(0, 1, Util.C.columnPluginName());
table.setText(0, 2, Util.C.columnPluginVersion());
+ table.setText(0, 3, Util.C.columnPluginStatus());
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 2, Gerrit.RESOURCES.css().dataHeader());
+ fmt.addStyleName(0, 3, Gerrit.RESOURCES.css().dataHeader());
}
void display(final PluginMap plugins) {
@@ -80,16 +82,24 @@
}
void populate(final int row, final PluginInfo plugin) {
- table.setWidget(
- row,
- 1,
- new Anchor(plugin.name(), Gerrit.selfRedirect("/plugins/"
- + plugin.name() + "/")));
+ if (plugin.isDisabled()) {
+ table.setText(row, 1, plugin.name());
+ } else {
+ table.setWidget(
+ row,
+ 1,
+ new Anchor(plugin.name(), Gerrit.selfRedirect("/plugins/"
+ + plugin.name() + "/")));
+ }
table.setText(row, 2, plugin.version());
+ if (plugin.isDisabled()) {
+ table.setText(row, 3, Util.C.pluginDisabled());
+ }
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 2, Gerrit.RESOURCES.css().dataCell());
+ fmt.addStyleName(row, 3, Gerrit.RESOURCES.css().dataCell());
setRowItem(row, plugin);
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/auth/openid/OpenIdSsoPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/auth/openid/OpenIdSsoPanel.java
new file mode 100644
index 0000000..3dd54a7
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/auth/openid/OpenIdSsoPanel.java
@@ -0,0 +1,70 @@
+// Copyright (C) 2012 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.client.auth.openid;
+
+import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.rpc.GerritCallback;
+import com.google.gerrit.client.ui.SmallHeading;
+import com.google.gerrit.common.auth.SignInMode;
+import com.google.gerrit.common.auth.openid.DiscoveryResult;
+import com.google.gerrit.common.auth.openid.OpenIdUrls;
+import com.google.gwt.dom.client.FormElement;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.FormPanel;
+import com.google.gwt.user.client.ui.Hidden;
+
+import java.util.Map;
+
+public class OpenIdSsoPanel extends FlowPanel {
+ private final FormPanel redirectForm;
+ private final FlowPanel redirectBody;
+ private final String ssoUrl;
+
+ public OpenIdSsoPanel() {
+ super();
+ redirectBody = new FlowPanel();
+ redirectBody.setVisible(false);
+ redirectForm = new FormPanel();
+ redirectForm.add(redirectBody);
+
+ add(redirectForm);
+
+ ssoUrl = Gerrit.getConfig().getOpenIdSsoUrl();
+ }
+
+ public void authenticate(SignInMode requestedMode, final String token) {
+ OpenIdUtil.SVC.discover(ssoUrl, requestedMode, /* remember */ false, token,
+ new GerritCallback<DiscoveryResult>() {
+ public void onSuccess(final DiscoveryResult result) {
+ onDiscovery(result);
+ }
+ });
+ }
+
+ private void onDiscovery(final DiscoveryResult result) {
+ switch (result.status) {
+ case VALID:
+ redirectForm.setMethod(FormPanel.METHOD_POST);
+ redirectForm.setAction(result.providerUrl);
+ redirectBody.clear();
+ for (final Map.Entry<String, String> e : result.providerArgs.entrySet()) {
+ redirectBody.add(new Hidden(e.getKey(), e.getValue()));
+ }
+ FormElement.as(redirectForm.getElement()).setTarget("_top");
+ redirectForm.submit();
+ break;
+ }
+ }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java
index 44a49a8..97bb4ca 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java
@@ -202,10 +202,7 @@
}
table.setWidget(row, C_ID, new TableChangeLink(idstr, c));
- String s = c.getSubject();
- if (s.length() > 80) {
- s = s.substring(0, 80);
- }
+ String s = Util.cropSubject(c.getSubject());
if (c.getStatus() != null && c.getStatus() != Change.Status.NEW) {
s += " (" + c.getStatus().name() + ")";
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable2.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable2.java
index fc2b418..0dd0b0f 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable2.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable2.java
@@ -200,10 +200,7 @@
}
table.setWidget(row, C_ID, new TableChangeLink(c.id_abbreviated(), c));
- String subject = c.subject();
- if (subject.length() > 80) {
- subject = subject.substring(0, 80);
- }
+ String subject = Util.cropSubject(c.subject());
Change.Status status = c.status();
if (status != Change.Status.NEW) {
subject += " (" + Util.toLongString(status) + ")";
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
index 00baf28..ca8aedf 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
@@ -424,7 +424,8 @@
parentsTable.setWidget(row, 0, new InlineLabel(parent.id.get()));
ptfmt.addStyleName(row, 0, Gerrit.RESOURCES.css().noborder());
ptfmt.addStyleName(row, 0, Gerrit.RESOURCES.css().monospace());
- parentsTable.setWidget(row, 1, new InlineLabel(parent.shortMessage));
+ parentsTable.setWidget(row, 1,
+ new InlineLabel(Util.cropSubject(parent.shortMessage)));
ptfmt.addStyleName(row, 1, Gerrit.RESOURCES.css().noborder());
row++;
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchTable.java
index 7177525..b228cf2 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchTable.java
@@ -50,6 +50,28 @@
import java.util.List;
public class PatchTable extends Composite {
+ public interface PatchValidator {
+ /**
+ * Returns true if patch is valid
+ *
+ * @param patch
+ * @return
+ */
+ boolean isValid(Patch patch);
+ }
+
+ public final PatchValidator PREFERENCE_VALIDATOR =
+ new PatchValidator() {
+ @Override
+ public boolean isValid(Patch patch) {
+ return !((listenablePrefs.get().isSkipDeleted()
+ && patch.getChangeType().equals(ChangeType.DELETED))
+ || (listenablePrefs.get().isSkipUncommented()
+ && patch.getCommentCount() == 0));
+ }
+
+ };
+
private final FlowPanel myBody;
private PatchSetDetail detail;
private Command onLoadCommand;
@@ -176,29 +198,32 @@
/**
* @return a link to the previous file in this patch set, or null.
*/
- public InlineHyperlink getPreviousPatchLink(int index, PatchScreen.Type patchType) {
- for(index--; index > -1; index--) {
- InlineHyperlink link = createLink(index, patchType, SafeHtml.asis(Util.C
- .prevPatchLinkIcon()), null);
- if (link != null) {
- return link;
- }
+ public InlineHyperlink getPreviousPatchLink(int index,
+ PatchScreen.Type patchType) {
+ int previousPatchIndex = getPreviousPatch(index, PREFERENCE_VALIDATOR);
+ if (previousPatchIndex < 0) {
+ return null;
}
- return null;
+ InlineHyperlink link =
+ createLink(previousPatchIndex, patchType,
+ SafeHtml.asis(Util.C.prevPatchLinkIcon()), null);
+
+ return link;
}
/**
* @return a link to the next file in this patch set, or null.
*/
public InlineHyperlink getNextPatchLink(int index, PatchScreen.Type patchType) {
- for(index++; index < patchList.size(); index++) {
- InlineHyperlink link = createLink(index, patchType, null, SafeHtml.asis(Util.C
- .nextPatchLinkIcon()));
- if (link != null) {
- return link;
- }
+ int nextPatchIndex = getNextPatch(index, false, PREFERENCE_VALIDATOR);
+ if (nextPatchIndex < 0) {
+ return null;
}
- return null;
+ InlineHyperlink link =
+ createLink(nextPatchIndex, patchType, null,
+ SafeHtml.asis(Util.C.nextPatchLinkIcon()));
+
+ return link;
}
/**
@@ -208,16 +233,9 @@
* @param before A string to display at the beginning of the href text
* @param after A string to display at the end of the href text
*/
- private PatchLink createLink(int index, PatchScreen.Type patchType,
+ public PatchLink createLink(int index, PatchScreen.Type patchType,
SafeHtml before, SafeHtml after) {
Patch patch = patchList.get(index);
- if (( listenablePrefs.get().isSkipDeleted() &&
- patch.getChangeType().equals(ChangeType.DELETED) )
- ||
- ( listenablePrefs.get().isSkipUncommented() &&
- patch.getCommentCount() == 0 ) ) {
- return null;
- }
Key thisKey = patch.getKey();
PatchLink link;
@@ -814,4 +832,75 @@
return System.currentTimeMillis() - start > 200;
}
}
+
+
+ /**
+ * Gets the next patch
+ *
+ * @param currentIndex
+ * @param validators
+ * @param loopAround loops back around to the front and traverses if this is
+ * true
+ * @return
+ */
+ public int getNextPatch(int currentIndex, boolean loopAround,
+ PatchValidator... validators) {
+ return getNextPatchHelper(currentIndex, loopAround, detail.getPatches()
+ .size(), validators);
+ }
+
+ /**
+ * Helper function for getNextPatch
+ *
+ * @param currentIndex
+ * @param validators
+ * @param loopAround
+ * @param maxIndex will only traverse up to this index
+ * @return
+ */
+ private int getNextPatchHelper(int currentIndex, boolean loopAround,
+ int maxIndex, PatchValidator... validators) {
+ for (int i = currentIndex + 1; i < maxIndex; i++) {
+ Patch patch = detail.getPatches().get(i);
+ if (patch != null && patchIsValid(patch, validators)) {
+ return i;
+ }
+ }
+
+ if (loopAround) {
+ return getNextPatchHelper(-1, false, currentIndex, validators);
+ }
+
+ return -1;
+ }
+
+ /**
+ * @return the index to the previous patch
+ */
+ public int getPreviousPatch(int currentIndex, PatchValidator... validators) {
+ for (int i = currentIndex - 1; i >= 0; i--) {
+ Patch patch = detail.getPatches().get(i);
+ if (patch != null && patchIsValid(patch, validators)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Helper function that returns whether a patch is valid or not
+ *
+ * @param patch
+ * @param validators
+ * @return whether the patch is valid based on the validators
+ */
+ private boolean patchIsValid(Patch patch, PatchValidator... validators) {
+ for (PatchValidator v : validators) {
+ if (!v.isValid(patch)) {
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/Util.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/Util.java
index e84cac8..590ad87 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/Util.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/Util.java
@@ -30,6 +30,10 @@
public static final ChangeListService LIST_SVC;
public static final ChangeManageService MANAGE_SVC;
+ private static final int SUBJECT_MAX_LENGTH = 80;
+ private static final String SUBJECT_CROP_APPENDIX = "...";
+ private static final int SUBJECT_CROP_RANGE = 10;
+
static {
DETAIL_SVC = GWT.create(ChangeDetailService.class);
JsonUtil.bind(DETAIL_SVC, "rpc/ChangeDetailService");
@@ -60,4 +64,40 @@
return status.name();
}
}
+
+ /**
+ * Crops the given change subject if needed so that it has at most
+ * {@link #SUBJECT_MAX_LENGTH} characters.
+ *
+ * If the given subject is not longer than {@link #SUBJECT_MAX_LENGTH}
+ * characters it is returned unchanged.
+ *
+ * If the length of the given subject exceeds {@link #SUBJECT_MAX_LENGTH}
+ * characters it is cropped. In this case {@link #SUBJECT_CROP_APPENDIX} is
+ * appended to the cropped subject, the cropped subject including the appendix
+ * has at most {@link #SUBJECT_MAX_LENGTH} characters.
+ *
+ * If cropping is needed, the subject will be cropped after the last space
+ * character that is found within the last {@link #SUBJECT_CROP_RANGE}
+ * characters of the potentially visible characters. If no such space is
+ * found, the subject will be cropped so that the cropped subject including
+ * the appendix has exactly {@link #SUBJECT_MAX_LENGTH} characters.
+ *
+ * @return the subject, cropped if needed
+ */
+ @SuppressWarnings("deprecation")
+ public static String cropSubject(final String subject) {
+ if (subject.length() > SUBJECT_MAX_LENGTH) {
+ final int maxLength = SUBJECT_MAX_LENGTH - SUBJECT_CROP_APPENDIX.length();
+ for (int cropPosition = maxLength; cropPosition > maxLength - SUBJECT_CROP_RANGE; cropPosition--) {
+ // Character.isWhitespace(char) can't be used because this method is not supported by GWT,
+ // see https://developers.google.com/web-toolkit/doc/1.6/RefJreEmulation#Package_java_lang
+ if (Character.isSpace(subject.charAt(cropPosition - 1))) {
+ return subject.substring(0, cropPosition) + SUBJECT_CROP_APPENDIX;
+ }
+ }
+ return subject.substring(0, maxLength) + SUBJECT_CROP_APPENDIX;
+ }
+ return subject;
+ }
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
index 3789c6a..446b71d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
@@ -43,7 +43,9 @@
@eval textColor com.google.gerrit.client.Gerrit.getTheme().textColor;
@eval trimColor com.google.gerrit.client.Gerrit.getTheme().trimColor;
@eval selectionColor com.google.gerrit.client.Gerrit.getTheme().selectionColor;
-
+@eval changeTableOutdatedColor com.google.gerrit.client.Gerrit.getTheme().changeTableOutdatedColor;
+@eval tableOddRowColor com.google.gerrit.client.Gerrit.getTheme().tableOddRowColor;
+@eval tableEvenRowColor com.google.gerrit.client.Gerrit.getTheme().tableEvenRowColor;
@sprite .greenCheckClass {
gwt-image: "greenCheck";
@@ -411,8 +413,16 @@
border-spacing: 0;
}
+.changeTable tr:nth-child\(even\) {
+ background: tableEvenRowColor;
+}
+
+.changeTable tr:nth-child\(odd\) {
+ background: tableOddRowColor;
+}
+
.changeTable .outdated {
- background: red;
+ background: changeTableOutdatedColor;
}
.changeTable .iconCell {
@@ -482,7 +492,6 @@
.accountDashboard.changeTable tr {
color: #444444;
- background: #F6F6F6;
}
.accountDashboard.changeTable tr a {
color: #444444;
@@ -492,13 +501,12 @@
.accountDashboard.changeTable .needsReview a {
font-weight: bold;
color: textColor;
- background: backgroundColor;
}
.changeTable .activeRow,
.accountDashboard.changeTable .activeRow,
.accountDashboard.changeTable .activeRow a {
- background: selectionColor;
+ background: selectionColor !important;
}
.changeTable .cID {
@@ -1042,6 +1050,10 @@
display: table;
}
+.sideBySideScreenSideBySideTable .fileLine {
+ width: 50%;
+}
+
.sideBySideScreenLinkTable {
width: 100%;
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.java
index fd34729..70dcf75 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.java
@@ -31,6 +31,7 @@
String patchHeaderPatchSet();
String patchHeaderOld();
String patchHeaderNew();
+ String patchSet();
String patchHistoryTitle();
String disabledOnLargeFiles();
@@ -60,7 +61,8 @@
String previousFileHelp();
String nextFileHelp();
- String reviewed();
+ String reviewedAnd();
+ String next();
String download();
String buttonReplyDone();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.properties
index 23090a2..694ccb4 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.properties
@@ -15,6 +15,7 @@
patchHeaderOld = Old Version
patchHeaderNew = New Version
patchHistoryTitle = Patch History
+patchSet = Patch Set
disabledOnLargeFiles = Disabled on very large source files.
intralineFailure = Intraline difference not available due to server error.
illegalNumberOfColumns = The number of columns cannot be zero or negative
@@ -42,7 +43,8 @@
previousFileHelp = Previous file
nextFileHelp = Next file
-reviewed = Reviewed
+reviewedAnd = Reviewed &
+next = next
download = (Download)
fileTypeSymlink = Type: Symbolic Link
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchScreen.java
index 77d8659..0976a9d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchScreen.java
@@ -20,10 +20,13 @@
import com.google.gerrit.client.RpcStatus;
import com.google.gerrit.client.changes.CommitMessageBlock;
import com.google.gerrit.client.changes.PatchTable;
+import com.google.gerrit.client.changes.PatchTable.PatchValidator;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
+import com.google.gerrit.client.ui.ChangeLink;
import com.google.gerrit.client.ui.ListenableAccountDiffPreference;
+import com.google.gerrit.client.ui.PatchLink;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchSetDetail;
@@ -34,17 +37,22 @@
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwtexpui.globalkey.client.GlobalKey;
import com.google.gwtexpui.globalkey.client.KeyCommand;
import com.google.gwtexpui.globalkey.client.KeyCommandSet;
+import com.google.gwtexpui.safehtml.client.SafeHtml;
+import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import com.google.gwtjsonrpc.common.VoidResult;
public abstract class PatchScreen extends Screen implements
@@ -102,10 +110,12 @@
protected PatchScriptSettingsPanel settingsPanel;
protected TopView topView;
- private CheckBox reviewed;
+ private CheckBox reviewedCheckBox;
+ private FlowPanel reviewedPanel;
private HistoryTable historyTable;
private FlowPanel topPanel;
private FlowPanel contentPanel;
+ private PatchTableHeader header;
private Label noDifference;
private AbstractPatchContentTable contentTable;
private CommitMessageBlock commitMessageBlock;
@@ -143,15 +153,6 @@
idSideB = id.getParentKey();
this.patchIndex = patchIndex;
- reviewed = new CheckBox(Util.C.reviewed());
- reviewed.addValueChangeHandler(
- new ValueChangeHandler<Boolean>() {
- @Override
- public void onValueChange(ValueChangeEvent<Boolean> event) {
- setReviewedByCurrentUser(event.getValue());
- }
- });
-
prefs = fileList != null ? fileList.getPreferences() :
new ListenableAccountDiffPreference();
if (Gerrit.isSignedIn()) {
@@ -165,9 +166,75 @@
}
});
+ reviewedPanel = new FlowPanel();
settingsPanel = new PatchScriptSettingsPanel(prefs);
}
+ private void populateReviewedPanel(){
+ reviewedPanel.clear();
+
+ reviewedCheckBox = new CheckBox(PatchUtil.C.reviewedAnd() + " ");
+ reviewedCheckBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
+ @Override
+ public void onValueChange(ValueChangeEvent<Boolean> event) {
+ setReviewedByCurrentUser(event.getValue());
+ }
+ });
+
+ reviewedPanel.add(reviewedCheckBox);
+ reviewedPanel.add(getReviewedAnchor());
+ }
+
+ private Anchor getReviewedAnchor() {
+ SafeHtmlBuilder text = new SafeHtmlBuilder();
+ text.append(PatchUtil.C.next());
+ text.append(SafeHtml.asis(Util.C.nextPatchLinkIcon()));
+
+ Anchor reviewedAnchor = new Anchor("");
+ SafeHtml.set(reviewedAnchor, text);
+
+ reviewedAnchor.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ setReviewedByCurrentUser(true);
+ }
+ });
+
+ final PatchValidator unreviewedValidator = new PatchValidator() {
+ public boolean isValid(Patch patch) {
+ return !patch.isReviewedByCurrentUser();
+ }
+ };
+
+ int nextUnreviewedPatchIndex =
+ fileList.getNextPatch(patchIndex, true, unreviewedValidator,
+ fileList.PREFERENCE_VALIDATOR);
+
+ if (nextUnreviewedPatchIndex > -1) {
+ // Create invisible patch link to change page
+ final PatchLink reviewedLink =
+ fileList.createLink(nextUnreviewedPatchIndex, getPatchScreenType(),
+ null, null);
+ reviewedLink.setText("");
+ reviewedAnchor.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ reviewedLink.go();
+ }
+ });
+ } else {
+ final ChangeLink upLink = new ChangeLink("", patchKey.getParentKey());
+ reviewedAnchor.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ upLink.go();
+ }
+ });
+ }
+
+ return reviewedAnchor;
+ }
+
@Override
public void notifyDraftDelta(int delta) {
lastScript = null;
@@ -180,9 +247,9 @@
private void update(AccountDiffPreference dp) {
// Did the user just turn on auto-review?
- if (!reviewed.getValue() && prefs.getOld().isManualReview()
+ if (!reviewedCheckBox.getValue() && prefs.getOld().isManualReview()
&& !dp.isManualReview()) {
- reviewed.setValue(true);
+ reviewedCheckBox.setValue(true);
setReviewedByCurrentUser(true);
}
@@ -236,7 +303,7 @@
super.onInitUI();
if (Gerrit.isSignedIn()) {
- setTitleFarEast(reviewed);
+ setTitleFarEast(reviewedPanel);
}
keysNavigation = new KeyCommandSet(Gerrit.C.sectionNavigation());
@@ -250,6 +317,8 @@
topPanel = new FlowPanel();
add(topPanel);
+ header = new PatchTableHeader(getPatchScreenType());
+
noDifference = new Label(PatchUtil.C.noDifference());
noDifference.setStyleName(Gerrit.RESOURCES.css().patchNoDifference());
noDifference.setVisible(false);
@@ -264,6 +333,7 @@
contentPanel = new FlowPanel();
contentPanel.setStyleName(Gerrit.RESOURCES.css()
.sideBySideScreenSideBySideTable());
+ contentPanel.add(header);
contentPanel.add(noDifference);
contentPanel.add(contentTable);
add(contentPanel);
@@ -369,6 +439,7 @@
final int rpcseq = ++rpcSequence;
lastScript = null;
settingsPanel.setEnabled(false);
+ populateReviewedPanel();
if (isFirst && fileList != null) {
fileList.movePointerTo(patchKey);
}
@@ -439,6 +510,8 @@
setToken(Dispatcher.toPatchUnified(idSideA, patchKey));
}
+ header.display(patchSetDetail, script, patchKey, idSideA, idSideB);
+
if (hasDifferences) {
contentTable.display(patchKey, idSideA, idSideB, script);
contentTable.display(script.getCommentDetail(), script.isExpandAllComments());
@@ -468,7 +541,7 @@
}
}
}
- reviewed.setValue(isReviewed);
+ reviewedCheckBox.setValue(isReviewed);
}
intralineFailure = isFirst && script.hasIntralineFailure();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.java
new file mode 100644
index 0000000..5dd4e1f
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.java
@@ -0,0 +1,169 @@
+// Copyright (C) 2012 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.client.patches;
+
+import com.google.gerrit.client.Dispatcher;
+import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.common.data.PatchScript;
+import com.google.gerrit.common.data.PatchSetDetail;
+import com.google.gerrit.reviewdb.client.Patch;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.SpanElement;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.resources.client.CssResource;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.user.client.ui.Anchor;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTMLPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwtorm.client.KeyUtil;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class PatchSetSelectBox extends Composite {
+ interface Binder extends UiBinder<HTMLPanel, PatchSetSelectBox> {
+ }
+
+ private static Binder uiBinder = GWT.create(Binder.class);
+
+ interface BoxStyle extends CssResource {
+ String selected();
+
+ String hidden();
+ }
+
+ public enum Side {
+ A, B
+ }
+
+ PatchScript script;
+ Patch.Key patchKey;
+ PatchSet.Id idSideA;
+ PatchSet.Id idSideB;
+ PatchSet.Id idActive;
+ Side side;
+ PatchScreen.Type screenType;
+ List<Anchor> links;
+
+ @UiField
+ HTMLPanel linkPanel;
+
+ @UiField
+ BoxStyle style;
+
+ @UiField
+ SpanElement sideMarker;
+
+ public PatchSetSelectBox(Side side, final PatchScreen.Type type) {
+ this.side = side;
+ this.screenType = type;
+
+ initWidget(uiBinder.createAndBindUi(this));
+ }
+
+ public void display(final PatchSetDetail detail, final PatchScript script, Patch.Key key,
+ PatchSet.Id idSideA, PatchSet.Id idSideB) {
+ this.script = script;
+ this.patchKey = key;
+ this.idSideA = idSideA;
+ this.idSideB = idSideB;
+ this.idActive = (side == Side.A) ? idSideA : idSideB;
+ this.links = new LinkedList<Anchor>();
+
+ if (screenType == PatchScreen.Type.UNIFIED) {
+ sideMarker.setInnerText((side == Side.A) ? "(-)" : "(+)");
+ }
+
+ if (detail.getInfo().getParents().size() > 1) {
+ addLink(PatchUtil.C.patchBaseAutoMerge(), null);
+ } else {
+ addLink(PatchUtil.C.patchBase(), null);
+ }
+
+ if (side == Side.B) {
+ links.get(0).setStyleName(style.hidden());
+ }
+
+ for (Patch patch : script.getHistory()) {
+ PatchSet.Id psId = patch.getKey().getParentKey();
+ addLink(Integer.toString(psId.get()), psId);
+ }
+
+ if (idActive == null && side == Side.A) {
+ links.get(0).setStyleName(style.selected());
+ } else {
+ links.get(idActive.get()).setStyleName(style.selected());
+ }
+
+ Anchor downloadLink = getDownloadLink();
+ if (downloadLink != null) {
+ linkPanel.add(new Label(" - "));
+ linkPanel.add(downloadLink);
+ }
+ }
+
+ private void addLink(String label, final PatchSet.Id id) {
+ final Anchor anchor = new Anchor(label);
+ anchor.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ if (side == Side.A) {
+ idSideA = id;
+ } else {
+ idSideB = id;
+ }
+
+ Patch.Key keySideB = new Patch.Key(idSideB, patchKey.get());
+
+ switch (screenType) {
+ case SIDE_BY_SIDE:
+ Gerrit.display(Dispatcher.toPatchSideBySide(idSideA, keySideB));
+ break;
+ case UNIFIED:
+ Gerrit.display(Dispatcher.toPatchUnified(idSideA, keySideB));
+ break;
+ }
+ }
+
+ });
+
+ links.add(anchor);
+ linkPanel.add(anchor);
+ }
+
+ private Anchor getDownloadLink() {
+ boolean isCommitMessage = Patch.COMMIT_MSG.equals(script.getNewName());
+
+ if (isCommitMessage || (side == Side.A && 0 >= script.getA().size())
+ || (side == Side.B && 0 >= script.getB().size())) {
+ return null;
+ }
+
+ Patch.Key key =
+ (idSideA == null) ? patchKey : (new Patch.Key(idSideA, patchKey.get()));
+
+ String sideURL = (side == Side.A) ? "1" : "0";
+ final String base = GWT.getHostPageBaseURL() + "cat/";
+
+ final Anchor anchor = new Anchor(PatchUtil.C.download());
+ anchor.setHref(base + KeyUtil.encode(key.toString()) + "^" + sideURL);
+
+ return anchor;
+ }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.ui.xml
new file mode 100644
index 0000000..2c4bd5d
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.ui.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2012 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.
+-->
+
+<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
+ xmlns:g='urn:import:com.google.gwt.user.client.ui'>
+
+
+ <ui:with field='res' type='com.google.gerrit.client.GerritResources'/>
+ <ui:with field='cons' type='com.google.gerrit.client.patches.PatchConstants'/>
+ <ui:style type='com.google.gerrit.client.patches.PatchSetSelectBox.BoxStyle'>
+ @eval selectionColor com.google.gerrit.client.Gerrit.getTheme().selectionColor;
+ @eval trimColor com.google.gerrit.client.Gerrit.getTheme().trimColor;
+ @eval backgroundColor com.google.gerrit.client.Gerrit.getTheme().backgroundColor;
+
+ .wrapper {
+ width: 100%;
+ }
+
+ .patchSetLabel {
+ font-weight: bold;
+ }
+
+ .linkPanel > div {
+ display: inline-block;
+ padding: 3px;
+ }
+
+ .linkPanel {
+ font-size: 12px;
+ }
+
+ .linkPanel > a {
+ padding: 3px;
+ display: inline-block;
+ text-decoration: none;
+ }
+
+ .selected {
+ font-weight: bold;
+ background-color: selectionColor;
+ }
+
+ .sideMarker {
+ font-family: monospace;
+ }
+
+ .hidden {
+ visibility: hidden;
+ }
+ </ui:style>
+
+ <g:HTMLPanel styleName='wrapper'>
+ <g:HTMLPanel styleName='{style.linkPanel}' ui:field='linkPanel'><span class='{style.patchSetLabel}'><ui:text from="{cons.patchSet}" /></span> <span class='{style.sideMarker}' ui:field='sideMarker'></span>: </g:HTMLPanel>
+ </g:HTMLPanel>
+</ui:UiBinder>
+
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeader.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeader.java
new file mode 100644
index 0000000..3dd8908
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeader.java
@@ -0,0 +1,71 @@
+// Copyright (C) 2012 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.client.patches;
+
+import com.google.gerrit.common.data.PatchScript;
+import com.google.gerrit.common.data.PatchSetDetail;
+import com.google.gerrit.reviewdb.client.Patch;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.uibinder.client.UiTemplate;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTMLPanel;
+import com.google.gwt.user.client.ui.SimplePanel;
+
+public class PatchTableHeader extends Composite {
+
+ @UiTemplate("PatchTableHeaderSideBySide.ui.xml")
+ interface SideBySideBinder extends UiBinder<HTMLPanel, PatchTableHeader> {
+ }
+
+ @UiTemplate("PatchTableHeaderUnified.ui.xml")
+ interface UnifiedBinder extends UiBinder<HTMLPanel, PatchTableHeader> {
+ }
+
+ private static SideBySideBinder uiBinderS = GWT.create(SideBySideBinder.class);
+ private static UnifiedBinder uiBinderU = GWT.create(UnifiedBinder.class);
+
+ @UiField
+ SimplePanel sideAPanel;
+
+ @UiField
+ SimplePanel sideBPanel;
+
+ PatchSetSelectBox listA;
+ PatchSetSelectBox listB;
+
+ public PatchTableHeader(PatchScreen.Type type) {
+ listA = new PatchSetSelectBox(PatchSetSelectBox.Side.A, type);
+ listB = new PatchSetSelectBox(PatchSetSelectBox.Side.B, type);
+
+ if (type == PatchScreen.Type.SIDE_BY_SIDE) {
+ initWidget(uiBinderS.createAndBindUi(this));
+ } else {
+ initWidget(uiBinderU.createAndBindUi(this));
+ }
+
+ sideAPanel.add(listA);
+ sideBPanel.add(listB);
+ }
+
+
+ public void display(final PatchSetDetail detail, PatchScript script, final Patch.Key patchKey,
+ final PatchSet.Id idSideA, final PatchSet.Id idSideB) {
+ listA.display(detail, script, patchKey, idSideA, idSideB);
+ listB.display(detail, script, patchKey, idSideA, idSideB);
+ }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderSideBySide.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderSideBySide.ui.xml
new file mode 100644
index 0000000..424e6e5
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderSideBySide.ui.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2012 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.
+-->
+
+<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
+ xmlns:g='urn:import:com.google.gwt.user.client.ui'>
+
+
+ <ui:style>
+ @eval trimColor com.google.gerrit.client.Gerrit.getTheme().trimColor;
+
+ .wrapper {
+ width: 100%;
+ background-color: trimColor;
+ overflow: hidden;
+ }
+
+ .wrapper .box {
+ width: 100%;
+ text-align: center;
+ }
+
+ .leftWrapper {
+ width: 50%;
+ float: left;
+ }
+
+ .rightWrapper {
+ width: 50%;
+ overflow: hidden;
+ }
+
+ .leftBox {
+ float:left;
+ }
+
+ .rightBox {
+ float: right;
+ }
+ </ui:style>
+
+ <g:HTMLPanel styleName="{style.wrapper}">
+ <div class='{style.leftWrapper}'>
+ <g:SimplePanel addStyleNames='{style.box} {style.leftBox}' ui:field='sideAPanel'/>
+ </div>
+ <div class='{style.rightWrapper}'>
+ <g:SimplePanel addStyleNames='{style.box} {style.rightBox}' ui:field='sideBPanel'/>
+ </div>
+ </g:HTMLPanel>
+</ui:UiBinder>
+
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderUnified.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderUnified.ui.xml
new file mode 100644
index 0000000..e26e96a
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderUnified.ui.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2012 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.
+-->
+
+<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
+ xmlns:g='urn:import:com.google.gwt.user.client.ui'>
+
+ <ui:style>
+ @eval trimColor com.google.gerrit.client.Gerrit.getTheme().trimColor;
+
+ .wrapper {
+ width: 100%;
+ background-color: trimColor;
+ }
+
+ .wrapper .box {
+ width: 100%;
+ text-align: left;
+ margin-left: 3px;
+ }
+ </ui:style>
+
+ <g:HTMLPanel styleName="{style.wrapper}">
+ <g:SimplePanel addStyleNames='{style.box}' ui:field='sideAPanel'/>
+ <g:SimplePanel addStyleNames='{style.box}' ui:field='sideBPanel'/>
+ </g:HTMLPanel>
+</ui:UiBinder>
+
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java
index 964ba4b..ec63a83 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java
@@ -25,10 +25,7 @@
import com.google.gerrit.common.data.PatchScript.FileMode;
import com.google.gerrit.prettify.common.EditList;
import com.google.gerrit.prettify.common.SparseHtmlFile;
-import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gerrit.reviewdb.client.Patch.ChangeType;
import com.google.gerrit.reviewdb.client.PatchLineComment;
-import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Anchor;
@@ -38,8 +35,6 @@
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
-import com.google.gwtorm.client.KeyUtil;
-
import org.eclipse.jgit.diff.Edit;
import java.util.ArrayList;
@@ -89,9 +84,6 @@
script.getDiffPrefs().isIntralineDifference()
&& script.hasIntralineDifference();
- appendHeader(script, nc);
- lines.add(null);
-
if (script.getFileModeA() != FileMode.FILE
|| script.getFileModeB() != FileMode.FILE) {
openLine(nc);
@@ -262,71 +254,6 @@
return row;
}
- private void appendHeader(PatchScript script, final SafeHtmlBuilder m) {
- boolean isCommitMessage = Patch.COMMIT_MSG.equals(script.getNewName());
-
- m.openTr();
-
- m.openTd();
- m.addStyleName(Gerrit.RESOURCES.css().iconCell());
- m.addStyleName(Gerrit.RESOURCES.css().fileColumnHeader());
- m.closeTd();
-
- m.openTd();
- m.addStyleName(Gerrit.RESOURCES.css().fileColumnHeader());
- m.addStyleName(Gerrit.RESOURCES.css().lineNumber());
- m.closeTd();
-
- m.openTd();
- m.setStyleName(Gerrit.RESOURCES.css().fileColumnHeader());
- m.setAttribute("width", "50%");
- if (script.getChangeType() == ChangeType.RENAMED
- || script.getChangeType() == ChangeType.COPIED) {
- m.append(script.getOldName());
- } else {
- m.append(PatchUtil.C.patchHeaderOld());
- }
- if (!isCommitMessage) {
- m.br();
- if (0 < script.getA().size()) {
- if (idSideA == null) {
- downloadLink(m, patchKey, "1");
- } else {
- downloadLink(m, new Patch.Key(idSideA, patchKey.get()), "0");
- }
- }
- }
- m.closeTd();
-
- m.openTd();
- m.setStyleName(Gerrit.RESOURCES.css().fileColumnHeader());
- m.setAttribute("width", "50%");
- m.append(PatchUtil.C.patchHeaderNew());
- if (!isCommitMessage) {
- m.br();
- if (0 < script.getB().size()) {
- downloadLink(m, new Patch.Key(idSideB, patchKey.get()), "0");
- }
- }
- m.closeTd();
-
- m.openTd();
- m.addStyleName(Gerrit.RESOURCES.css().fileColumnHeader());
- m.addStyleName(Gerrit.RESOURCES.css().lineNumber());
- m.closeTd();
-
- m.closeTr();
- }
-
- private void downloadLink(final SafeHtmlBuilder m, final Patch.Key key,
- final String side) {
- final String base = GWT.getHostPageBaseURL() + "cat/";
- m.openAnchor();
- m.setAttribute("href", base + KeyUtil.encode(key.toString()) + "^" + side);
- m.append(PatchUtil.C.download());
- m.closeAnchor();
- }
-
private void appendSkipLine(final SafeHtmlBuilder m, final int skipCnt) {
m.openTr();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/plugins/PluginInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/plugins/PluginInfo.java
index 454c97b..ace4a49 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/plugins/PluginInfo.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/plugins/PluginInfo.java
@@ -20,6 +20,8 @@
public final native String name() /*-{ return this.name; }-*/;
public final native String version() /*-{ return this.version; }-*/;
+ public final native boolean isDisabled()
+ /*-{ return this.disabled ? true : false; }-*/;
protected PluginInfo() {
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/plugins/PluginMap.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/plugins/PluginMap.java
index 0f2ab4c..6eca206 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/plugins/PluginMap.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/plugins/PluginMap.java
@@ -21,7 +21,7 @@
/** Plugins available from {@code /plugins/}. */
public class PluginMap extends NativeMap<PluginInfo> {
public static void all(AsyncCallback<PluginMap> callback) {
- new RestApi("/plugins/")
+ new RestApi("/plugins/").addParameterTrue("all")
.send(NativeMap.copyKeysIntoChildren(callback));
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectMap.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectMap.java
index 55bb902..408919e 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectMap.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectMap.java
@@ -37,6 +37,14 @@
.send(NativeMap.copyKeysIntoChildren(callback));
}
+ public static void parentCandidates(AsyncCallback<ProjectMap> callback) {
+ new RestApi("/projects/")
+ .addParameterRaw("type", "PARENT_CANDIDATES")
+ .addParameterTrue("all")
+ .addParameterTrue("d") // description
+ .send(NativeMap.copyKeysIntoChildren(callback));
+ }
+
public static void suggest(String prefix, int limit, AsyncCallback<ProjectMap> cb) {
new RestApi("/projects/" + URL.encode(prefix).replaceAll("[?]", "%3F"))
.addParameterRaw("type", "ALL")
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/ProjectListPopup.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/ProjectListPopup.java
new file mode 100644
index 0000000..217ca5a
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/ProjectListPopup.java
@@ -0,0 +1,160 @@
+// Copyright (C) 2011 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.client.ui;
+
+import com.google.gerrit.client.account.Util;
+import com.google.gerrit.client.projects.ProjectMap;
+import com.google.gerrit.client.rpc.GerritCallback;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.ScrollPanel;
+import com.google.gwtexpui.globalkey.client.GlobalKey;
+import com.google.gwtexpui.globalkey.client.HidePopupPanelCommand;
+import com.google.gwtexpui.user.client.PluginSafeDialogBox;
+
+/** It creates a popup containing all the projects. */
+public class ProjectListPopup {
+ private ProjectsTable projectsTab;
+ private PluginSafeDialogBox popup;
+ private Button close;
+ private ScrollPanel sp;
+ private PopupPanel.PositionCallback popupPosition;
+ private int preferredTop;
+ private int preferredLeft;
+ private boolean popingUp;
+ private boolean firstPopupLoad = true;
+
+ public void initPopup(final String popupText, final String currentPageLink) {
+ createWidgets(popupText, currentPageLink);
+ final FlowPanel pfp = new FlowPanel();
+ sp = new ScrollPanel(projectsTab);
+ sp.setSize("100%", "100%");
+ pfp.add(sp);
+ pfp.add(close);
+ popup.setWidget(pfp);
+ popup.setHeight("100%");
+ popupPosition = getPositionCallback();
+ }
+
+ protected PopupPanel.PositionCallback getPositionCallback() {
+ return new PopupPanel.PositionCallback() {
+ @Override
+ public void setPosition(int offsetWidth, int offsetHeight) {
+ if (preferredTop + offsetHeight > Window.getClientWidth()) {
+ preferredTop = Window.getClientWidth() - offsetHeight;
+ }
+ if (preferredLeft + offsetWidth > Window.getClientWidth()) {
+ preferredLeft = Window.getClientWidth() - offsetWidth;
+ }
+
+ if (preferredTop < 0) {
+ sp.setHeight((sp.getOffsetHeight() + preferredTop) + "px");
+ preferredTop = 0;
+ }
+ if (preferredLeft < 0) {
+ sp.setWidth((sp.getOffsetWidth() + preferredLeft) + "px");
+ preferredLeft = 0;
+ }
+
+ popup.setPopupPosition(preferredLeft, preferredTop);
+ }
+ };
+ }
+
+ protected void onMovePointerTo(String projectName) {
+ }
+
+ protected void openRow(String projectName) {
+ }
+
+ public boolean isPopingUp() {
+ return popingUp;
+ }
+
+ private void createWidgets(final String popupText,
+ final String currentPageLink) {
+ projectsTab = new ProjectsTable() {
+ @Override
+ protected void movePointerTo(final int row, final boolean scroll) {
+ super.movePointerTo(row, scroll);
+ onMovePointerTo(getRowItem(row).name());
+ }
+
+ @Override
+ protected void onOpenRow(final int row) {
+ super.onOpenRow(row);
+ openRow(getRowItem(row).name());
+ }
+ };
+ projectsTab.setSavePointerId(currentPageLink);
+
+ close = new Button(Util.C.projectsClose());
+ close.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(final ClickEvent event) {
+ closePopup();
+ }
+ });
+
+ popup = new PluginSafeDialogBox();
+ popup.setModal(false);
+ popup.setText(popupText);
+ }
+
+ public void displayPopup() {
+ popingUp = true;
+ if (firstPopupLoad) { // For sizing/positioning, delay display until loaded
+ populateProjects();
+ } else {
+ popup.setPopupPositionAndShow(popupPosition);
+ GlobalKey.dialog(popup);
+ try {
+ GlobalKey.addApplication(popup, new HidePopupPanelCommand(0,
+ KeyCodes.KEY_ESCAPE, popup));
+ } catch (Throwable e) {
+ }
+ projectsTab.setRegisterKeys(true);
+ projectsTab.finishDisplay();
+ popingUp = false;
+ }
+ }
+
+ public void closePopup() {
+ popup.hide();
+ }
+
+ public void setPreferredCoordinates(final int top, final int left) {
+ this.preferredTop = top;
+ this.preferredLeft = left;
+ }
+
+ protected void populateProjects() {
+ ProjectMap.all(new GerritCallback<ProjectMap>() {
+ @Override
+ public void onSuccess(final ProjectMap result) {
+ projectsTab.display(result);
+ if (firstPopupLoad) { // Display was delayed until table was loaded
+ firstPopupLoad = false;
+ displayPopup();
+ }
+ }
+ });
+ }
+}
diff --git a/gerrit-httpd/.settings/org.eclipse.core.resources.prefs b/gerrit-httpd/.settings/org.eclipse.core.resources.prefs
index 9df523e..839d647 100644
--- a/gerrit-httpd/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-httpd/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:36 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
index f92f13d..72bb0c2 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
@@ -90,6 +90,10 @@
config.setAllowedOpenIDs(authConfig.getAllowedOpenIDs());
break;
+ case OPENID_SSO:
+ config.setOpenIdSsoUrl(authConfig.getOpenIdSsoUrl());
+ break;
+
case LDAP:
case LDAP_BIND:
config.setRegisterUrl(cfg.getString("auth", null, "registerurl"));
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitOverHttpServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitOverHttpServlet.java
index 1c9c521..aea42f4 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitOverHttpServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GitOverHttpServlet.java
@@ -44,7 +44,6 @@
import org.eclipse.jgit.http.server.resolver.AsIsFileService;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.storage.pack.PackConfig;
import org.eclipse.jgit.transport.ReceivePack;
import org.eclipse.jgit.transport.UploadPack;
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
@@ -177,19 +176,20 @@
}
static class UploadFactory implements UploadPackFactory<HttpServletRequest> {
- private final PackConfig packConfig;
+ private final TransferConfig config;
private final Provider<WebSession> session;
@Inject
UploadFactory(TransferConfig tc, Provider<WebSession> session) {
- this.packConfig = tc.getPackConfig();
+ this.config = tc;
this.session = session;
}
@Override
public UploadPack create(HttpServletRequest req, Repository repo) {
UploadPack up = new UploadPack(repo);
- up.setPackConfig(packConfig);
+ up.setPackConfig(config.getPackConfig());
+ up.setTimeout(config.getTimeout());
session.get().setAccessPath(AccessPath.GIT);
return up;
}
@@ -239,12 +239,14 @@
static class ReceiveFactory implements ReceivePackFactory<HttpServletRequest> {
private final AsyncReceiveCommits.Factory factory;
private final Provider<WebSession> session;
+ private final TransferConfig config;
@Inject
ReceiveFactory(AsyncReceiveCommits.Factory factory,
- Provider<WebSession> session) {
+ Provider<WebSession> session, TransferConfig config) {
this.factory = factory;
this.session = session;
+ this.config = config;
}
@Override
@@ -259,10 +261,13 @@
final IdentifiedUser user = (IdentifiedUser) pc.getCurrentUser();
final ReceiveCommits rc = factory.create(pc, db).getReceiveCommits();
- rc.getReceivePack().setRefLogIdent(user.newRefLogIdent());
+ ReceivePack rp = rc.getReceivePack();
+ rp.setRefLogIdent(user.newRefLogIdent());
+ rp.setTimeout(config.getTimeout());
+ rp.setMaxObjectSizeLimit(config.getMaxObjectSizeLimit());
req.setAttribute(ATT_RC, rc);
session.get().setAccessPath(AccessPath.GIT);
- return rc.getReceivePack();
+ return rp;
}
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebModule.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebModule.java
index 0d14b79..1a48bb5 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebModule.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebModule.java
@@ -108,6 +108,7 @@
break;
case OPENID:
+ case OPENID_SSO:
// OpenID support is bound in WebAppInitializer and Daemon.
case CUSTOM_EXTENSION:
break;
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/ThemeFactory.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/ThemeFactory.java
index 68379d7..a2f4c99 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/ThemeFactory.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/ThemeFactory.java
@@ -43,6 +43,9 @@
theme.trimColor = color(name, "trimColor", "#D4E9A9");
theme.selectionColor = color(name, "selectionColor", "#FFFFCC");
theme.topMenuColor = color(name, "topMenuColor", theme.trimColor);
+ theme.changeTableOutdatedColor = color(name, "changeTableOutdatedColor", "#FF0000");
+ theme.tableOddRowColor = color(name, "tableOddRowColor", "transparent");
+ theme.tableEvenRowColor = color(name, "tableEvenRowColor", "transparent");
return theme;
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/GroupAdminServiceImpl.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/GroupAdminServiceImpl.java
index c7b4c79..aca2e05 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/GroupAdminServiceImpl.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/GroupAdminServiceImpl.java
@@ -31,15 +31,20 @@
import com.google.gerrit.reviewdb.client.AccountGroupIncludeAudit;
import com.google.gerrit.reviewdb.client.AccountGroupMember;
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
+import com.google.gerrit.reviewdb.client.AuthType;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.account.AccountException;
+import com.google.gerrit.server.account.AccountManager;
import com.google.gerrit.server.account.AccountResolver;
+import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.GroupBackends;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.account.GroupControl;
import com.google.gerrit.server.account.GroupIncludeCache;
+import com.google.gerrit.server.config.AuthConfig;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtjsonrpc.common.VoidResult;
import com.google.gwtorm.server.OrmException;
@@ -54,6 +59,8 @@
GroupAdminService {
private final AccountCache accountCache;
private final AccountResolver accountResolver;
+ private final AccountManager accountManager;
+ private final AuthType authType;
private final GroupCache groupCache;
private final GroupBackend groupBackend;
private final GroupIncludeCache groupIncludeCache;
@@ -70,6 +77,8 @@
final AccountCache accountCache,
final GroupIncludeCache groupIncludeCache,
final AccountResolver accountResolver,
+ final AccountManager accountManager,
+ final AuthConfig authConfig,
final GroupCache groupCache,
final GroupBackend groupBackend,
final GroupControl.Factory groupControlFactory,
@@ -81,6 +90,8 @@
this.accountCache = accountCache;
this.groupIncludeCache = groupIncludeCache;
this.accountResolver = accountResolver;
+ this.accountManager = accountManager;
+ this.authType = authConfig.getAuthType();
this.groupCache = groupCache;
this.groupBackend = groupBackend;
this.groupControlFactory = groupControlFactory;
@@ -366,13 +377,38 @@
private Account findAccount(final String nameOrEmail) throws OrmException,
Failure {
- final Account r = accountResolver.find(nameOrEmail);
+ Account r = accountResolver.find(nameOrEmail);
if (r == null) {
- throw new Failure(new NoSuchAccountException(nameOrEmail));
+ switch (authType) {
+ case HTTP_LDAP:
+ case CLIENT_SSL_CERT_LDAP:
+ case LDAP:
+ r = createAccountByLdap(nameOrEmail);
+ break;
+ default:
+ }
+ if (r == null) {
+ throw new Failure(new NoSuchAccountException(nameOrEmail));
+ }
}
return r;
}
+ private Account createAccountByLdap(String user) {
+ if (!user.matches(Account.USER_NAME_PATTERN)) {
+ return null;
+ }
+
+ try {
+ final AuthRequest req = AuthRequest.forUser(user);
+ req.setSkipAuthentication(true);
+ return accountCache.get(accountManager.authenticate(req).getAccountId())
+ .getAccount();
+ } catch (AccountException e) {
+ return null;
+ }
+ }
+
private AccountGroup findGroup(final String name) throws OrmException,
Failure {
final AccountGroup g = groupCache.get(new AccountGroup.NameKey(name));
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/RenameGroup.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/RenameGroup.java
index 09dc582..24faf9e 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/RenameGroup.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/RenameGroup.java
@@ -15,6 +15,7 @@
package com.google.gerrit.httpd.rpc.account;
import com.google.gerrit.common.data.GroupDetail;
+import com.google.gerrit.common.errors.InvalidNameException;
import com.google.gerrit.common.errors.NameAlreadyUsedException;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.httpd.rpc.Handler;
@@ -44,7 +45,7 @@
@Override
public GroupDetail call() throws OrmException, NameAlreadyUsedException,
- NoSuchGroupException {
+ NoSuchGroupException, InvalidNameException {
return performRenameGroupFactory.create().renameGroup(groupId, newName);
}
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/ChangeDetailFactory.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/ChangeDetailFactory.java
index a929b6e..6660a3d 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/ChangeDetailFactory.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/ChangeDetailFactory.java
@@ -32,6 +32,7 @@
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.ChangeUtil;
+import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.ProjectUtil;
import com.google.gerrit.server.account.AccountInfoCacheFactory;
@@ -41,6 +42,7 @@
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
+import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.workflow.CategoryFunction;
import com.google.gerrit.server.workflow.FunctionState;
import com.google.gwtorm.server.OrmException;
@@ -252,6 +254,15 @@
detail.setApprovals(ad.values());
}
+ private boolean isReviewer(Change change) {
+ // Return true if the currently logged in user is a reviewer of the change.
+ try {
+ return control.isReviewer(db, new ChangeData(change));
+ } catch (OrmException e) {
+ return false;
+ }
+ }
+
private void loadCurrentPatchSet() throws OrmException,
NoSuchEntityException, PatchSetInfoNotAvailableException,
NoSuchChangeException {
@@ -292,11 +303,21 @@
final Map<Change.Id, Change> m =
db.changes().toMap(db.changes().get(changesToGet));
+ final CurrentUser currentUser = control.getCurrentUser();
+ Account.Id currentUserId = null;
+ if (currentUser instanceof IdentifiedUser) {
+ currentUserId = ((IdentifiedUser) currentUser).getAccountId();
+ }
+
final ArrayList<ChangeInfo> dependsOn = new ArrayList<ChangeInfo>();
for (final Change.Id a : ancestorOrder) {
final Change ac = m.get(a);
if (ac != null && ac.getProject().equals(detail.getChange().getProject())) {
- dependsOn.add(newChangeInfo(ac, ancestorPatchIds));
+ if (ac.getStatus().getCode() != Change.STATUS_DRAFT
+ || ac.getOwner().equals(currentUserId)
+ || isReviewer(ac)) {
+ dependsOn.add(newChangeInfo(ac, ancestorPatchIds));
+ }
}
}
@@ -304,7 +325,11 @@
for (final PatchSet.Id a : descendants) {
final Change ac = m.get(a.getParentKey());
if (ac != null && ac.currentPatchSetId().equals(a)) {
- neededBy.add(newChangeInfo(ac, null));
+ if (ac.getStatus().getCode() != Change.STATUS_DRAFT
+ || ac.getOwner().equals(currentUserId)
+ || isReviewer(ac)) {
+ neededBy.add(newChangeInfo(ac, null));
+ }
}
}
diff --git a/gerrit-launcher/.settings/org.eclipse.core.resources.prefs b/gerrit-launcher/.settings/org.eclipse.core.resources.prefs
index c780f44..e9441bb 100644
--- a/gerrit-launcher/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-launcher/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:36 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding/<project>=UTF-8
diff --git a/gerrit-main/.settings/org.eclipse.core.resources.prefs b/gerrit-main/.settings/org.eclipse.core.resources.prefs
index c780f44..e9441bb 100644
--- a/gerrit-main/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-main/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:36 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding/<project>=UTF-8
diff --git a/gerrit-openid/.settings/org.eclipse.core.resources.prefs b/gerrit-openid/.settings/org.eclipse.core.resources.prefs
index fc11c3f..f9fe345 100644
--- a/gerrit-openid/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-openid/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:36 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
diff --git a/gerrit-patch-commonsnet/.settings/org.eclipse.core.resources.prefs b/gerrit-patch-commonsnet/.settings/org.eclipse.core.resources.prefs
index 589908f..e9441bb 100644
--- a/gerrit-patch-commonsnet/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-patch-commonsnet/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:35 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding/<project>=UTF-8
diff --git a/gerrit-patch-jgit/.settings/org.eclipse.core.resources.prefs b/gerrit-patch-jgit/.settings/org.eclipse.core.resources.prefs
index 589908f..e9441bb 100644
--- a/gerrit-patch-jgit/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-patch-jgit/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:35 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding/<project>=UTF-8
diff --git a/gerrit-pgm/.settings/org.eclipse.core.resources.prefs b/gerrit-pgm/.settings/org.eclipse.core.resources.prefs
index 9df523e..839d647 100644
--- a/gerrit-pgm/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-pgm/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:36 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
index 263b2b4..7d27482 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
@@ -369,7 +369,8 @@
}
AuthConfig authConfig = cfgInjector.getInstance(AuthConfig.class);
- if (authConfig.getAuthType() == AuthType.OPENID) {
+ if (authConfig.getAuthType() == AuthType.OPENID ||
+ authConfig.getAuthType() == AuthType.OPENID_SSO) {
modules.add(new OpenIdModule());
}
modules.add(sysInjector.getInstance(GetUserFilter.Module.class));
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/ExportReviewNotes.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/ExportReviewNotes.java
index f100372..525360d 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/ExportReviewNotes.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/ExportReviewNotes.java
@@ -21,7 +21,6 @@
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.pgm.util.SiteProgram;
import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.account.AccountCacheImpl;
@@ -35,6 +34,7 @@
import com.google.gerrit.server.git.CreateCodeReviewNotes;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.LocalDiskRepositoryManager;
+import com.google.gerrit.server.git.NotesBranchUtil;
import com.google.gerrit.server.schema.SchemaVersionCheck;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
@@ -44,7 +44,6 @@
import com.google.inject.Scopes;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
-import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.lib.ThreadSafeProgressMonitor;
@@ -104,6 +103,7 @@
@Override
protected void configure() {
factory(CreateCodeReviewNotes.Factory.class);
+ factory(NotesBranchUtil.Factory.class);
}
});
install(new LifecycleModule() {
@@ -172,21 +172,8 @@
}
try {
CreateCodeReviewNotes notes = codeReviewNotesFactory.create(db, git);
- try {
- notes.loadBase();
- for (Change change : changes) {
- monitor.update(1);
- PatchSet ps = db.patchSets().get(change.currentPatchSetId());
- if (ps == null) {
- continue;
- }
- notes.add(change, ObjectId.fromString(ps.getRevision().get()));
- }
- notes.commit("Exported prior reviews from Gerrit Code Review\n");
- notes.updateRef();
- } finally {
- notes.release();
- }
+ notes.create(changes, null,
+ "Exported prior reviews from Gerrit Code Review\n", monitor);
} finally {
git.close();
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Init.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Init.java
index 2d56453..95b8487f 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Init.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Init.java
@@ -141,12 +141,12 @@
}
final StringBuilder buf = new StringBuilder();
- buf.append(why.getMessage());
- why = why.getCause();
while (why != null) {
- buf.append("\n caused by ");
- buf.append(why.toString());
+ buf.append(why.getMessage());
why = why.getCause();
+ if (why != null) {
+ buf.append("\n caused by ");
+ }
}
throw die(buf.toString(), new RuntimeException("InitInjector failed", ce));
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/ProjectQoSFilter.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/ProjectQoSFilter.java
index ee7c794..2d6db63 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/ProjectQoSFilter.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/ProjectQoSFilter.java
@@ -97,7 +97,7 @@
this.userProvider = userProvider;
this.queue = queue;
this.context = context;
- this.maxWait = getTimeUnit(cfg, "httpd", null, "maxwait", 5, MINUTES);
+ this.maxWait = MINUTES.toMillis(getTimeUnit(cfg, "httpd", null, "maxwait", 5, MINUTES));
}
@Override
diff --git a/gerrit-plugin-archetype/.settings/org.eclipse.core.resources.prefs b/gerrit-plugin-archetype/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..abdea9ac
--- /dev/null
+++ b/gerrit-plugin-archetype/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding/<project>=UTF-8
diff --git a/gerrit-plugin-archetype/.settings/org.eclipse.jdt.core.prefs b/gerrit-plugin-archetype/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..470942d
--- /dev/null
+++ b/gerrit-plugin-archetype/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,269 @@
+#Thu Jul 28 11:02:36 PDT 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=16
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=0
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=0
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=2
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=true
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=3
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=2
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
diff --git a/gerrit-plugin-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml b/gerrit-plugin-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml
index 88328be..ce8fa1a 100644
--- a/gerrit-plugin-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml
+++ b/gerrit-plugin-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<archetype-descriptor name="com.sap.ldi.qi.itests">
+<archetype-descriptor name="Gerrit Plugin">
<requiredProperties>
<requiredProperty key="pluginName"/>
diff --git a/gerrit-prettify/.settings/org.eclipse.core.resources.prefs b/gerrit-prettify/.settings/org.eclipse.core.resources.prefs
index e7d6680..abdea9ac 100644
--- a/gerrit-prettify/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-prettify/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:35 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
diff --git a/gerrit-reviewdb/.settings/org.eclipse.core.resources.prefs b/gerrit-reviewdb/.settings/org.eclipse.core.resources.prefs
index e7d6680..abdea9ac 100644
--- a/gerrit-reviewdb/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-reviewdb/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:35 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AuthType.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AuthType.java
index 962426b..b615fc5 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AuthType.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AuthType.java
@@ -18,6 +18,9 @@
/** Login relies upon the OpenID standard: {@link "http://openid.net/"} */
OPENID,
+ /** Login relies upon the OpenID standard: {@link "http://openid.net/"} in Single Sign On mode */
+ OPENID_SSO,
+
/**
* Login relies upon the container/web server security.
* <p>
diff --git a/gerrit-server/.settings/org.eclipse.core.resources.prefs b/gerrit-server/.settings/org.eclipse.core.resources.prefs
index 7d5f965..29abf99 100644
--- a/gerrit-server/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-server/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:36 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
diff --git a/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHookRunner.java b/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHookRunner.java
index 79c047f..935a707 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHookRunner.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHookRunner.java
@@ -35,7 +35,7 @@
import com.google.gerrit.server.events.ChangeAbandonedEvent;
import com.google.gerrit.server.events.ChangeEvent;
import com.google.gerrit.server.events.ChangeMergedEvent;
-import com.google.gerrit.server.events.ChangeRestoreEvent;
+import com.google.gerrit.server.events.ChangeRestoredEvent;
import com.google.gerrit.server.events.CommentAddedEvent;
import com.google.gerrit.server.events.DraftPublishedEvent;
import com.google.gerrit.server.events.EventFactory;
@@ -111,7 +111,7 @@
/** Filename of the change abandoned hook. */
private final File changeAbandonedHook;
- /** Filename of the change abandoned hook. */
+ /** Filename of the change restored hook. */
private final File changeRestoredHook;
/** Filename of the ref updated hook. */
@@ -339,9 +339,9 @@
runHook(change.getProject(), changeAbandonedHook, args);
}
- public void doChangeRestoreHook(final Change change, final Account account,
+ public void doChangeRestoredHook(final Change change, final Account account,
final String reason, final ReviewDb db) throws OrmException {
- final ChangeRestoreEvent event = new ChangeRestoreEvent();
+ final ChangeRestoredEvent event = new ChangeRestoredEvent();
event.change = eventFactory.asChangeAttribute(change);
event.restorer = eventFactory.asAccountAttribute(account);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHooks.java b/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHooks.java
index 0c86049..134057d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHooks.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHooks.java
@@ -61,7 +61,7 @@
*
* @param change The change itself.
* @param patchSet The patchset this comment is related to.
- * @param account The gerrit user who commited the change.
+ * @param account The gerrit user who added the comment.
* @param comment The comment given.
* @param approvals Map of Approval Categories and Scores
* @throws OrmException
@@ -75,7 +75,7 @@
* Fire the Change Merged Hook.
*
* @param change The change itself.
- * @param account The gerrit user who commited the change.
+ * @param account The gerrit user who submitted the change.
* @param patchSet The patchset that was merged.
* @throws OrmException
*/
@@ -101,7 +101,7 @@
* @param reason Reason for restoring the change.
* @throws OrmException
*/
- public void doChangeRestoreHook(Change change, Account account,
+ public void doChangeRestoredHook(Change change, Account account,
String reason, ReviewDb db) throws OrmException;
/**
diff --git a/gerrit-server/src/main/java/com/google/gerrit/common/DisabledChangeHooks.java b/gerrit-server/src/main/java/com/google/gerrit/common/DisabledChangeHooks.java
index 357a8b9..f30f5ea 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/common/DisabledChangeHooks.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/common/DisabledChangeHooks.java
@@ -46,7 +46,7 @@
}
@Override
- public void doChangeRestoreHook(Change change, Account account,
+ public void doChangeRestoredHook(Change change, Account account,
String reason, ReviewDb db) {
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
index a0814f5..3868710 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
@@ -62,6 +62,7 @@
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.util.Base64;
+import org.eclipse.jgit.util.ChangeIdUtil;
import org.eclipse.jgit.util.NB;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -463,7 +464,11 @@
revertCommit.setTreeId(parentToCommitToRevert.getTree());
revertCommit.setAuthor(authorIdent);
revertCommit.setCommitter(myIdent);
- revertCommit.setMessage(message);
+
+ final ObjectId computedChangeId =
+ ChangeIdUtil.computeChangeId(parentToCommitToRevert.getTree(),
+ commitToRevert, authorIdent, myIdent, message);
+ revertCommit.setMessage(ChangeIdUtil.insertId(message, computedChangeId, true));
final ObjectInserter oi = git.newObjectInserter();;
ObjectId id;
@@ -474,7 +479,7 @@
oi.release();
}
- Change.Key changeKey = new Change.Key("I" + id.name());
+ Change.Key changeKey = new Change.Key("I" + computedChangeId.name());
final Change change =
new Change(changeKey, new Change.Id(db.nextChangeId()),
user.getAccountId(), db.changes().get(changeId).getDest());
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PerformRenameGroup.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PerformRenameGroup.java
index 6db232a..4c72d49 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PerformRenameGroup.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PerformRenameGroup.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.account;
import com.google.gerrit.common.data.GroupDetail;
+import com.google.gerrit.common.errors.InvalidNameException;
import com.google.gerrit.common.errors.NameAlreadyUsedException;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.reviewdb.client.AccountGroup;
@@ -60,7 +61,7 @@
public GroupDetail renameGroup(final String groupName,
final String newGroupName) throws OrmException, NameAlreadyUsedException,
- NoSuchGroupException {
+ NoSuchGroupException, InvalidNameException {
final AccountGroup.NameKey groupNameKey =
new AccountGroup.NameKey(groupName);
final AccountGroup group = groupCache.get(groupNameKey);
@@ -72,12 +73,15 @@
public GroupDetail renameGroup(final AccountGroup.Id groupId,
final String newName) throws OrmException, NameAlreadyUsedException,
- NoSuchGroupException {
+ NoSuchGroupException, InvalidNameException {
final GroupControl ctl = groupControlFactory.validateFor(groupId);
final AccountGroup group = db.accountGroups().get(groupId);
if (group == null || !ctl.isOwner()) {
throw new NoSuchGroupException(groupId);
}
+ if (newName.trim().isEmpty()) {
+ throw new InvalidNameException();
+ }
final AccountGroup.NameKey old = group.getNameKey();
final AccountGroup.NameKey key = new AccountGroup.NameKey(newName);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RestoreChange.java b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RestoreChange.java
index 875ae06..53da2b6 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RestoreChange.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RestoreChange.java
@@ -149,8 +149,8 @@
ChangeUtil.updatedChange(db, currentUser, updatedChange, cmsg,
restoredSenderFactory);
- hooks.doChangeRestoreHook(updatedChange, currentUser.getAccount(),
- message, db);
+ hooks.doChangeRestoredHook(updatedChange, currentUser.getAccount(),
+ message, db);
return result;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java
index 6f1096c..dc36988 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java
@@ -39,6 +39,7 @@
private final boolean userNameToLowerCase;
private final boolean gitBasicAuth;
private final String logoutUrl;
+ private final String openIdSsoUrl;
private final List<OpenIdProviderPattern> trustedOpenIDs;
private final List<OpenIdProviderPattern> allowedOpenIDs;
private final String cookiePath;
@@ -53,6 +54,7 @@
authType = toType(cfg);
httpHeader = cfg.getString("auth", null, "httpheader");
logoutUrl = cfg.getString("auth", null, "logouturl");
+ openIdSsoUrl = cfg.getString("auth", null, "openidssourl");
trustedOpenIDs = toPatterns(cfg, "trustedOpenID");
allowedOpenIDs = toPatterns(cfg, "allowedOpenID");
cookiePath = cfg.getString("auth", null, "cookiepath");
@@ -111,6 +113,10 @@
return logoutUrl;
}
+ public String getOpenIdSsoUrl() {
+ return openIdSsoUrl;
+ }
+
public String getCookiePath() {
return cookiePath;
}
@@ -161,6 +167,10 @@
//
return true;
+ case OPENID_SSO:
+ // There's only one provider in SSO mode, so it must be okay.
+ return true;
+
case OPENID:
// All identities must be trusted in order to trust the account.
//
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java
index 71676ad..ba54c56 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java
@@ -35,6 +35,7 @@
import com.google.gerrit.server.git.CreateCodeReviewNotes;
import com.google.gerrit.server.git.MergeOp;
import com.google.gerrit.server.git.MetaDataUpdate;
+import com.google.gerrit.server.git.NotesBranchUtil;
import com.google.gerrit.server.git.SubmoduleOp;
import com.google.gerrit.server.mail.AbandonedSender;
import com.google.gerrit.server.mail.AddReviewerSender;
@@ -82,6 +83,7 @@
factory(SubmoduleOp.Factory.class);
factory(MergeOp.Factory.class);
factory(CreateCodeReviewNotes.Factory.class);
+ factory(NotesBranchUtil.Factory.class);
install(new AsyncReceiveCommits.Module());
// Not really per-request, but dammit, I don't know where else to
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/events/ChangeRestoreEvent.java b/gerrit-server/src/main/java/com/google/gerrit/server/events/ChangeRestoredEvent.java
similarity index 93%
rename from gerrit-server/src/main/java/com/google/gerrit/server/events/ChangeRestoreEvent.java
rename to gerrit-server/src/main/java/com/google/gerrit/server/events/ChangeRestoredEvent.java
index 1a2922b..717e23c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/events/ChangeRestoreEvent.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/events/ChangeRestoredEvent.java
@@ -14,7 +14,7 @@
package com.google.gerrit.server.events;
-public class ChangeRestoreEvent extends ChangeEvent {
+public class ChangeRestoredEvent extends ChangeEvent {
public final String type = "change-restored";
public ChangeAttribute change;
public PatchSetAttribute patchSet;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/BanCommit.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/BanCommit.java
index 4bfee9c..da38573 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/BanCommit.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/BanCommit.java
@@ -16,6 +16,7 @@
import static com.google.gerrit.server.git.GitRepositoryManager.REF_REJECT_COMMITS;
+import com.google.common.base.Strings;
import com.google.gerrit.common.errors.PermissionDeniedException;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
@@ -23,34 +24,25 @@
import com.google.inject.Inject;
import com.google.inject.Provider;
-import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.notes.Note;
import org.eclipse.jgit.notes.NoteMap;
-import org.eclipse.jgit.notes.NoteMapMerger;
-import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
public class BanCommit {
-
- private static final int MAX_LOCK_FAILURE_CALLS = 10;
- private static final int SLEEP_ON_LOCK_FAILURE_MS = 25;
-
public interface Factory {
BanCommit create();
}
@@ -58,49 +50,37 @@
private final Provider<IdentifiedUser> currentUser;
private final GitRepositoryManager repoManager;
private final PersonIdent gerritIdent;
+ private NotesBranchUtil.Factory notesBranchUtilFactory;
@Inject
BanCommit(final Provider<IdentifiedUser> currentUser,
final GitRepositoryManager repoManager,
- @GerritPersonIdent final PersonIdent gerritIdent) {
+ @GerritPersonIdent final PersonIdent gerritIdent,
+ final NotesBranchUtil.Factory notesBranchUtilFactory) {
this.currentUser = currentUser;
this.repoManager = repoManager;
this.gerritIdent = gerritIdent;
+ this.notesBranchUtilFactory = notesBranchUtilFactory;
}
public BanCommitResult ban(final ProjectControl projectControl,
final List<ObjectId> commitsToBan, final String reason)
throws PermissionDeniedException, IOException,
- InterruptedException, MergeException {
+ InterruptedException, MergeException, ConcurrentRefUpdateException {
if (!projectControl.isOwner()) {
throw new PermissionDeniedException(
"No project owner: not permitted to ban commits");
}
final BanCommitResult result = new BanCommitResult();
-
- final PersonIdent currentUserIdent = createPersonIdent();
+ NoteMap banCommitNotes = NoteMap.newEmptyMap();
+ // add a note for each banned commit to notes
final Repository repo =
repoManager.openRepository(projectControl.getProject().getNameKey());
try {
final RevWalk revWalk = new RevWalk(repo);
final ObjectInserter inserter = repo.newObjectInserter();
try {
- NoteMap baseNoteMap = null;
- RevCommit baseCommit = null;
- final Ref notesBranch = repo.getRef(REF_REJECT_COMMITS);
- if (notesBranch != null) {
- baseCommit = revWalk.parseCommit(notesBranch.getObjectId());
- baseNoteMap = NoteMap.read(revWalk.getObjectReader(), baseCommit);
- }
-
- final NoteMap ourNoteMap;
- if (baseCommit != null) {
- ourNoteMap = NoteMap.read(repo.newObjectReader(), baseCommit);
- } else {
- ourNoteMap = NoteMap.newEmptyMap();
- }
-
for (final ObjectId commitToBan : commitsToBan) {
try {
revWalk.parseCommit(commitToBan);
@@ -110,31 +90,22 @@
result.notACommit(commitToBan, e.getMessage());
continue;
}
+ banCommitNotes.set(commitToBan, createNoteContent(reason, inserter));
+ }
+ inserter.flush();
+ NotesBranchUtil notesBranchUtil = notesBranchUtilFactory.create(repo);
+ NoteMap newlyCreated =
+ notesBranchUtil.commitNewNotes(banCommitNotes, REF_REJECT_COMMITS,
+ createPersonIdent(), buildCommitMessage(commitsToBan, reason));
- final Note note = ourNoteMap.getNote(commitToBan);
- if (note != null) {
- result.commitAlreadyBanned(commitToBan);
- continue;
+ for (Note n : banCommitNotes) {
+ if (newlyCreated.contains(n)) {
+ result.commitBanned(n);
+ } else {
+ result.commitAlreadyBanned(n);
}
-
- final String noteContent = reason != null ? reason : "";
- final ObjectId noteContentId =
- inserter
- .insert(Constants.OBJ_BLOB, noteContent.getBytes("UTF-8"));
- ourNoteMap.set(commitToBan, noteContentId);
- result.commitBanned(commitToBan);
}
-
- if (result.getNewlyBannedCommits().isEmpty()) {
- return result;
- }
-
- final ObjectId ourCommit =
- commit(ourNoteMap, inserter, currentUserIdent, baseCommit, result,
- reason);
-
- updateRef(repo, revWalk, inserter, ourNoteMap, ourCommit, baseNoteMap,
- baseCommit);
+ return result;
} finally {
revWalk.release();
inserter.release();
@@ -142,8 +113,15 @@
} finally {
repo.close();
}
+ }
- return result;
+ private ObjectId createNoteContent(String reason, ObjectInserter inserter)
+ throws UnsupportedEncodingException, IOException {
+ String noteContent = reason != null ? reason : "";
+ if (noteContent.length() > 0 && !noteContent.endsWith("\n")) {
+ noteContent = noteContent + "\n";
+ }
+ return inserter.insert(Constants.OBJ_BLOB, noteContent.getBytes("UTF-8"));
}
private PersonIdent createPersonIdent() {
@@ -152,35 +130,6 @@
return currentUser.get().newCommitterIdent(now, tz);
}
- private static ObjectId commit(final NoteMap noteMap,
- final ObjectInserter inserter, final PersonIdent personIdent,
- final ObjectId baseCommit, final BanCommitResult result,
- final String reason) throws IOException {
- final String commitMsg =
- buildCommitMessage(result.getNewlyBannedCommits(), reason);
- if (baseCommit != null) {
- return createCommit(noteMap, inserter, personIdent, commitMsg, baseCommit);
- } else {
- return createCommit(noteMap, inserter, personIdent, commitMsg);
- }
- }
-
- private static ObjectId createCommit(final NoteMap noteMap,
- final ObjectInserter inserter, final PersonIdent personIdent,
- final String message, final ObjectId... parents) throws IOException {
- final CommitBuilder b = new CommitBuilder();
- b.setTreeId(noteMap.writeTree(inserter));
- b.setAuthor(personIdent);
- b.setCommitter(personIdent);
- if (parents.length > 0) {
- b.setParentIds(parents);
- }
- b.setMessage(message);
- final ObjectId commitId = inserter.insert(b);
- inserter.flush();
- return commitId;
- }
-
private static String buildCommitMessage(final List<ObjectId> bannedCommits,
final String reason) {
final StringBuilder commitMsg = new StringBuilder();
@@ -205,61 +154,4 @@
commitMsg.append(commitList);
return commitMsg.toString();
}
-
- public void updateRef(final Repository repo, final RevWalk revWalk,
- final ObjectInserter inserter, final NoteMap ourNoteMap,
- final ObjectId oursCommit, final NoteMap baseNoteMap,
- final ObjectId baseCommit) throws IOException, InterruptedException,
- MissingObjectException, IncorrectObjectTypeException,
- CorruptObjectException, MergeException {
-
- int remainingLockFailureCalls = MAX_LOCK_FAILURE_CALLS;
- RefUpdate refUpdate = createRefUpdate(repo, oursCommit, baseCommit);
-
- for (;;) {
- final Result result = refUpdate.update();
-
- if (result == Result.LOCK_FAILURE) {
- if (--remainingLockFailureCalls > 0) {
- Thread.sleep(SLEEP_ON_LOCK_FAILURE_MS);
- } else {
- throw new MergeException("Failed to lock the ref: "
- + REF_REJECT_COMMITS);
- }
-
- } else if (result == Result.REJECTED) {
- final RevCommit theirsCommit =
- revWalk.parseCommit(refUpdate.getOldObjectId());
- final NoteMap theirNoteMap =
- NoteMap.read(revWalk.getObjectReader(), theirsCommit);
- final NoteMapMerger merger = new NoteMapMerger(repo);
- final NoteMap merged =
- merger.merge(baseNoteMap, ourNoteMap, theirNoteMap);
- final ObjectId mergeCommit =
- createCommit(merged, inserter, gerritIdent,
- "Merged note commits\n", oursCommit, theirsCommit);
- refUpdate = createRefUpdate(repo, mergeCommit, theirsCommit);
- remainingLockFailureCalls = MAX_LOCK_FAILURE_CALLS;
-
- } else if (result == Result.IO_FAILURE) {
- throw new IOException(
- "Couldn't create commit reject notes because of IO_FAILURE");
- } else {
- break;
- }
- }
- }
-
- private static RefUpdate createRefUpdate(final Repository repo,
- final ObjectId newObjectId, final ObjectId expectedOldObjectId)
- throws IOException {
- RefUpdate refUpdate = repo.updateRef(REF_REJECT_COMMITS);
- refUpdate.setNewObjectId(newObjectId);
- if (expectedOldObjectId == null) {
- refUpdate.setExpectedOldObjectId(ObjectId.zeroId());
- } else {
- refUpdate.setExpectedOldObjectId(expectedOldObjectId);
- }
- return refUpdate;
- }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/CreateCodeReviewNotes.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/CreateCodeReviewNotes.java
index 6fea8f1..b067a49 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/CreateCodeReviewNotes.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/CreateCodeReviewNotes.java
@@ -20,6 +20,7 @@
import com.google.gerrit.common.data.ApprovalTypes;
import com.google.gerrit.reviewdb.client.ApprovalCategory;
import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.GerritPersonIdent;
@@ -31,23 +32,15 @@
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
-import org.eclipse.jgit.errors.CorruptObjectException;
-import org.eclipse.jgit.errors.IncorrectObjectTypeException;
-import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.lib.CommitBuilder;
+import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.PersonIdent;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.RefUpdate.Result;
+import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.notes.Note;
import org.eclipse.jgit.notes.NoteMap;
-import org.eclipse.jgit.notes.NoteMapMerger;
-import org.eclipse.jgit.notes.NoteMerger;
import org.eclipse.jgit.revwalk.FooterKey;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
@@ -68,30 +61,22 @@
CreateCodeReviewNotes create(ReviewDb reviewDb, Repository db);
}
- private static final int MAX_LOCK_FAILURE_CALLS = 10;
- private static final int SLEEP_ON_LOCK_FAILURE_MS = 25;
private static final FooterKey CHANGE_ID = new FooterKey("Change-Id");
- private final ReviewDb schema;
- private final PersonIdent gerritIdent;
private final AccountCache accountCache;
private final ApprovalTypes approvalTypes;
private final String canonicalWebUrl;
private final String anonymousCowardName;
+ private final ReviewDb schema;
private final Repository db;
- private final RevWalk revWalk;
- private final ObjectInserter inserter;
- private final ObjectReader reader;
- private RevCommit baseCommit;
- private NoteMap base;
-
- private RevCommit oursCommit;
- private NoteMap ours;
-
- private List<CodeReviewCommit> commits;
private PersonIdent author;
+ private RevWalk revWalk;
+ private ObjectInserter inserter;
+
+ private final NotesBranchUtil.Factory notesBranchUtilFactory;
+
@Inject
CreateCodeReviewNotes(
@GerritPersonIdent final PersonIdent gerritIdent,
@@ -99,90 +84,87 @@
final ApprovalTypes approvalTypes,
final @Nullable @CanonicalWebUrl String canonicalWebUrl,
final @AnonymousCowardName String anonymousCowardName,
+ final NotesBranchUtil.Factory notesBranchUtilFactory,
final @Assisted ReviewDb reviewDb,
final @Assisted Repository db) {
- schema = reviewDb;
this.author = gerritIdent;
- this.gerritIdent = gerritIdent;
this.accountCache = accountCache;
this.approvalTypes = approvalTypes;
this.canonicalWebUrl = canonicalWebUrl;
this.anonymousCowardName = anonymousCowardName;
+ this.notesBranchUtilFactory = notesBranchUtilFactory;
+ schema = reviewDb;
this.db = db;
-
- revWalk = new RevWalk(db);
- inserter = db.newObjectInserter();
- reader = db.newObjectReader();
}
public void create(List<CodeReviewCommit> commits, PersonIdent author)
throws CodeReviewNoteCreationException {
try {
- this.commits = commits;
- this.author = author;
- loadBase();
- applyNotes();
- updateRef();
+ revWalk = new RevWalk(db);
+ inserter = db.newObjectInserter();
+ if (author != null) {
+ this.author = author;
+ }
+
+ NoteMap notes = NoteMap.newEmptyMap();
+ StringBuilder message =
+ new StringBuilder("Update notes for submitted changes\n\n");
+ for (CodeReviewCommit c : commits) {
+ notes.set(c, createNoteContent(c.change, c));
+ message.append("* ").append(c.getShortMessage()).append("\n");
+ }
+
+ NotesBranchUtil notesBranchUtil = notesBranchUtilFactory.create(db);
+ notesBranchUtil.commitAllNotes(notes, REFS_NOTES_REVIEW, author,
+ message.toString());
} catch (IOException e) {
throw new CodeReviewNoteCreationException(e);
- } catch (InterruptedException e) {
+ } catch (ConcurrentRefUpdateException e) {
throw new CodeReviewNoteCreationException(e);
} finally {
- release();
+ revWalk.release();
+ inserter.release();
}
}
- public void loadBase() throws IOException {
- Ref notesBranch = db.getRef(REFS_NOTES_REVIEW);
- if (notesBranch != null) {
- baseCommit = revWalk.parseCommit(notesBranch.getObjectId());
- base = NoteMap.read(revWalk.getObjectReader(), baseCommit);
- }
- if (baseCommit != null) {
- ours = NoteMap.read(db.newObjectReader(), baseCommit);
- } else {
- ours = NoteMap.newEmptyMap();
+ public void create(List<Change> changes, PersonIdent author,
+ String commitMessage, ProgressMonitor monitor) throws OrmException,
+ IOException, CodeReviewNoteCreationException {
+ try {
+ revWalk = new RevWalk(db);
+ inserter = db.newObjectInserter();
+ if (author != null) {
+ this.author = author;
+ }
+ if (monitor == null) {
+ monitor = NullProgressMonitor.INSTANCE;
+ }
+
+ NoteMap notes = NoteMap.newEmptyMap();
+ for (Change c : changes) {
+ monitor.update(1);
+ PatchSet ps = schema.patchSets().get(c.currentPatchSetId());
+ ObjectId commitId = ObjectId.fromString(ps.getRevision().get());
+ notes.set(commitId, createNoteContent(c, commitId));
+ }
+
+ NotesBranchUtil notesBranchUtil = notesBranchUtilFactory.create(db);
+ notesBranchUtil.commitAllNotes(notes, REFS_NOTES_REVIEW, author,
+ commitMessage);
+ } catch (ConcurrentRefUpdateException e) {
+ throw new CodeReviewNoteCreationException(e);
+ } finally {
+ revWalk.release();
+ inserter.release();
}
}
- private void applyNotes() throws IOException, CodeReviewNoteCreationException {
- StringBuilder message =
- new StringBuilder("Update notes for submitted changes\n\n");
- for (CodeReviewCommit c : commits) {
- add(c.change, c);
- message.append("* ").append(c.getShortMessage()).append("\n");
- }
- commit(message.toString());
- }
-
- public void commit(String message) throws IOException {
- if (baseCommit != null) {
- oursCommit = createCommit(ours, author, message, baseCommit);
- } else {
- oursCommit = createCommit(ours, author, message);
- }
- }
-
- public void add(Change change, ObjectId commit)
- throws MissingObjectException, IncorrectObjectTypeException, IOException,
- CodeReviewNoteCreationException {
+ private ObjectId createNoteContent(Change change, ObjectId commit)
+ throws CodeReviewNoteCreationException, IOException {
if (!(commit instanceof RevCommit)) {
commit = revWalk.parseCommit(commit);
}
-
- RevCommit c = (RevCommit) commit;
- ObjectId noteContent = createNoteContent(change, c);
- if (ours.contains(c)) {
- // merge the existing and the new note as if they are both new
- // means: base == null
- // there is not really a common ancestry for these two note revisions
- // use the same NoteMerger that is used from the NoteMapMerger
- NoteMerger noteMerger = new ReviewNoteMerger();
- Note newNote = new Note(c, noteContent);
- noteContent = noteMerger.merge(null, newNote, ours.getNote(c),
- reader, inserter).getData();
- }
- ours.set(c, noteContent);
+ return createNoteContent(change, (RevCommit) commit);
}
private ObjectId createNoteContent(Change change, RevCommit commit)
@@ -227,83 +209,4 @@
throw new CodeReviewNoteCreationException(commit, e);
}
}
-
- public void updateRef() throws IOException, InterruptedException,
- CodeReviewNoteCreationException, MissingObjectException,
- IncorrectObjectTypeException, CorruptObjectException {
- if (baseCommit != null && oursCommit.getTree().equals(baseCommit.getTree())) {
- // If the trees are identical, there is no change in the notes.
- // Avoid saving this commit as it has no new information.
- return;
- }
-
- int remainingLockFailureCalls = MAX_LOCK_FAILURE_CALLS;
- RefUpdate refUpdate = createRefUpdate(oursCommit, baseCommit);
-
- for (;;) {
- Result result = refUpdate.update();
-
- if (result == Result.LOCK_FAILURE) {
- if (--remainingLockFailureCalls > 0) {
- Thread.sleep(SLEEP_ON_LOCK_FAILURE_MS);
- } else {
- throw new CodeReviewNoteCreationException(
- "Failed to lock the ref: " + REFS_NOTES_REVIEW);
- }
-
- } else if (result == Result.REJECTED) {
- RevCommit theirsCommit =
- revWalk.parseCommit(refUpdate.getOldObjectId());
- NoteMap theirs =
- NoteMap.read(revWalk.getObjectReader(), theirsCommit);
- NoteMapMerger merger = new NoteMapMerger(db);
- NoteMap merged = merger.merge(base, ours, theirs);
- RevCommit mergeCommit =
- createCommit(merged, gerritIdent, "Merged note commits\n",
- theirsCommit, oursCommit);
- refUpdate = createRefUpdate(mergeCommit, theirsCommit);
- remainingLockFailureCalls = MAX_LOCK_FAILURE_CALLS;
-
- } else if (result == Result.IO_FAILURE) {
- throw new CodeReviewNoteCreationException(
- "Couldn't create code review notes because of IO_FAILURE");
- } else {
- break;
- }
- }
- }
-
- public void release() {
- reader.release();
- inserter.release();
- revWalk.release();
- }
-
- private RevCommit createCommit(NoteMap map, PersonIdent author,
- String message, RevCommit... parents) throws IOException {
- CommitBuilder b = new CommitBuilder();
- b.setTreeId(map.writeTree(inserter));
- b.setAuthor(author != null ? author : gerritIdent);
- b.setCommitter(gerritIdent);
- if (parents.length > 0) {
- b.setParentIds(parents);
- }
- b.setMessage(message);
- ObjectId commitId = inserter.insert(b);
- inserter.flush();
- return revWalk.parseCommit(commitId);
- }
-
-
- private RefUpdate createRefUpdate(ObjectId newObjectId,
- ObjectId expectedOldObjectId) throws IOException {
- RefUpdate refUpdate = db.updateRef(REFS_NOTES_REVIEW);
- refUpdate.setNewObjectId(newObjectId);
- if (expectedOldObjectId == null) {
- refUpdate.setExpectedOldObjectId(ObjectId.zeroId());
- } else {
- refUpdate.setExpectedOldObjectId(expectedOldObjectId);
- }
- return refUpdate;
- }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/NotesBranchUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/NotesBranchUtil.java
new file mode 100644
index 0000000..17cfea8
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/NotesBranchUtil.java
@@ -0,0 +1,271 @@
+// Copyright (C) 2012 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.server.GerritPersonIdent;
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+
+import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
+import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.lib.CommitBuilder;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.RefUpdate.Result;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.merge.MergeStrategy;
+import org.eclipse.jgit.notes.Note;
+import org.eclipse.jgit.notes.NoteMap;
+import org.eclipse.jgit.notes.NoteMapMerger;
+import org.eclipse.jgit.notes.NoteMerger;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+
+import java.io.IOException;
+
+/**
+ * A utility class for updating a notes branch with automatic merge of note
+ * trees.
+ */
+public class NotesBranchUtil {
+ public interface Factory {
+ NotesBranchUtil create(Repository db);
+ }
+
+ private static final int MAX_LOCK_FAILURE_CALLS = 10;
+ private static final int SLEEP_ON_LOCK_FAILURE_MS = 25;
+
+ private PersonIdent gerritIdent;
+ private final Repository db;
+
+ private RevCommit baseCommit;
+ private NoteMap base;
+
+ private RevCommit oursCommit;
+ private NoteMap ours;
+
+ private RevWalk revWalk;
+ private ObjectInserter inserter;
+ private ObjectReader reader;
+ private boolean overwrite;
+
+ private ReviewNoteMerger noteMerger;
+
+ @Inject
+ public NotesBranchUtil(@GerritPersonIdent final PersonIdent gerritIdent,
+ @Assisted Repository db) {
+ this.gerritIdent = gerritIdent;
+ this.db = db;
+ }
+
+ /**
+ * Create a new commit in the <code>notesBranch</code> by updating existing
+ * or creating new notes from the <code>notes</code> map.
+ *
+ * @param notes map of notes
+ * @param notesBranch notes branch to update
+ * @param commitAuthor author of the commit in the notes branch
+ * @param commitMessage for the commit in the notes branch
+ * @throws IOException
+ * @throws ConcurrentRefUpdateException
+ */
+ public final void commitAllNotes(NoteMap notes, String notesBranch,
+ PersonIdent commitAuthor, String commitMessage) throws IOException,
+ ConcurrentRefUpdateException {
+ this.overwrite = true;
+ commitNotes(notes, notesBranch, commitAuthor, commitMessage);
+ }
+
+ /**
+ * Create a new commit in the <code>notesBranch</code> by creating not yet
+ * existing notes from the <code>notes</code> map. The notes from the
+ * <code>notes</code> map which already exist in the note-tree of the
+ * tip of the <code>notesBranch</code> will not be updated.
+ *
+ * @param notes map of notes
+ * @param notesBranch notes branch to update
+ * @param commitAuthor author of the commit in the notes branch
+ * @param commitMessage for the commit in the notes branch
+ * @return map with those notes from the <code>notes</code> that were newly
+ * created
+ * @throws IOException
+ * @throws ConcurrentRefUpdateException
+ */
+ public final NoteMap commitNewNotes(NoteMap notes, String notesBranch,
+ PersonIdent commitAuthor, String commitMessage) throws IOException,
+ ConcurrentRefUpdateException {
+ this.overwrite = false;
+ commitNotes(notes, notesBranch, commitAuthor, commitMessage);
+ NoteMap newlyCreated = NoteMap.newEmptyMap();
+ for (Note n : notes) {
+ if (base == null || !base.contains(n)) {
+ newlyCreated.set(n, n.getData());
+ }
+ }
+ return newlyCreated;
+ }
+
+ private void commitNotes(NoteMap notes, String notesBranch,
+ PersonIdent commitAuthor, String commitMessage) throws IOException,
+ ConcurrentRefUpdateException {
+ try {
+ revWalk = new RevWalk(db);
+ inserter = db.newObjectInserter();
+ reader = db.newObjectReader();
+ loadBase(notesBranch);
+ if (overwrite) {
+ addAllNotes(notes);
+ } else {
+ addNewNotes(notes);
+ }
+ if (base != null) {
+ oursCommit = createCommit(ours, commitAuthor, commitMessage, baseCommit);
+ } else {
+ oursCommit = createCommit(ours, commitAuthor, commitMessage);
+ }
+ updateRef(notesBranch);
+ } finally {
+ revWalk.release();
+ inserter.release();
+ reader.release();
+ }
+ }
+
+ private void addNewNotes(NoteMap notes) throws IOException {
+ for (Note n : notes) {
+ if (! ours.contains(n)) {
+ ours.set(n, n.getData());
+ }
+ }
+ }
+
+ private void addAllNotes(NoteMap notes) throws IOException {
+ for (Note n : notes) {
+ if (ours.contains(n)) {
+ // Merge the existing and the new note as if they are both new,
+ // means: base == null
+ // There is no really a common ancestry for these two note revisions
+ ObjectId noteContent = getNoteMerger().merge(null, n, ours.getNote(n),
+ reader, inserter).getData();
+ ours.set(n, noteContent);
+ } else {
+ ours.set(n, n.getData());
+ }
+ }
+ }
+
+ private NoteMerger getNoteMerger() {
+ if (noteMerger == null) {
+ noteMerger = new ReviewNoteMerger();
+ }
+ return noteMerger;
+ }
+
+ private void loadBase(String notesBranch) throws IOException {
+ Ref branch = db.getRef(notesBranch);
+ if (branch != null) {
+ baseCommit = revWalk.parseCommit(branch.getObjectId());
+ base = NoteMap.read(revWalk.getObjectReader(), baseCommit);
+ }
+ if (baseCommit != null) {
+ ours = NoteMap.read(revWalk.getObjectReader(), baseCommit);
+ } else {
+ ours = NoteMap.newEmptyMap();
+ }
+ }
+
+ private RevCommit createCommit(NoteMap map, PersonIdent author,
+ String message, RevCommit... parents) throws IOException {
+ CommitBuilder b = new CommitBuilder();
+ b.setTreeId(map.writeTree(inserter));
+ b.setAuthor(author != null ? author : gerritIdent);
+ b.setCommitter(gerritIdent);
+ if (parents.length > 0) {
+ b.setParentIds(parents);
+ }
+ b.setMessage(message);
+ ObjectId commitId = inserter.insert(b);
+ inserter.flush();
+ return revWalk.parseCommit(commitId);
+ }
+
+ private void updateRef(String notesBranch) throws IOException,
+ MissingObjectException, IncorrectObjectTypeException,
+ CorruptObjectException, ConcurrentRefUpdateException {
+ if (baseCommit != null && oursCommit.getTree().equals(baseCommit.getTree())) {
+ // If the trees are identical, there is no change in the notes.
+ // Avoid saving this commit as it has no new information.
+ return;
+ }
+
+ int remainingLockFailureCalls = MAX_LOCK_FAILURE_CALLS;
+ RefUpdate refUpdate = createRefUpdate(notesBranch, oursCommit, baseCommit);
+
+ for (;;) {
+ Result result = refUpdate.update();
+
+ if (result == Result.LOCK_FAILURE) {
+ if (--remainingLockFailureCalls > 0) {
+ try {
+ Thread.sleep(SLEEP_ON_LOCK_FAILURE_MS);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ } else {
+ throw new ConcurrentRefUpdateException("Failed to lock the ref: "
+ + notesBranch, db.getRef(notesBranch), result);
+ }
+
+ } else if (result == Result.REJECTED) {
+ RevCommit theirsCommit =
+ revWalk.parseCommit(refUpdate.getOldObjectId());
+ NoteMap theirs =
+ NoteMap.read(revWalk.getObjectReader(), theirsCommit);
+ NoteMapMerger merger =
+ new NoteMapMerger(db, getNoteMerger(), MergeStrategy.RESOLVE);
+ NoteMap merged = merger.merge(base, ours, theirs);
+ RevCommit mergeCommit =
+ createCommit(merged, gerritIdent, "Merged note commits\n",
+ theirsCommit, oursCommit);
+ refUpdate = createRefUpdate(notesBranch, mergeCommit, theirsCommit);
+ remainingLockFailureCalls = MAX_LOCK_FAILURE_CALLS;
+
+ } else if (result == Result.IO_FAILURE) {
+ throw new IOException("Couldn't update " + notesBranch + ". "
+ + result.name());
+ } else {
+ break;
+ }
+ }
+ }
+
+ private RefUpdate createRefUpdate(String notesBranch, ObjectId newObjectId,
+ ObjectId expectedOldObjectId) throws IOException {
+ RefUpdate refUpdate = db.updateRef(notesBranch);
+ refUpdate.setNewObjectId(newObjectId);
+ if (expectedOldObjectId == null) {
+ refUpdate.setExpectedOldObjectId(ObjectId.zeroId());
+ } else {
+ refUpdate.setExpectedOldObjectId(expectedOldObjectId);
+ }
+ return refUpdate;
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/ListPlugins.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/ListPlugins.java
index dca47e0..b87af89 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/ListPlugins.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/ListPlugins.java
@@ -33,13 +33,16 @@
import java.util.List;
import java.util.Map;
-/** List projects visible to the calling user. */
+/** List the installed plugins. */
public class ListPlugins {
private final PluginLoader pluginLoader;
@Option(name = "--format", metaVar = "FMT", usage = "Output display format")
private OutputFormat format = OutputFormat.TEXT;
+ @Option(name = "--all", aliases = {"-a"}, usage = "List all plugins, including disabled plugins")
+ private boolean all;
+
@Inject
protected ListPlugins(PluginLoader pluginLoader) {
this.pluginLoader = pluginLoader;
@@ -67,7 +70,7 @@
Map<String, PluginInfo> output = Maps.newTreeMap();
- List<Plugin> plugins = Lists.newArrayList(pluginLoader.getPlugins());
+ List<Plugin> plugins = Lists.newArrayList(pluginLoader.getPlugins(all));
Collections.sort(plugins, new Comparator<Plugin>() {
@Override
public int compare(Plugin a, Plugin b) {
@@ -76,20 +79,22 @@
});
if (!format.isJson()) {
- stdout.format("%-30s %-10s\n", "Name", "Version");
+ stdout.format("%-30s %-10s %-8s\n", "Name", "Version", "Status");
stdout
- .print("----------------------------------------------------------------------\n");
+ .print("-------------------------------------------------------------------------------\n");
}
for (Plugin p : plugins) {
PluginInfo info = new PluginInfo();
info.version = p.getVersion();
+ info.disabled = p.isDisabled() ? true : null;
if (format.isJson()) {
output.put(p.getName(), info);
} else {
- stdout.format("%-30s %-10s\n", p.getName(),
- Strings.nullToEmpty(info.version));
+ stdout.format("%-30s %-10s %-8s\n", p.getName(),
+ Strings.nullToEmpty(info.version),
+ p.isDisabled() ? "DISABLED" : "");
}
}
@@ -103,5 +108,9 @@
private static class PluginInfo {
String version;
+ // disabled is only read via reflection when building the json output. We
+ // do not want to show a compiler error that it isn't used.
+ @SuppressWarnings("unused")
+ Boolean disabled;
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/Plugin.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/Plugin.java
index a3c363b..91ffbba 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/Plugin.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/Plugin.java
@@ -89,6 +89,7 @@
private final File dataDir;
private final ApiType apiType;
private final ClassLoader classLoader;
+ private final boolean disabled;
private Class<? extends Module> sysModule;
private Class<? extends Module> sshModule;
private Class<? extends Module> httpModule;
@@ -119,6 +120,7 @@
this.dataDir = dataDir;
this.apiType = apiType;
this.classLoader = classLoader;
+ this.disabled = srcJar.getName().endsWith(".disabled");
this.sysModule = sysModule;
this.sshModule = sshModule;
this.httpModule = httpModule;
@@ -165,6 +167,10 @@
return snapshot.lastModified() != jar.lastModified();
}
+ public boolean isDisabled() {
+ return disabled;
+ }
+
public void start(PluginGuiceEnvironment env) throws Exception {
Injector root = newRootInjector(env);
manager = new LifecycleManager();
@@ -294,13 +300,15 @@
}
public void add(RegistrationHandle handle) {
- if (handle instanceof ReloadableRegistrationHandle) {
- if (reloadableHandles == null) {
- reloadableHandles = Lists.newArrayList();
+ if (manager != null) {
+ if (handle instanceof ReloadableRegistrationHandle) {
+ if (reloadableHandles == null) {
+ reloadableHandles = Lists.newArrayList();
+ }
+ reloadableHandles.add((ReloadableRegistrationHandle<?>) handle);
}
- reloadableHandles.add((ReloadableRegistrationHandle<?>) handle);
+ manager.add(handle);
}
- manager.add(handle);
}
List<ReloadableRegistrationHandle<?>> getReloadableHandles() {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java
index 67d715f..76cee02 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java
@@ -45,6 +45,7 @@
import java.net.URL;
import java.net.URLClassLoader;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
@@ -67,6 +68,7 @@
private final PluginGuiceEnvironment env;
private final ServerInformationImpl srvInfoImpl;
private final ConcurrentMap<String, Plugin> running;
+ private final ConcurrentMap<String, Plugin> disabled;
private final Map<String, FileSnapshot> broken;
private final ReferenceQueue<ClassLoader> cleanupQueue;
private final ConcurrentMap<CleanupHandle, Boolean> cleanupHandles;
@@ -85,6 +87,7 @@
env = pe;
srvInfoImpl = sii;
running = Maps.newConcurrentMap();
+ disabled = Maps.newConcurrentMap();
broken = Maps.newHashMap();
cleanupQueue = new ReferenceQueue<ClassLoader>();
cleanupHandles = Maps.newConcurrentMap();
@@ -100,8 +103,14 @@
}
}
- public Iterable<Plugin> getPlugins() {
- return running.values();
+ public Iterable<Plugin> getPlugins(boolean all) {
+ if (!all) {
+ return running.values();
+ } else {
+ ArrayList<Plugin> plugins = new ArrayList<Plugin>(running.values());
+ plugins.addAll(disabled.values());
+ return plugins;
+ }
}
public void installPluginFromStream(String name, InputStream in)
@@ -178,6 +187,15 @@
active.stop();
running.remove(name);
+ try {
+ FileSnapshot snapshot = FileSnapshot.save(off);
+ Plugin offPlugin = loadPlugin(name, off, snapshot);
+ disabled.put(name, offPlugin);
+ } catch (Throwable e) {
+ // This shouldn't happen, as the plugin was loaded earlier.
+ log.warn(String.format("Cannot load disabled plugin %s", name),
+ e.getCause());
+ }
}
cleanInBackground();
}
@@ -205,6 +223,7 @@
p.stop();
}
running.clear();
+ disabled.clear();
broken.clear();
if (cleanupHandles.size() > running.size()) {
System.gc();
@@ -250,6 +269,7 @@
public synchronized void rescan() {
List<File> jars = scanJarsInPluginsDirectory();
stopRemovedPlugins(jars);
+ dropRemovedDisabledPlugins(jars);
for (File jar : jars) {
String name = nameOf(jar);
@@ -292,14 +312,20 @@
oldPlugin.stop();
running.remove(name);
}
- newPlugin.start(env);
+ if (!newPlugin.isDisabled()) {
+ newPlugin.start(env);
+ }
if (reload) {
env.onReloadPlugin(oldPlugin, newPlugin);
oldPlugin.stop();
- } else {
+ } else if (!newPlugin.isDisabled()) {
env.onStartPlugin(newPlugin);
}
- running.put(name, newPlugin);
+ if (!newPlugin.isDisabled()) {
+ running.put(name, newPlugin);
+ } else {
+ disabled.put(name, newPlugin);
+ }
broken.remove(name);
} catch (Throwable err) {
broken.put(name, snapshot);
@@ -310,7 +336,9 @@
private void stopRemovedPlugins(List<File> jars) {
Set<String> unload = Sets.newHashSet(running.keySet());
for (File jar : jars) {
- unload.remove(nameOf(jar));
+ if (!jar.getName().endsWith(".disabled")) {
+ unload.remove(nameOf(jar));
+ }
}
for (String name : unload){
log.info(String.format("Unloading plugin %s", name));
@@ -318,6 +346,18 @@
}
}
+ private void dropRemovedDisabledPlugins(List<File> jars) {
+ Set<String> unload = Sets.newHashSet(disabled.keySet());
+ for (File jar : jars) {
+ if (jar.getName().endsWith(".disabled")) {
+ unload.remove(nameOf(jar));
+ }
+ }
+ for (String name : unload) {
+ disabled.remove(name);
+ }
+ }
+
synchronized int processPendingCleanups() {
CleanupHandle h;
while ((h = (CleanupHandle) cleanupQueue.poll()) != null) {
@@ -336,6 +376,9 @@
private static String nameOf(File jar) {
String name = jar.getName();
+ if (name.endsWith(".disabled")) {
+ name = name.substring(0, name.lastIndexOf('.'));
+ }
int ext = name.lastIndexOf('.');
return 0 < ext ? name.substring(0, ext) : name;
}
@@ -430,7 +473,9 @@
File[] matches = pluginsDir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
- return pathname.getName().endsWith(".jar") && pathname.isFile();
+ String n = pathname.getName();
+ return (n.endsWith(".jar") || n.endsWith(".jar.disabled"))
+ && pathname.isFile();
}
});
if (matches == null) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
index 7387fd1..41f2aa6 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
@@ -211,7 +211,8 @@
/** Can this user restore this change? */
public boolean canRestore() {
- return canAbandon(); // Anyone who can abandon the change can restore it back
+ return canAbandon() // Anyone who can abandon the change can restore it back
+ && getRefControl().canUpload(); // as long as you can upload too
}
/** All value ranges of any allowed label permission. */
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ListProjects.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListProjects.java
index 8b4e000..e5a11ca 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ListProjects.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListProjects.java
@@ -40,8 +40,10 @@
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
@@ -57,6 +59,12 @@
return !PERMISSIONS.matches(git);
}
},
+ PARENT_CANDIDATES {
+ @Override
+ boolean matches(Repository git) {
+ return true;
+ }
+ },
PERMISSIONS {
@Override
boolean matches(Repository git) throws IOException {
@@ -155,6 +163,7 @@
int found = 0;
Map<String, ProjectInfo> output = Maps.newTreeMap();
Map<String, String> hiddenNames = Maps.newHashMap();
+ Set<String> rejected = new HashSet<String>();
final TreeMap<Project.NameKey, ProjectNode> treeMap =
new TreeMap<Project.NameKey, ProjectNode>();
@@ -166,84 +175,102 @@
//
continue;
}
-
- final ProjectControl pctl = e.controlFor(currentUser);
- final boolean isVisible = pctl.isVisible() || (all && pctl.isOwner());
- if (showTree && !format.isJson()) {
- treeMap.put(projectName,
- projectNodeFactory.create(pctl.getProject(), isVisible));
- continue;
- }
-
- if (!isVisible && !(showTree && pctl.isOwner())) {
- // Require the project itself to be visible to the user.
- //
- continue;
- }
-
ProjectInfo info = new ProjectInfo();
- info.name = projectName.get();
- if (showTree && format.isJson()) {
- ProjectState parent = e.getParentState();
- if (parent != null) {
- ProjectControl parentCtrl = parent.controlFor(currentUser);
+ if (type == FilterType.PARENT_CANDIDATES) {
+ ProjectState parentState = e.getParentState();
+ if (parentState != null
+ && !output.keySet().contains(parentState.getProject().getName())
+ && !rejected.contains(parentState.getProject().getName())) {
+ ProjectControl parentCtrl = parentState.controlFor(currentUser);
if (parentCtrl.isVisible() || parentCtrl.isOwner()) {
- info.parent = parent.getProject().getName();
+ info.name = parentState.getProject().getName();
+ info.description = parentState.getProject().getDescription();
} else {
- info.parent = hiddenNames.get(parent.getProject().getName());
- if (info.parent == null) {
- info.parent = "?-" + (hiddenNames.size() + 1);
- hiddenNames.put(parent.getProject().getName(), info.parent);
- }
+ rejected.add(parentState.getProject().getName());
+ continue;
}
+ } else {
+ continue;
}
- }
- if (showDescription && !e.getProject().getDescription().isEmpty()) {
- info.description = e.getProject().getDescription();
- }
- try {
- if (showBranch != null) {
- Repository git = repoManager.openRepository(projectName);
- try {
- if (!type.matches(git)) {
- continue;
- }
+ } else {
+ final ProjectControl pctl = e.controlFor(currentUser);
+ final boolean isVisible = pctl.isVisible() || (all && pctl.isOwner());
+ if (showTree && !format.isJson()) {
+ treeMap.put(projectName,
+ projectNodeFactory.create(pctl.getProject(), isVisible));
+ continue;
+ }
- List<Ref> refs = getBranchRefs(projectName, pctl);
- if (!hasValidRef(refs)) {
- continue;
- }
+ if (!isVisible && !(showTree && pctl.isOwner())) {
+ // Require the project itself to be visible to the user.
+ //
+ continue;
+ }
- for (int i = 0; i < showBranch.size(); i++) {
- Ref ref = refs.get(i);
- if (ref != null && ref.getObjectId() != null) {
- if (info.branches == null) {
- info.branches = Maps.newLinkedHashMap();
- }
- info.branches.put(showBranch.get(i), ref.getObjectId().name());
+ info.name = projectName.get();
+ if (showTree && format.isJson()) {
+ ProjectState parent = e.getParentState();
+ if (parent != null) {
+ ProjectControl parentCtrl = parent.controlFor(currentUser);
+ if (parentCtrl.isVisible() || parentCtrl.isOwner()) {
+ info.parent = parent.getProject().getName();
+ } else {
+ info.parent = hiddenNames.get(parent.getProject().getName());
+ if (info.parent == null) {
+ info.parent = "?-" + (hiddenNames.size() + 1);
+ hiddenNames.put(parent.getProject().getName(), info.parent);
}
}
- } finally {
- git.close();
- }
- } else if (!showTree && type != FilterType.ALL) {
- Repository git = repoManager.openRepository(projectName);
- try {
- if (!type.matches(git)) {
- continue;
- }
- } finally {
- git.close();
}
}
+ if (showDescription && !e.getProject().getDescription().isEmpty()) {
+ info.description = e.getProject().getDescription();
+ }
- } catch (RepositoryNotFoundException err) {
- // If the Git repository is gone, the project doesn't actually exist anymore.
- continue;
- } catch (IOException err) {
- log.warn("Unexpected error reading " + projectName, err);
- continue;
+ try {
+ if (showBranch != null) {
+ Repository git = repoManager.openRepository(projectName);
+ try {
+ if (!type.matches(git)) {
+ continue;
+ }
+
+ List<Ref> refs = getBranchRefs(projectName, pctl);
+ if (!hasValidRef(refs)) {
+ continue;
+ }
+
+ for (int i = 0; i < showBranch.size(); i++) {
+ Ref ref = refs.get(i);
+ if (ref != null && ref.getObjectId() != null) {
+ if (info.branches == null) {
+ info.branches = Maps.newLinkedHashMap();
+ }
+ info.branches.put(showBranch.get(i), ref.getObjectId().name());
+ }
+ }
+ } finally {
+ git.close();
+ }
+ } else if (!showTree && type != FilterType.ALL) {
+ Repository git = repoManager.openRepository(projectName);
+ try {
+ if (!type.matches(git)) {
+ continue;
+ }
+ } finally {
+ git.close();
+ }
+ }
+
+ } catch (RepositoryNotFoundException err) {
+ // If the Git repository is gone, the project doesn't actually exist anymore.
+ continue;
+ } catch (IOException err) {
+ log.warn("Unexpected error reading " + projectName, err);
+ continue;
+ }
}
if (limit > 0 && ++found > limit) {
diff --git a/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeSubject.vm b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeSubject.vm
index a67c38c..bb3c127 100644
--- a/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeSubject.vm
+++ b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeSubject.vm
@@ -32,6 +32,6 @@
## subject line for ALL emails related to changes.
##
#macro(elipses $length $str)
-#if($str.length() > $length)${str.substring(0,$length)}...#else$str#end
+#if(($str.length()+3) > $length)${str.substring(0,$length)}...#else$str#end
#end
Change in $projectName.replaceAll('/.*/', '...')[$branch.shortName]: #elipses(60, $change.subject)
diff --git a/gerrit-sshd/.settings/org.eclipse.core.resources.prefs b/gerrit-sshd/.settings/org.eclipse.core.resources.prefs
index 0871ea8..839d647 100644
--- a/gerrit-sshd/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-sshd/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Tue May 15 09:21:12 PDT 2012
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/BanCommitCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/BanCommitCommand.java
index 4350d1e..939d68a 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/BanCommitCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/BanCommitCommand.java
@@ -22,6 +22,7 @@
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;
+import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
import org.eclipse.jgit.lib.ObjectId;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@@ -80,6 +81,8 @@
throw die(e);
} catch (InterruptedException e) {
throw die(e);
+ } catch (ConcurrentRefUpdateException e) {
+ throw die(e);
}
}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/RenameGroupCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/RenameGroupCommand.java
index ad9733d..b9abc92 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/RenameGroupCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/RenameGroupCommand.java
@@ -14,6 +14,7 @@
package com.google.gerrit.sshd.commands;
+import com.google.gerrit.common.errors.InvalidNameException;
import com.google.gerrit.common.errors.NameAlreadyUsedException;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.server.account.PerformRenameGroup;
@@ -39,6 +40,8 @@
performRenameGroupFactory.create().renameGroup(groupName, newGroupName);
} catch (OrmException e) {
throw die(e);
+ } catch (InvalidNameException e) {
+ throw die(e);
} catch (NameAlreadyUsedException e) {
throw die(e);
} catch (NoSuchGroupException e) {
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
index 8ce1e82..5ebb6c7 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
@@ -68,7 +68,8 @@
private final Set<PatchSet.Id> patchSetIds = new HashSet<PatchSet.Id>();
- @Argument(index = 0, required = true, multiValued = true, metaVar = "{COMMIT | CHANGE,PATCHSET}", usage = "patch to review")
+ @Argument(index = 0, required = true, multiValued = true, metaVar = "{COMMIT | CHANGE,PATCHSET}",
+ usage = "list of commits or patch sets to review")
void addPatchSetId(final String token) {
try {
patchSetIds.addAll(parsePatchSetId(token));
@@ -79,29 +80,29 @@
}
}
- @Option(name = "--project", aliases = "-p", usage = "project containing the patch set")
+ @Option(name = "--project", aliases = "-p", usage = "project containing the specified patch set(s)")
private ProjectControl projectControl;
- @Option(name = "--message", aliases = "-m", usage = "cover message to publish on change", metaVar = "MESSAGE")
+ @Option(name = "--message", aliases = "-m", usage = "cover message to publish on change(s)", metaVar = "MESSAGE")
private String changeComment;
- @Option(name = "--abandon", usage = "abandon the patch set")
+ @Option(name = "--abandon", usage = "abandon the specified change(s)")
private boolean abandonChange;
- @Option(name = "--restore", usage = "restore an abandoned the patch set")
+ @Option(name = "--restore", usage = "restore the specified abandoned change(s)")
private boolean restoreChange;
- @Option(name = "--submit", aliases = "-s", usage = "submit the patch set")
+ @Option(name = "--submit", aliases = "-s", usage = "submit the specified patch set(s)")
private boolean submitChange;
@Option(name = "--force-message", usage = "publish the message, "
- + "even if the label score cannot be applied due to change being closed")
+ + "even if the label score cannot be applied due to the change being closed")
private boolean forceMessage = false;
- @Option(name = "--publish", usage = "publish a draft patch set")
+ @Option(name = "--publish", usage = "publish the specified draft patch set(s)")
private boolean publishPatchSet;
- @Option(name = "--delete", usage = "delete a draft patch set")
+ @Option(name = "--delete", usage = "delete the specified draft patch set(s)")
private boolean deleteDraftPatchSet;
@Inject
@@ -266,7 +267,7 @@
errMsg += "rule error";
break;
case NOT_A_DRAFT:
- errMsg += "change is not a draft";
+ errMsg += "change/patch set is not a draft";
break;
case GIT_ERROR:
errMsg += "error writing change to git repository";
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/StreamEvents.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/StreamEvents.java
old mode 100755
new mode 100644
diff --git a/gerrit-util-cli/.settings/org.eclipse.core.resources.prefs b/gerrit-util-cli/.settings/org.eclipse.core.resources.prefs
index c780f44..e9441bb 100644
--- a/gerrit-util-cli/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-util-cli/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:36 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding/<project>=UTF-8
diff --git a/gerrit-util-ssl/.settings/org.eclipse.core.resources.prefs b/gerrit-util-ssl/.settings/org.eclipse.core.resources.prefs
index 589908f..e9441bb 100644
--- a/gerrit-util-ssl/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-util-ssl/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:35 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding/<project>=UTF-8
diff --git a/gerrit-war/.settings/org.eclipse.core.resources.prefs b/gerrit-war/.settings/org.eclipse.core.resources.prefs
index d404b00..abdea9ac 100644
--- a/gerrit-war/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-war/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,3 @@
-#Thu Jul 28 11:02:37 PDT 2011
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
diff --git a/pom.xml b/pom.xml
index e5f6fc5..d7b5988 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,12 +88,26 @@
<module>gerrit-war</module>
<module>gerrit-extension-api</module>
- <module>gerrit-plugin-api</module>
- <module>gerrit-plugin-archetype</module>
<module>gerrit-gwtui</module>
</modules>
+ <profiles>
+ <profile>
+ <id>all</id>
+ <modules>
+ <module>gerrit-plugin-api</module>
+ <module>gerrit-plugin-archetype</module>
+ </modules>
+ </profile>
+ <profile>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <id>no-plugins</id>
+ </profile>
+ </profiles>
+
<licenses>
<license>
<name>Apache License, 2.0</name>
@@ -464,7 +478,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
- <version>12.0</version>
+ <version>12.0.1</version>
</dependency>
<dependency>
diff --git a/tools/release.sh b/tools/release.sh
index 4a872a1..79e6605 100755
--- a/tools/release.sh
+++ b/tools/release.sh
@@ -25,7 +25,7 @@
fi
./tools/version.sh --release &&
-mvn clean package $include_docs
+mvn clean package $include_docs -P all
rc=$?
./tools/version.sh --reset