Merge changes from topic 'bundle-diff-fixes'
* changes:
ChangeBundle: Ignore ReviewDb current PSID if invalid
ChangeBundle: Be more lenient about reviewers
ChangeBundle: Handle change subjects extracted with a buggy JGit
ChangeBundle: Fix ChangeMessage comparison for extra patch sets
ChangeBundle: Handle leading whitespace in ReviewDb topics
ChangeBundle: Fix NPE when change has no current patch set
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
index 0123724..771e323 100644
--- a/Documentation/access-control.txt
+++ b/Documentation/access-control.txt
@@ -204,8 +204,8 @@
Permissions can be set on a single reference name to match one
branch (e.g. `refs/heads/master`), or on a reference namespace
(e.g. `+refs/heads/*+`) to match any branch starting with that
-prefix. So a permission with `+refs/heads/*+` will match
-`refs/heads/master` and `refs/heads/experimental`, etc.
+prefix. So a permission with `+refs/heads/*+` will match all of
+`refs/heads/master`, `refs/heads/experimental`, `refs/heads/release/1.0` etc.
Reference names can also be described with a regular expression
by prefixing the reference name with `^`. For example
diff --git a/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/RestSession.java b/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/RestSession.java
index 4c8ba42..9c59e10 100644
--- a/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/RestSession.java
+++ b/gerrit-acceptance-framework/src/test/java/com/google/gerrit/acceptance/RestSession.java
@@ -54,6 +54,10 @@
return execute(get);
}
+ public RestResponse head(String endPoint) throws IOException {
+ return execute(Request.Head(url + "/a" + endPoint));
+ }
+
public RestResponse put(String endPoint) throws IOException {
return put(endPoint, null);
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountGroupSuggestOracle.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountGroupSuggestOracle.java
index aa76128..a96624a 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountGroupSuggestOracle.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountGroupSuggestOracle.java
@@ -35,7 +35,9 @@
@Override
public void _onRequestSuggestions(final Request req, final Callback callback) {
GroupMap.suggestAccountGroupForProject(
- projectName.get(), req.getQuery(), req.getLimit(),
+ projectName == null ? null : projectName.get(),
+ req.getQuery(),
+ req.getLimit(),
new GerritCallback<GroupMap>() {
@Override
public void onSuccess(GroupMap result) {
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Change.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Change.java
index 20f9b82..1864c56 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Change.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Change.java
@@ -280,6 +280,9 @@
/** ID number of the first patch set in a change. */
public static final int INITIAL_PATCH_SET_ID = 1;
+ /** Change-Id pattern. */
+ public static final String CHANGE_ID_PATTERN = "^[iI][0-9a-f]{4,}.*$";
+
/**
* Current state within the basic workflow of the change.
*
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java
index 5e84fd3..74411ad 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java
@@ -14,6 +14,7 @@
package com.google.gerrit.server.git.validators;
+import static com.google.gerrit.reviewdb.client.Change.CHANGE_ID_PATTERN;
import static com.google.gerrit.reviewdb.client.RefNames.REFS_CHANGES;
import static com.google.gerrit.reviewdb.client.RefNames.REFS_CONFIG;
import static org.eclipse.jgit.lib.Constants.R_HEADS;
@@ -61,6 +62,7 @@
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.regex.Pattern;
public class CommitValidators {
private static final Logger log = LoggerFactory
@@ -182,6 +184,27 @@
}
public static class ChangeIdValidator implements CommitValidationListener {
+ private static final int SHA1_LENGTH = 7;
+ private static final String CHANGE_ID_PREFIX =
+ FooterConstants.CHANGE_ID.getName() + ":";
+ private static final String MISSING_CHANGE_ID_MSG =
+ "[%s] missing "
+ + FooterConstants.CHANGE_ID.getName()
+ + " in commit message footer";
+ private static final String MISSING_SUBJECT_MSG =
+ "[%s] missing subject; "
+ + FooterConstants.CHANGE_ID.getName()
+ + " must be in commit message footer";
+ private static final String MULTIPLE_CHANGE_ID_MSG =
+ "[%s] multiple "
+ + FooterConstants.CHANGE_ID.getName()
+ + " lines in commit message footer";
+ private static final String INVALID_CHANGE_ID_MSG =
+ "[%s] invalid "
+ + FooterConstants.CHANGE_ID.getName() +
+ " line format in commit message footer";
+ private static final Pattern CHANGE_ID = Pattern.compile(CHANGE_ID_PATTERN);
+
private final ProjectControl projectControl;
private final String canonicalWebUrl;
private final String installCommitMsgHookCommand;
@@ -200,63 +223,62 @@
@Override
public List<CommitValidationMessage> onCommitReceived(
CommitReceivedEvent receiveEvent) throws CommitValidationException {
- final List<String> idList = receiveEvent.commit.getFooterLines(
- FooterConstants.CHANGE_ID);
-
+ RevCommit commit = receiveEvent.commit;
List<CommitValidationMessage> messages = new LinkedList<>();
+ List<String> idList = commit.getFooterLines(FooterConstants.CHANGE_ID);
+ String sha1 = commit.abbreviate(SHA1_LENGTH).name();
if (idList.isEmpty()) {
if (projectControl.getProjectState().isRequireChangeID()) {
- String shortMsg = receiveEvent.commit.getShortMessage();
- String changeIdPrefix = FooterConstants.CHANGE_ID.getName() + ":";
- if (shortMsg.startsWith(changeIdPrefix)
- && shortMsg.substring(changeIdPrefix.length()).trim()
- .matches("^I[0-9a-f]{8,}.*$")) {
- throw new CommitValidationException(
- "missing subject; Change-Id must be in commit message footer");
- } else {
- String errMsg = "missing Change-Id in commit message footer";
- messages.add(getMissingChangeIdErrorMsg(
- errMsg, receiveEvent.commit));
- throw new CommitValidationException(errMsg, messages);
+ String shortMsg = commit.getShortMessage();
+ if (shortMsg.startsWith(CHANGE_ID_PREFIX)
+ && CHANGE_ID.matcher(shortMsg.substring(
+ CHANGE_ID_PREFIX.length()).trim()).matches()) {
+ String errMsg = String.format(MISSING_SUBJECT_MSG, sha1);
+ throw new CommitValidationException(errMsg);
}
- }
- } else if (idList.size() > 1) {
- throw new CommitValidationException(
- "multiple Change-Id lines in commit message footer", messages);
- } else {
- final String v = idList.get(idList.size() - 1).trim();
- if (!v.matches("^I[0-9a-f]{8,}.*$")) {
- final String errMsg =
- "missing or invalid Change-Id line format in commit message footer";
- messages.add(
- getMissingChangeIdErrorMsg(errMsg, receiveEvent.commit));
+ String errMsg = String.format(MISSING_CHANGE_ID_MSG, sha1);
+ messages.add(getMissingChangeIdErrorMsg(errMsg, commit));
throw new CommitValidationException(errMsg, messages);
}
+ } else if (idList.size() > 1) {
+ String errMsg = String.format(
+ MULTIPLE_CHANGE_ID_MSG, sha1);
+ throw new CommitValidationException(errMsg, messages);
+ }
+ String v = idList.get(idList.size() - 1).trim();
+ if (!CHANGE_ID.matcher(v).matches()) {
+ String errMsg = String.format(INVALID_CHANGE_ID_MSG, sha1);
+ messages.add(
+ getMissingChangeIdErrorMsg(errMsg, receiveEvent.commit));
+ throw new CommitValidationException(errMsg, messages);
}
return Collections.emptyList();
}
private CommitValidationMessage getMissingChangeIdErrorMsg(
final String errMsg, final RevCommit c) {
- final String changeId = "Change-Id:";
StringBuilder sb = new StringBuilder();
sb.append("ERROR: ").append(errMsg);
- if (c.getFullMessage().indexOf(changeId) >= 0) {
+ if (c.getFullMessage().indexOf(CHANGE_ID_PREFIX) >= 0) {
String[] lines = c.getFullMessage().trim().split("\n");
String lastLine = lines.length > 0 ? lines[lines.length - 1] : "";
- if (lastLine.indexOf(changeId) == -1) {
+ if (lastLine.indexOf(CHANGE_ID_PREFIX) == -1) {
sb.append('\n');
sb.append('\n');
- sb.append("Hint: A potential Change-Id was found, but it was not in the ");
+ sb.append("Hint: A potential ");
+ sb.append(FooterConstants.CHANGE_ID.getName());
+ sb.append("Change-Id was found, but it was not in the ");
sb.append("footer (last paragraph) of the commit message.");
}
}
sb.append('\n');
sb.append('\n');
- sb.append("Hint: To automatically insert Change-Id, install the hook:\n");
+ sb.append("Hint: To automatically insert ");
+ sb.append(FooterConstants.CHANGE_ID.getName());
+ sb.append(", install the hook:\n");
sb.append(getCommitMessageHookInstallationHint());
sb.append('\n');
sb.append("And then amend the commit:\n");
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index d92c2b2..590be32 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -14,6 +14,7 @@
package com.google.gerrit.server.query.change;
+import static com.google.gerrit.reviewdb.client.Change.CHANGE_ID_PATTERN;
import static com.google.gerrit.server.query.change.ChangeData.asChanges;
import com.google.common.annotations.VisibleForTesting;
@@ -94,8 +95,7 @@
}
private static final Pattern PAT_LEGACY_ID = Pattern.compile("^[1-9][0-9]*$");
- private static final Pattern PAT_CHANGE_ID =
- Pattern.compile("^[iI][0-9a-f]{4,}.*$");
+ private static final Pattern PAT_CHANGE_ID = Pattern.compile(CHANGE_ID_PATTERN);
private static final Pattern DEF_CHANGE = Pattern.compile(
"^(?:[1-9][0-9]*|(?:[^~]+~[^~]+~)?[iI][0-9a-f]{4,}.*)$");
diff --git a/plugins/replication b/plugins/replication
index 43af15b..b3ab82d 160000
--- a/plugins/replication
+++ b/plugins/replication
@@ -1 +1 @@
-Subproject commit 43af15baab9b2312677000c47313026f34352abb
+Subproject commit b3ab82de95bedd46a60152e2ecffdab1f762e00d
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
index 78d4123..25eacc2 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
@@ -279,7 +279,7 @@
comments="[[_comments]]"
drafts="[[_diffDrafts]]"
revisions="[[_change.revisions]]"
- projectConfig="[[projectConfig]]"
+ projectConfig="[[_projectConfig]]"
selected-index="{{viewState.selectedFileIndex}}"></gr-file-list>
<gr-messages-list id="messageList"
change-num="[[_changeNum]]"
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
index 17aa0c4..85cf380 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
@@ -69,6 +69,7 @@
value: true,
},
_prefs: Object,
+ _projectConfig: Object,
_userPrefs: Object,
_diffMode: {
type: String,
diff --git a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html
index b55a1c3..ae514ba 100644
--- a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html
@@ -43,6 +43,36 @@
_account_id: 123
}),
'/accounts/123/avatar?s=16');
+ assert.equal(element._buildAvatarURL(
+ {
+ _account_id: 123,
+ avatars: [
+ {
+ url: 'https://cdn.example.com/s12-p/photo.jpg',
+ height: 12
+ },
+ {
+ url: 'https://cdn.example.com/s16-p/photo.jpg',
+ height: 16
+ },
+ {
+ url: 'https://cdn.example.com/s100-p/photo.jpg',
+ height: 100
+ },
+ ],
+ }),
+ 'https://cdn.example.com/s16-p/photo.jpg');
+ assert.equal(element._buildAvatarURL(
+ {
+ _account_id: 123,
+ avatars: [
+ {
+ url: 'https://cdn.example.com/s95-p/photo.jpg',
+ height: 95
+ },
+ ],
+ }),
+ '/accounts/123/avatar?s=16');
});
test('dom for existing account', function() {
diff --git a/tools/eclipse/project.py b/tools/eclipse/project.py
index 4b35f7c..46f5680 100755
--- a/tools/eclipse/project.py
+++ b/tools/eclipse/project.py
@@ -42,6 +42,8 @@
help='do not attach sources')
opts.add_option('--plugins', help='create eclipse projects for plugins',
action='store_true')
+opts.add_option('--name', help='name of the generated project',
+ action='store', default='gerrit', dest='project_name')
args, _ = opts.parse_args()
def _query_classpath(targets):
@@ -223,7 +225,7 @@
except CalledProcessError as err:
exit(1)
- gen_project()
+ gen_project(args.project_name)
gen_classpath()
gen_factorypath()