diff --git a/src/applications/diffusion/query/DiffusionCommitQuery.php b/src/applications/diffusion/query/DiffusionCommitQuery.php --- a/src/applications/diffusion/query/DiffusionCommitQuery.php +++ b/src/applications/diffusion/query/DiffusionCommitQuery.php @@ -51,6 +51,11 @@ * they queried for. */ public function withIdentifiers(array $identifiers) { + // Some workflows (like blame lookups) can pass in large numbers of + // duplicate identifiers. We only care about unique identifiers, so + // get rid of duplicates immediately. + $identifiers = array_fuse($identifiers); + $this->identifiers = $identifiers; return $this; } @@ -185,7 +190,7 @@ // Build the identifierMap if ($this->identifiers !== null) { - $ids = array_fuse($this->identifiers); + $ids = $this->identifiers; $prefixes = array( 'r'.$commit->getRepository()->getCallsign(), 'r'.$commit->getRepository()->getCallsign().':', @@ -395,7 +400,6 @@ $repos->execute(); $repos = $repos->getIdentifierMap(); - foreach ($refs as $key => $ref) { $repo = idx($repos, $ref['callsign']); @@ -404,7 +408,7 @@ } if ($repo->isSVN()) { - if (!ctype_digit($ref['identifier'])) { + if (!ctype_digit((string)$ref['identifier'])) { continue; } $sql[] = qsprintf( @@ -419,11 +423,25 @@ if (strlen($ref['identifier']) < $min_qualified) { continue; } - $sql[] = qsprintf( - $conn, - '(commit.repositoryID = %d AND commit.commitIdentifier LIKE %>)', - $repo->getID(), - $ref['identifier']); + + $identifier = $ref['identifier']; + if (strlen($identifier) == 40) { + // MySQL seems to do slightly better with this version if the + // clause, so issue it if we have a full commit hash. + $sql[] = qsprintf( + $conn, + '(commit.repositoryID = %d + AND commit.commitIdentifier = %s)', + $repo->getID(), + $identifier); + } else { + $sql[] = qsprintf( + $conn, + '(commit.repositoryID = %d + AND commit.commitIdentifier LIKE %>)', + $repo->getID(), + $identifier); + } } } }