Honor --reviewer=not.preferred.email during upload
This is more DWIMery for the upload patch, when a reviewer is
selected we should support picking them by any registered email
address, not just their preferred email address.
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/src/main/java/com/google/gerrit/server/ssh/Receive.java b/src/main/java/com/google/gerrit/server/ssh/Receive.java
index c4d22eb..91a97ce 100644
--- a/src/main/java/com/google/gerrit/server/ssh/Receive.java
+++ b/src/main/java/com/google/gerrit/server/ssh/Receive.java
@@ -304,19 +304,50 @@
private void lookup(final Set<Account.Id> accountIds,
final String addressType, final Set<String> emails) throws Failure {
final String efmt = server.getEmailFormat();
+ final boolean haveFormat = efmt != null && efmt.contains("{0}");
final StringBuilder errors = new StringBuilder();
try {
- for (final String email : emails) {
- Account who = Account.find(db, email);
- if (who == null && !email.contains("@") && !email.contains(" ")
- && efmt != null && efmt.contains("{0}")) {
- who = Account.find(db, MessageFormat.format(efmt, email));
+ for (final String nameOrEmail : emails) {
+ final HashSet<Account.Id> matches = new HashSet<Account.Id>();
+ String email = splitEmail(nameOrEmail);
+
+ if (email == null && haveFormat && !nameOrEmail.contains(" ")) {
+ // Not a full name, since it has no space, and not an email
+ // address either. Assume it is just the local portion of
+ // the organizations standard email format, and complete out.
+ //
+ email = MessageFormat.format(efmt, nameOrEmail);
}
- if (who != null) {
- accountIds.add(who.getId());
+
+ if (email == null) {
+ // Not an email address implies it was a full name, search by
+ // full name hoping to get a unique match.
+ //
+ final String n = nameOrEmail;
+ for (final Account a : db.accounts().suggestByFullName(n, n, 2)) {
+ matches.add(a.getId());
+ }
} else {
- errors.append("fatal: " + addressType + " " + email
- + " is not registered on Gerrit\n");
+ // Scan email addresses for any potential matches.
+ //
+ for (final AccountExternalId e : db.accountExternalIds()
+ .byEmailAddress(email)) {
+ matches.add(e.getAccountId());
+ }
+ }
+
+ switch (matches.size()) {
+ case 0:
+ errors.append("fatal: " + addressType + " \"" + nameOrEmail
+ + "\" is not registered\n");
+ break;
+ case 1:
+ accountIds.add(matches.iterator().next());
+ break;
+ default:
+ errors.append("fatal: " + addressType + " \"" + nameOrEmail
+ + "\" matches multiple accounts\n");
+ break;
}
}
} catch (OrmException e) {
@@ -327,6 +358,18 @@
}
}
+ private static String splitEmail(final String nameOrEmail) {
+ final int lt = nameOrEmail.indexOf('<');
+ final int gt = nameOrEmail.indexOf('>');
+ if (lt >= 0 && gt > lt) {
+ return nameOrEmail.substring(lt + 1, gt);
+ }
+ if (nameOrEmail.contains("@")) {
+ return nameOrEmail;
+ }
+ return null;
+ }
+
@Override
protected String parseCommandLine(final String[] args) throws Failure {
int argi = 0;