Merge "AccountPatchReview mariadb: fix key length" into stable-3.1
diff --git a/Documentation/error-commit-already-exists.txt b/Documentation/error-commit-already-exists.txt
index d2b7c9d..2832c78 100644
--- a/Documentation/error-commit-already-exists.txt
+++ b/Documentation/error-commit-already-exists.txt
@@ -1,6 +1,6 @@
= commit already exists
-With "commit already exists (as current patchset)" or
+With "commit(s) already exists (as current patchset)" or
"commit already exists (in the change)" error message
Gerrit rejects to push a commit to an existing change via
`refs/changes/n` if the commit was already successfully
diff --git a/contrib/find-duplicate-usernames.sh b/contrib/find-duplicate-usernames.sh
new file mode 100755
index 0000000..b59e5be
--- /dev/null
+++ b/contrib/find-duplicate-usernames.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# Copyright (C) 2021 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.
+usage() {
+ f="$(basename -- $0)"
+ cat <<EOF
+Usage:
+ cd /path/to/All-Users.git
+ "$f [username|gerrit|external]"
+
+This script finds duplicate usernames only differing in case in the given
+account schema ("username", "gerrit" or "external") and their respective accountIds.
+EOF
+ exit 1
+}
+
+if [[ "$#" -ne "1" ]] || ! [[ "$1" =~ ^(gerrit|username|external)$ ]]; then
+ usage
+fi
+
+# 1. find lines with user name and subsequent line in external-ids notes branch
+# example output of git grep -A1 "\[externalId \"username:" refs/meta/external-ids:
+# refs/meta/external-ids:00/1d/abd037e437f71d42134e6ad532a06948a2ba:[externalId "username:johndoe"]
+# refs/meta/external-ids:00/1d/abd037e437f71d42134e6ad532a06948a2ba- accountId = 1000815
+# --
+# refs/meta/external-ids:00/1f/0270fc2a6fc3a2439c454c8ab0c75323fdb0:[externalId "username:JohnDoe"]
+# refs/meta/external-ids:00/1f/0270fc2a6fc3a2439c454c8ab0c75323fdb0- accountId = 1000816
+# --
+# 2. remove group separators
+# 3. remove line break between user name and accountId lines
+# 4. unify separators to ":"
+# 5. cut on ":", select username and accountId fields
+# 6. sort case-insensitive
+# 7. flip columns
+# 8. uniq case-insensitive, only show duplicates, avoid comparing first field
+# 9. flip columns back
+git grep -A1 "\[externalId \"$1:" refs/meta/external-ids \
+ | sed -E "/$1/,/accountId/!d" \
+ | paste -d ' ' - - \
+ | tr \"= : \
+ | cut -d: --output-delimiter="" -f 5,8 \
+ | sort -f \
+ | sed -E "s/(.*) (.*)/\2 \1/" \
+ | uniq -Di -f1 \
+ | sed -E "s/(.*) (.*)/\2 \1/"
diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/AbandonChange.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/AbandonChange.scala
index 51bcb9e..d387a3e 100644
--- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/AbandonChange.scala
+++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/AbandonChange.scala
@@ -43,9 +43,9 @@
numbersCopy = createChange.get.numbers.clone()
}
}
- session.set("number", numbersCopy.dequeue())
+ session.set(numberKey, numbersCopy.dequeue())
})
- .exec(http(uniqueName).post("${url}${number}/abandon"))
+ .exec(http(uniqueName).post("${url}${" + numberKey + "}/abandon"))
private val createProject = new CreateProject(projectName)
private val deleteProject = new DeleteProject(projectName)
diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/ApproveChange.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/ApproveChange.scala
index 5e4f671..9a91153 100644
--- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/ApproveChange.scala
+++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/ApproveChange.scala
@@ -40,13 +40,13 @@
if (numbersCopy.isEmpty) {
numbersCopy = createChange.get.numbers.clone()
}
- session.set("number", numbersCopy.dequeue())
+ session.set(numberKey, numbersCopy.dequeue())
} else {
session
}
})
.exec(http(uniqueName)
- .post("${url}${number}/revisions/current/review")
+ .post("${url}${" + numberKey + "}/revisions/current/review")
.body(ElFileBody(body)).asJson)
setUp(
diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CreateChange.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CreateChange.scala
index b28edb5..fb41075 100644
--- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CreateChange.scala
+++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/CreateChange.scala
@@ -24,7 +24,6 @@
class CreateChange extends ProjectSimulation {
private val data: FeederBuilder = jsonFile(resource).convert(keys).circular
- private val numberKey = "_number"
private val weightPerUser = 0.1
private var createBranch: Option[CreateBranch] = None
private var branchesCopy: mutable.Queue[String] = mutable.Queue[String]()
@@ -58,7 +57,7 @@
})
.exec(httpRequest
.body(ElFileBody(body)).asJson
- .check(regex("\"" + numberKey + "\":(\\d+),").saveAs(numberKey)))
+ .check(regex("\"_" + numberKey + "\":(\\d+),").saveAs(numberKey)))
.exec(session => {
number = session(numberKey).as[Int]
numbers += number
diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/DeleteChange.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/DeleteChange.scala
index e47108f..743219f 100644
--- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/DeleteChange.scala
+++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/DeleteChange.scala
@@ -34,12 +34,12 @@
.feed(data)
.exec(session => {
if (createChange.nonEmpty) {
- session.set("number", createChange.get.numbers.dequeue())
+ session.set(numberKey, createChange.get.numbers.dequeue())
} else {
session
}
})
- .exec(http(uniqueName).delete("${url}${number}"))
+ .exec(http(uniqueName).delete("${url}${" + numberKey + "}"))
setUp(
test.inject(
diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/GerritSimulation.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/GerritSimulation.scala
index b11c87c..c199dd9 100644
--- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/GerritSimulation.scala
+++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/GerritSimulation.scala
@@ -23,6 +23,8 @@
class GerritSimulation extends Simulation {
implicit val conf: GatlingGitConfiguration = GatlingGitConfiguration()
+ protected val numberKey: String = "number"
+
private val packageName = getClass.getPackage.getName
private val path = packageName.replaceAllLiterally(".", "/")
@@ -64,9 +66,9 @@
protected val keys: PartialFunction[(String, Any), Any] = {
case ("entries", entries) =>
replaceProperty("projects_entries", "1", entries.toString)
- case ("number", number) =>
- val precedes = replaceKeyWith("_number", 0, number.toString)
- replaceProperty("number", 1, precedes)
+ case (`numberKey`, number) =>
+ val precedes = replaceKeyWith("_" + numberKey, 0, number.toString)
+ replaceProperty(numberKey, 1, precedes)
case ("parent", parent) =>
replaceProperty("parent", "All-Projects", parent.toString)
case ("project", project) =>
@@ -90,6 +92,11 @@
}
protected def replaceProperty(term: String, default: Any, in: String): String = {
+ val value = getProperty(term, default)
+ replaceKeyWith(term, value, in)
+ }
+
+ protected def getProperty(term: String, default: Any): String = {
val property = packageName + "." + term
var value = default
default match {
@@ -101,7 +108,7 @@
case _: Integer =>
value = Integer.getInteger(property, default.asInstanceOf[Integer])
}
- replaceKeyWith(term, value, in)
+ value.toString
}
protected def replaceKeyWith(term: String, value: Any, in: String): String = {
diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/RestoreChange.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/RestoreChange.scala
index b952670..81096b0 100644
--- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/RestoreChange.scala
+++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/RestoreChange.scala
@@ -35,9 +35,9 @@
if (numbersCopy.isEmpty) {
numbersCopy = createChange.numbers.clone()
}
- session.set("number", numbersCopy.dequeue())
+ session.set(numberKey, numbersCopy.dequeue())
}
- ).exec(http(uniqueName).post("${url}${number}/restore"))
+ ).exec(http(uniqueName).post("${url}${" + numberKey + "}/restore"))
private val createProject = new CreateProject(projectName)
private val createChange = new CreateChange(projectName)
diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/SubmitChange.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/SubmitChange.scala
index 067496a..20be28a 100644
--- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/SubmitChange.scala
+++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/SubmitChange.scala
@@ -36,9 +36,9 @@
val test: ScenarioBuilder = scenario(uniqueName)
.feed(data)
.exec(session => {
- session.set("number", createChange.number)
+ session.set(numberKey, createChange.number)
})
- .exec(http(uniqueName).post("${url}${number}/submit"))
+ .exec(http(uniqueName).post("${url}${" + numberKey + "}/submit"))
private val createProject = new CreateProject(projectName)
private val approveChange = new ApproveChange(createChange)
diff --git a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/SubmitChangeInBranch.scala b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/SubmitChangeInBranch.scala
index 1b88503..9e1431b 100644
--- a/e2e-tests/src/test/scala/com/google/gerrit/scenarios/SubmitChangeInBranch.scala
+++ b/e2e-tests/src/test/scala/com/google/gerrit/scenarios/SubmitChangeInBranch.scala
@@ -35,9 +35,9 @@
if (changesCopy.isEmpty) {
changesCopy = createChange.numbers.clone()
}
- session.set("number", changesCopy.dequeue())
+ session.set(numberKey, changesCopy.dequeue())
})
- .exec(http(uniqueName).post("${url}${number}/submit"))
+ .exec(http(uniqueName).post("${url}${" + numberKey + "}/submit"))
private val createProject = new CreateProject(projectName)
private val createBranch = new CreateBranch(projectName)
diff --git a/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior.html b/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior.html
index 0c75c44..fedefc6 100644
--- a/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior.html
+++ b/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior.html
@@ -88,10 +88,6 @@
id: 'owner',
name: 'Owner',
},
- publishDrafts: {
- id: 'publishDrafts',
- name: 'Publish Drafts',
- },
push: {
id: 'push',
name: 'Push',
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js
index 0eaa496..5de844f 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js
@@ -125,7 +125,7 @@
.then(repos => {
// Late response.
if (filter !== this._filter || !repos) { return; }
- this._repos = repos;
+ this._repos = repos.filter(repo => repo.name.includes(filter));
this._loading = false;
});
},
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html
index c77592c..625312d 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html
@@ -40,6 +40,7 @@
const repoGenerator = () => {
return {
id: `test${++counter}`,
+ name: `test`,
state: 'ACTIVE',
web_links: [
{
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
index 773ad68..ab9b70e 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
@@ -224,7 +224,7 @@
});
if (m.name in topMenuLinks) {
items.forEach(link => { topMenuLinks[m.name].push(link); });
- } else {
+ } else if (items.length > 0) {
links.push({
title: m.name,
links: topMenuLinks[m.name] = items,