1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-15 03:12:41 +01:00
phorge-phorge/src/applications/diffusion/query/DiffusionRenameHistoryQuery.php
epriestley f68d67530a Fix an issue with pulling Subversion blame data
Summary:
Fixes T4067. The way `DiffusionCommitQuery` works prevents it from loading SVN identifiers in some cases without additional constraints, since "12345" might be an SVN revision 12345, or it might be the first 5 characters of a Git commit hash.

Introduce `withRepository()` as a shorthand for `withDefaultRepository()` + `withRepositoryIDs()`. This tells the query to:

  - Only look in the given repository; and
  - use the more liberal identifier resolution rules while doing so.

The practical impact this has is that blame tooltips in SVN work again. The other queries which are fixed here were never run in SVN (which doesn't have first-class branches or tags); I've cleaned them up only for completeness.

Test Plan:
  - Viewed blame in SVN, saw information again instead of empty tooltip.
  - Viewed brnaches/tags in Mercurial and Git.

{F79226}

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T4067

Differential Revision: https://secure.phabricator.com/D7523
2013-11-07 12:10:43 -08:00

103 lines
2.8 KiB
PHP

<?php
final class DiffusionRenameHistoryQuery {
private $oldCommit;
private $wasCreated;
private $request;
private $viewer;
public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
}
public function getWasCreated() {
return $this->wasCreated;
}
public function setRequest(DiffusionRequest $request) {
$this->request = $request;
return $this;
}
public function setOldCommit($old_commit) {
$this->oldCommit = $old_commit;
return $this;
}
public function getOldCommit() {
return $this->oldCommit;
}
final public function loadOldFilename() {
$drequest = $this->request;
$repository_id = $drequest->getRepository()->getID();
$conn_r = id(new PhabricatorRepository())->establishConnection('r');
$commit_id = $this->loadCommitId($this->oldCommit);
$old_commit_sequence = $this->loadCommitSequence($commit_id);
$path = '/'.$drequest->getPath();
$commit_id = $this->loadCommitId($drequest->getCommit());
do {
$commit_sequence = $this->loadCommitSequence($commit_id);
$change = queryfx_one(
$conn_r,
'SELECT pc.changeType, pc.targetCommitID, tp.path
FROM %T p
JOIN %T pc ON p.id = pc.pathID
LEFT JOIN %T tp ON pc.targetPathID = tp.id
WHERE p.pathHash = %s
AND pc.repositoryID = %d
AND pc.changeType IN (%d, %d)
AND pc.commitSequence BETWEEN %d AND %d
ORDER BY pc.commitSequence DESC
LIMIT 1',
PhabricatorRepository::TABLE_PATH,
PhabricatorRepository::TABLE_PATHCHANGE,
PhabricatorRepository::TABLE_PATH,
md5($path),
$repository_id,
ArcanistDiffChangeType::TYPE_MOVE_HERE,
ArcanistDiffChangeType::TYPE_ADD,
$old_commit_sequence,
$commit_sequence);
if ($change) {
if ($change['changeType'] == ArcanistDiffChangeType::TYPE_ADD) {
$this->wasCreated = true;
return $path;
}
$commit_id = $change['targetCommitID'];
$path = $change['path'];
}
} while ($change && $path);
return $path;
}
private function loadCommitId($commit_identifier) {
$commit = id(new DiffusionCommitQuery())
->setViewer($this->viewer)
->withIdentifiers(array($commit_identifier))
->withRepository($this->request->getRepository())
->executeOne();
return $commit->getID();
}
private function loadCommitSequence($commit_id) {
$conn_r = id(new PhabricatorRepository())->establishConnection('r');
$path_change = queryfx_one(
$conn_r,
'SELECT commitSequence
FROM %T
WHERE repositoryID = %d AND commitID = %d
LIMIT 1',
PhabricatorRepository::TABLE_PATHCHANGE,
$this->request->getRepository()->getID(),
$commit_id);
return reset($path_change);
}
}