Merge branch 'stable-2.9' into stable-2.10

* stable-2.9:
  Release notes for Gerrit 2.9.1
  Set version to 2.9.1
  Display parents for all changes, not only merge commits
  Fix JS plugin load when using non-root Gerrit URLs
  Don't require secondary index when running daemon in slave mode
  Remove fixed limit of results returned by secondary index query

Conflicts:
	VERSION
	gerrit-extension-api/pom.xml
	gerrit-gwtui/src/main/java/com/google/gerrit/client/change/CommitBox.java
	gerrit-plugin-api/pom.xml
	gerrit-plugin-archetype/pom.xml
	gerrit-plugin-gwt-archetype/pom.xml
	gerrit-plugin-gwtui/pom.xml
	gerrit-plugin-js-archetype/pom.xml
	gerrit-war/pom.xml

Change-Id: Id7a49d3792510653da4312e240924d47e8b52724
This commit is contained in:
David Pursehouse 2014-09-09 18:39:01 +02:00
commit 5afd5b8f00
14 changed files with 218 additions and 28 deletions

View File

@ -98,7 +98,7 @@ It displays the author and the committer as links to a list of this
person's changes that have the same status as the currently viewed person's changes that have the same status as the currently viewed
change. change.
The commit ID and the link:user-changeid.html[Change-Id] are both The commit ID, the parent commit(s) and the link:user-changeid.html[Change-Id] are
displayed with a copy-to-clipboard icon that allows the ID to be copied displayed with a copy-to-clipboard icon that allows the ID to be copied
into the clipboard. into the clipboard.
@ -107,8 +107,7 @@ is also a link to the commit in the Git web browser.
image::images/user-review-ui-change-screen-commit-info.png[width=800, link="images/user-review-ui-change-screen-commit-info.png"] image::images/user-review-ui-change-screen-commit-info.png[width=800, link="images/user-review-ui-change-screen-commit-info.png"]
If a merge commit is viewed this is highlighted by an icon. In this If a merge commit is viewed this is highlighted by an icon.
case the parent commits are also shown.
image::images/user-review-ui-change-screen-commit-info-merge-commit.png[width=800, link="images/user-review-ui-change-screen-commit-info-merge-commit.png"] image::images/user-review-ui-change-screen-commit-info-merge-commit.png[width=800, link="images/user-review-ui-change-screen-commit-info-merge-commit.png"]

View File

@ -0,0 +1,99 @@
Release notes for Gerrit 2.9.1
==============================
There are no schema changes from link:ReleaseNotes-2.9.html[2.9].
Download:
link:https://gerrit-releases.storage.googleapis.com/gerrit-2.9.1.war[
https://gerrit-releases.storage.googleapis.com/gerrit-2.9.1.war]
Bug Fixes
---------
* link:https://code.google.com/p/gerrit/issues/detail?id=2801[Issue 2801]:
Set default for review SSH command to `notify=ALL`.
+
In 2.9 the default was incorrectly set to `notify=NONE`, which prevented
mail notifications from being sent for review comments that were added by
build jobs based on the Gerrit Trigger plugin.
* link:https://code.google.com/p/gerrit/issues/detail?id=2879[Issue 2879]:
Remove fixed limit of results returned by secondary index query.
+
The limit was hard-coded to 1000 results, which overrode the value set in
the global query limit capability.
* Don't require secondary index when running server in daemon mode.
+
The server failed to start if a secondary index was not present when starting
the daemon in slave mode.
+
Now the daemon can be started in slave mode without requiring the index
to be present.
+
The reindex program and the ssh query command are no longer available on
a server that is running in slave mode.
* Add full names for options on list groups REST API.
* Add full names for options on list projects REST API.
* link:https://code.google.com/p/gerrit/issues/detail?id=2878[Issue 2878]:
Make `-S` an alias of `--start` in changes query REST API.
* Run change hooks and ref-updated events after indexing is done.
+
The change hooks and ref-updated events were run parallel to the change
(re)indexing. This meant that the event-stream sent events to the clients
before the change indexing was finished.
* link:https://code.google.com/p/gerrit/issues/detail?id=2877[Issue 2877]:
Fix NullPointerException when ReviewInput's message is empty.
* link:https://code.google.com/p/gerrit/issues/detail?id=2500[Issue 2500],
link:https://code.google.com/p/gerrit/issues/detail?id=1748[Issue 1748]:
Fix replication of tags.
* Fix NullPointerException in `/projects/{name}/children?recursive` when a
project has a parent project that is does not exist.
* Fix NullPointerException when submitting review with inline comments via REST.
* Improve error logging in MergeabilityChecker.
* Gracefully skip mergeability checking on broken changes.
* link:https://code.google.com/p/gerrit/issues/detail?id=2861[Issue 2861]:
Replace "line" with "end_line" when range is given in inline comment.
+
Also update the documentation with an example of a range comment.
* Fix mutual exclusivity of --delete and --submit review command options.
* link:https://code.google.com/p/gerrit/issues/detail?id=2848[Issue 2848]:
Add support for CSharp syntax highlighting.
* link:https://code.google.com/p/gerrit/issues/detail?id=2831[Issue 2831]:
Add missing call to ref-updated hook for submodule updates.
* link:https://code.google.com/p/gerrit/issues/detail?id=2773[Issue 2773]
Fix stale dates in committer field.
* Prevent NullPointerException when trying to add an account that doesn't
exist as a reviewer.
* Fix potential NullPointerException in cherry-pick submit strategy.
* Add `--start` option to skip changes in ssh `query` command.
* Fix loading of javascript plugins when using non-root Gerrit URLs.
+
When Gerrit is not on the root URL path the javascript plugins failed to
load because of the exact matching required on the request URL.
* link:https://code.google.com/p/gerrit/issues/detail?id=2279[Issue 2279]:
Display parents for all changes, not only merge commits.
+
In the new change screen the parent commit is now also shown for regular
commits, as well as merge commits. This makes it consistent with the old
change screen.

View File

@ -5,6 +5,7 @@ Gerrit Code Review - Release Notes
Version 2.9.x Version 2.9.x
------------- -------------
* link:ReleaseNotes-2.9.html[2.9] * link:ReleaseNotes-2.9.html[2.9]
* link:ReleaseNotes-2.9.1.html[2.9.1]
[[2_8]] [[2_8]]
Version 2.8.x Version 2.8.x

View File

@ -70,6 +70,9 @@ public class GlobalCapability {
/** Maximum result limit per executed query. */ /** Maximum result limit per executed query. */
public static final String QUERY_LIMIT = "queryLimit"; public static final String QUERY_LIMIT = "queryLimit";
/** Default result limit per executed query. */
public static final int DEFAULT_MAX_QUERY_LIMIT = 500;
/** Ability to impersonate another user. */ /** Ability to impersonate another user. */
public static final String RUN_AS = "runAs"; public static final String RUN_AS = "runAs";
@ -145,7 +148,7 @@ public class GlobalCapability {
return new PermissionRange.WithDefaults( return new PermissionRange.WithDefaults(
varName, varName,
0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE,
0, 500); 0, DEFAULT_MAX_QUERY_LIMIT);
} }
return null; return null;
} }

View File

@ -121,8 +121,8 @@ class CommitBox extends Composite {
if (revInfo.commit().parents().length() > 1) { if (revInfo.commit().parents().length() > 1) {
mergeCommit.setVisible(true); mergeCommit.setVisible(true);
setParents(change.project(), revInfo.commit().parents());
} }
setParents(change.project(), revInfo.commit().parents());
} }
private void setWebLinks(ChangeInfo change, String revision, private void setWebLinks(ChangeInfo change, String revision,

View File

@ -155,7 +155,7 @@ limitations under the License.
<td ui:field='webLinkCell' class='{style.webLinkCell}'></td> <td ui:field='webLinkCell' class='{style.webLinkCell}'></td>
</tr> </tr>
<tr ui:field='parents' style='display: none'> <tr ui:field='parents' style='display: none'>
<th><ui:msg>Parents</ui:msg></th> <th><ui:msg>Parent(s)</ui:msg></th>
<td> <td>
<g:FlowPanel ui:field='parentCommits'/> <g:FlowPanel ui:field='parentCommits'/>
</td> </td>

View File

@ -608,7 +608,8 @@ class HttpPluginServlet extends HttpServlet
private void sendJsPlugin(Plugin plugin, ResourceKey key, private void sendJsPlugin(Plugin plugin, ResourceKey key,
HttpServletRequest req, HttpServletResponse res) throws IOException { HttpServletRequest req, HttpServletResponse res) throws IOException {
File pluginFile = plugin.getSrcFile(); File pluginFile = plugin.getSrcFile();
if (req.getRequestURI().equals(getJsPluginPath(plugin)) && pluginFile.exists()) { if (req.getRequestURI().endsWith(getJsPluginPath(plugin))
&& pluginFile.exists()) {
res.setHeader("Content-Length", Long.toString(pluginFile.length())); res.setHeader("Content-Length", Long.toString(pluginFile.length()));
res.setContentType("application/javascript"); res.setContentType("application/javascript");
writeToResponse(res, new FileInputStream(pluginFile)); writeToResponse(res, new FileInputStream(pluginFile));

View File

@ -57,6 +57,7 @@ import com.google.gerrit.server.contact.HttpContactStoreConnection;
import com.google.gerrit.server.git.GarbageCollectionRunner; import com.google.gerrit.server.git.GarbageCollectionRunner;
import com.google.gerrit.server.git.ReceiveCommitsExecutorModule; import com.google.gerrit.server.git.ReceiveCommitsExecutorModule;
import com.google.gerrit.server.git.WorkQueue; import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.index.DummyIndexModule;
import com.google.gerrit.server.index.IndexModule; import com.google.gerrit.server.index.IndexModule;
import com.google.gerrit.server.index.IndexModule.IndexType; import com.google.gerrit.server.index.IndexModule.IndexType;
import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier; import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier;
@ -361,6 +362,9 @@ public class Daemon extends SiteProgram {
} }
private AbstractModule createIndexModule() { private AbstractModule createIndexModule() {
if (slave) {
return new DummyIndexModule();
}
IndexType indexType = IndexModule.getIndexType(cfgInjector); IndexType indexType = IndexModule.getIndexType(cfgInjector);
switch (indexType) { switch (indexType) {
case LUCENE: case LUCENE:

View File

@ -21,6 +21,7 @@ import com.google.common.cache.Cache;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.gerrit.common.ChangeHooks; import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.common.Die;
import com.google.gerrit.common.DisabledChangeHooks; import com.google.gerrit.common.DisabledChangeHooks;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener; import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.events.LifecycleListener; import com.google.gerrit.extensions.events.LifecycleListener;
@ -126,6 +127,7 @@ public class Reindex extends SiteProgram {
private boolean dryRun; private boolean dryRun;
private Injector dbInjector; private Injector dbInjector;
private Config cfg;
private Injector sysInjector; private Injector sysInjector;
private ChangeIndex index; private ChangeIndex index;
@ -133,6 +135,9 @@ public class Reindex extends SiteProgram {
public int run() throws Exception { public int run() throws Exception {
mustHaveValidSite(); mustHaveValidSite();
dbInjector = createDbInjector(MULTI_USER); dbInjector = createDbInjector(MULTI_USER);
cfg = dbInjector.getInstance(
Key.get(Config.class, GerritServerConfig.class));
checkNotSlaveMode();
limitThreads(); limitThreads();
disableLuceneAutomaticCommit(); disableLuceneAutomaticCommit();
if (version == null) { if (version == null) {
@ -162,9 +167,13 @@ public class Reindex extends SiteProgram {
return result; return result;
} }
private void checkNotSlaveMode() throws Die {
if (cfg.getBoolean("container", "slave", false)) {
throw die("Cannot run reindex in slave mode");
}
}
private void limitThreads() { private void limitThreads() {
Config cfg =
dbInjector.getInstance(Key.get(Config.class, GerritServerConfig.class));
boolean usePool = cfg.getBoolean("database", "connectionpool", boolean usePool = cfg.getBoolean("database", "connectionpool",
dbInjector.getInstance(DataSourceType.class).usePool()); dbInjector.getInstance(DataSourceType.class).usePool());
int poolLimit = cfg.getInt("database", "poollimit", int poolLimit = cfg.getInt("database", "poollimit",

View File

@ -0,0 +1,60 @@
// Copyright (C) 2014 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.index;
import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeDataSource;
import java.io.IOException;
public class DummyIndex implements ChangeIndex {
@Override
public Schema<ChangeData> getSchema() {
throw new UnsupportedOperationException();
}
@Override
public void close() {
}
@Override
public void insert(ChangeData cd) throws IOException {
}
@Override
public void replace(ChangeData cd) throws IOException {
}
@Override
public void delete(ChangeData cd) throws IOException {
}
@Override
public void deleteAll() throws IOException {
}
@Override
public ChangeDataSource getSource(Predicate<ChangeData> p, int start,
int limit) throws QueryParseException {
throw new UnsupportedOperationException();
}
@Override
public void markReady(boolean ready) throws IOException {
}
}

View File

@ -0,0 +1,26 @@
// Copyright (C) 2014 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.index;
import com.google.inject.AbstractModule;
public class DummyIndexModule extends AbstractModule {
@Override
protected void configure() {
install(new IndexModule(1));
bind(ChangeIndex.class).toInstance(new DummyIndex());
}
}

View File

@ -14,7 +14,8 @@
package com.google.gerrit.server.index; package com.google.gerrit.server.index;
import com.google.common.annotations.VisibleForTesting; import static com.google.gerrit.common.data.GlobalCapability.DEFAULT_MAX_QUERY_LIMIT;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
@ -61,9 +62,6 @@ public class IndexRewriteImpl implements ChangeQueryRewriter {
CLOSED_STATUSES = Sets.immutableEnumSet(closed); CLOSED_STATUSES = Sets.immutableEnumSet(closed);
} }
@VisibleForTesting
static final int MAX_LIMIT = 1000;
/** /**
* Get the set of statuses that changes matching the given predicate may have. * Get the set of statuses that changes matching the given predicate may have.
* *
@ -135,13 +133,12 @@ public class IndexRewriteImpl implements ChangeQueryRewriter {
throws QueryParseException { throws QueryParseException {
ChangeIndex index = indexes.getSearchIndex(); ChangeIndex index = indexes.getSearchIndex();
in = basicRewrites.rewrite(in); in = basicRewrites.rewrite(in);
int limit = int limit = Objects.firstNonNull(
Objects.firstNonNull(ChangeQueryBuilder.getLimit(in), MAX_LIMIT); ChangeQueryBuilder.getLimit(in), DEFAULT_MAX_QUERY_LIMIT);
// Increase the limit rather than skipping, since we don't know how many // Increase the limit rather than skipping, since we don't know how many
// skipped results would have been filtered out by the enclosing AndSource. // skipped results would have been filtered out by the enclosing AndSource.
limit += start; limit += start;
limit = Math.max(limit, 1); limit = Math.max(limit, 1);
limit = Math.min(limit, MAX_LIMIT);
Predicate<ChangeData> out = rewriteImpl(in, index, limit); Predicate<ChangeData> out = rewriteImpl(in, index, limit);
if (in == out || out instanceof IndexPredicate) { if (in == out || out instanceof IndexPredicate) {

View File

@ -14,6 +14,7 @@
package com.google.gerrit.server.index; package com.google.gerrit.server.index;
import static com.google.gerrit.common.data.GlobalCapability.DEFAULT_MAX_QUERY_LIMIT;
import static com.google.gerrit.reviewdb.client.Change.Status.ABANDONED; import static com.google.gerrit.reviewdb.client.Change.Status.ABANDONED;
import static com.google.gerrit.reviewdb.client.Change.Status.DRAFT; import static com.google.gerrit.reviewdb.client.Change.Status.DRAFT;
import static com.google.gerrit.reviewdb.client.Change.Status.MERGED; import static com.google.gerrit.reviewdb.client.Change.Status.MERGED;
@ -179,13 +180,6 @@ public class IndexRewriteTest {
assertEquals(and(query(f, 5), l), rewrite.rewrite(in, 2)); assertEquals(and(query(f, 5), l), rewrite.rewrite(in, 2));
} }
@Test
public void testStartDoesNotExceedMaxLimit() throws Exception {
Predicate<ChangeData> in = parse("file:a");
assertEquals(query(in), rewrite.rewrite(in, 0));
assertEquals(query(in), rewrite.rewrite(in, 1));
}
@Test @Test
public void testGetPossibleStatus() throws Exception { public void testGetPossibleStatus() throws Exception {
assertEquals(EnumSet.allOf(Change.Status.class), status("file:a")); assertEquals(EnumSet.allOf(Change.Status.class), status("file:a"));
@ -233,7 +227,7 @@ public class IndexRewriteTest {
private IndexedChangeQuery query(Predicate<ChangeData> p) private IndexedChangeQuery query(Predicate<ChangeData> p)
throws QueryParseException { throws QueryParseException {
return query(p, IndexRewriteImpl.MAX_LIMIT); return query(p, DEFAULT_MAX_QUERY_LIMIT);
} }
private IndexedChangeQuery query(Predicate<ChangeData> p, int limit) private IndexedChangeQuery query(Predicate<ChangeData> p, int limit)

View File

@ -14,8 +14,6 @@
package com.google.gerrit.sshd.commands; package com.google.gerrit.sshd.commands;
import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
import com.google.gerrit.server.query.change.QueryProcessor; import com.google.gerrit.server.query.change.QueryProcessor;
import com.google.gerrit.sshd.CommandMetaData; import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand; import com.google.gerrit.sshd.SshCommand;
@ -26,8 +24,7 @@ import org.kohsuke.args4j.Option;
import java.util.List; import java.util.List;
@CommandMetaData(name = "query", description = "Query the change database", @CommandMetaData(name = "query", description = "Query the change database")
runsAt = MASTER_OR_SLAVE)
class Query extends SshCommand { class Query extends SshCommand {
@Inject @Inject
private QueryProcessor processor; private QueryProcessor processor;