Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F17707327
D9044.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
D9044.diff
View Options
diff --git a/resources/sql/autopatches/20140512.dparents.1.sql b/resources/sql/autopatches/20140512.dparents.1.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20140512.dparents.1.sql
@@ -0,0 +1,7 @@
+CREATE TABLE {$NAMESPACE}_repository.repository_parents (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ childCommitID INT UNSIGNED NOT NULL,
+ parentCommitID INT UNSIGNED NOT NULL,
+ UNIQUE `key_child` (childCommitID, parentCommitID),
+ KEY `key_parent` (parentCommitID)
+) ENGINE=InnoDB, COLLATE utf8_general_ci;
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1993,6 +1993,7 @@
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementLookupUsersWorkflow.php',
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkImportedWorkflow.php',
'PhabricatorRepositoryManagementMirrorWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMirrorWorkflow.php',
+ 'PhabricatorRepositoryManagementParentsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php',
'PhabricatorRepositoryManagementPullWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementPullWorkflow.php',
'PhabricatorRepositoryManagementRefsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementRefsWorkflow.php',
'PhabricatorRepositoryManagementUpdateWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementUpdateWorkflow.php',
@@ -4835,6 +4836,7 @@
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementMirrorWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
+ 'PhabricatorRepositoryManagementParentsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementPullWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementRefsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementUpdateWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
diff --git a/src/applications/repository/engine/PhabricatorRepositoryCommitRef.php b/src/applications/repository/engine/PhabricatorRepositoryCommitRef.php
--- a/src/applications/repository/engine/PhabricatorRepositoryCommitRef.php
+++ b/src/applications/repository/engine/PhabricatorRepositoryCommitRef.php
@@ -6,6 +6,7 @@
private $epoch;
private $branch;
private $canCloseImmediately;
+ private $parents = array();
public function setIdentifier($identifier) {
$this->identifier = $identifier;
@@ -43,4 +44,13 @@
return $this->canCloseImmediately;
}
+ public function setParents(array $parents) {
+ $this->parents = $parents;
+ return $this;
+ }
+
+ public function getParents() {
+ return $this->parents;
+ }
+
}
diff --git a/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php b/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php
--- a/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php
+++ b/src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php
@@ -61,7 +61,8 @@
$repository,
$ref->getIdentifier(),
$ref->getEpoch(),
- $ref->getCanCloseImmediately());
+ $ref->getCanCloseImmediately(),
+ $ref->getParents());
$this->commitCache[$ref->getIdentifier()] = true;
}
@@ -436,7 +437,8 @@
$refs[] = id(new PhabricatorRepositoryCommitRef())
->setIdentifier($commit)
->setEpoch($stream->getCommitDate($commit))
- ->setCanCloseImmediately($close_immediately);
+ ->setCanCloseImmediately($close_immediately)
+ ->setParents($stream->getParents($commit));
}
return $refs;
@@ -534,7 +536,8 @@
PhabricatorRepository $repository,
$commit_identifier,
$epoch,
- $close_immediately) {
+ $close_immediately,
+ array $parents) {
$commit = new PhabricatorRepositoryCommit();
$commit->setRepositoryID($repository->getID());
@@ -546,17 +549,55 @@
$data = new PhabricatorRepositoryCommitData();
+ $conn_w = $repository->establishConnection('w');
+
try {
+
+ // If this commit has parents, look up their IDs. The parent commits
+ // should always exist already.
+
+ $parent_ids = array();
+ if ($parents) {
+ $parent_rows = queryfx_all(
+ $conn_w,
+ 'SELECT id, commitIdentifier FROM %T
+ WHERE commitIdentifier IN (%Ls) AND repositoryID = %d',
+ $commit->getTableName(),
+ $parents,
+ $repository->getID());
+
+ $parent_map = ipull($parent_rows, 'id', 'commitIdentifier');
+
+ foreach ($parents as $parent) {
+ if (empty($parent_map[$parent])) {
+ throw new Exception(
+ pht('Unable to identify parent "%s"!', $parent));
+ }
+ $parent_ids[] = $parent_map[$parent];
+ }
+ }
+
$commit->openTransaction();
$commit->save();
+
$data->setCommitID($commit->getID());
$data->save();
+
+ foreach ($parent_ids as $parent_id) {
+ queryfx(
+ $conn_w,
+ 'INSERT IGNORE INTO %T (childCommitID, parentCommitID)
+ VALUES (%d, %d)',
+ PhabricatorRepository::TABLE_PARENTS,
+ $commit->getID(),
+ $parent_id);
+ }
$commit->saveTransaction();
$this->insertTask($repository, $commit);
queryfx(
- $repository->establishConnection('w'),
+ $conn_w,
'INSERT INTO %T (repositoryID, size, lastCommitID, epoch)
VALUES (%d, 1, %d, %d)
ON DUPLICATE KEY UPDATE
@@ -583,6 +624,8 @@
'commit' => $commit,
)));
+
+
} catch (AphrontQueryDuplicateKeyException $ex) {
$commit->killTransaction();
// Ignore. This can happen because we discover the same new commit
diff --git a/src/applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php b/src/applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php
new file mode 100644
--- /dev/null
+++ b/src/applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php
@@ -0,0 +1,149 @@
+<?php
+
+final class PhabricatorRepositoryManagementParentsWorkflow
+ extends PhabricatorRepositoryManagementWorkflow {
+
+ public function didConstruct() {
+ $this
+ ->setName('parents')
+ ->setExamples('**parents** [options] [__repository__] ...')
+ ->setSynopsis(
+ pht(
+ 'Build parent caches in repositories that are missing the data, '.
+ 'or rebuild them in a specific __repository__.'))
+ ->setArguments(
+ array(
+ array(
+ 'name' => 'repos',
+ 'wildcard' => true,
+ ),
+ ));
+ }
+
+ public function execute(PhutilArgumentParser $args) {
+ $repos = $this->loadRepositories($args, 'repos');
+ if (!$repos) {
+ $repos = id(new PhabricatorRepositoryQuery())
+ ->setViewer($this->getViewer())
+ ->execute();
+ }
+
+ $console = PhutilConsole::getConsole();
+ foreach ($repos as $repo) {
+ $monogram = $repo->getMonogram();
+ if ($repo->isSVN()) {
+ $console->writeOut(
+ "%s\n",
+ pht(
+ 'Skipping "%s": Subversion repositories do not require this '.
+ 'cache to be built.',
+ $monogram));
+ continue;
+ }
+ $this->rebuildRepository($repo);
+ }
+
+ return 0;
+ }
+
+ private function rebuildRepository(PhabricatorRepository $repo) {
+ $console = PhutilConsole::getConsole();
+ $console->writeOut("%s\n", pht('Rebuilding "%s"...', $repo->getMonogram()));
+
+ $refs = id(new PhabricatorRepositoryRefCursorQuery())
+ ->setViewer($this->getViewer())
+ ->withRefTypes(array(PhabricatorRepositoryRefCursor::TYPE_BRANCH))
+ ->withRepositoryPHIDs(array($repo->getPHID()))
+ ->execute();
+
+ $graph = array();
+ foreach ($refs as $ref) {
+ $console->writeOut(
+ "%s\n",
+ pht('Rebuilding branch "%s"...', $ref->getRefName()));
+
+ $commit = $ref->getCommitIdentifier();
+
+ if ($repo->isGit()) {
+ $stream = new PhabricatorGitGraphStream($repo, $commit);
+ } else {
+ $stream = new PhabricatorMercurialGraphStream($repo, $commit);
+ }
+
+ $discover = array($commit);
+ while ($discover) {
+ $target = array_pop($discover);
+ if (isset($graph[$target])) {
+ continue;
+ }
+ $graph[$target] = $stream->getParents($target);
+ foreach ($graph[$target] as $parent) {
+ $discover[] = $parent;
+ }
+ }
+ }
+
+ $console->writeOut(
+ "%s\n",
+ pht(
+ 'Found %s total commit(s); updating...',
+ new PhutilNumber(count($graph))));
+
+ $commit_table = id(new PhabricatorRepositoryCommit());
+ $commit_table_name = $commit_table->getTableName();
+ $conn_w = $commit_table->establishConnection('w');
+
+ $bar = id(new PhutilConsoleProgressBar())
+ ->setTotal(count($graph));
+
+ foreach ($graph as $child => $parents) {
+ $names = $parents;
+ $names[] = $child;
+
+ $rows = queryfx_all(
+ $conn_w,
+ 'SELECT id, commitIdentifier FROM %T
+ WHERE commitIdentifier IN (%Ls) AND repositoryID = %d',
+ $commit_table_name,
+ $names,
+ $repo->getID());
+
+ $map = ipull($rows, 'id', 'commitIdentifier');
+ foreach ($names as $name) {
+ if (empty($map[$name])) {
+ throw new Exception(pht('Unknown commit "%s"!', $name));
+ }
+ }
+
+ $sql = array();
+ foreach ($parents as $parent) {
+ $sql[] = qsprintf(
+ $conn_w,
+ '(%d, %d)',
+ $map[$child],
+ $map[$parent]);
+ }
+
+ $commit_table->openTransaction();
+ queryfx(
+ $conn_w,
+ 'DELETE FROM %T WHERE childCommitID = %d',
+ PhabricatorRepository::TABLE_PARENTS,
+ $map[$child]);
+
+ if ($sql) {
+ queryfx(
+ $conn_w,
+ 'INSERT INTO %T (childCommitID, parentCommitID) VALUES %Q',
+ PhabricatorRepository::TABLE_PARENTS,
+ implode(', ', $sql));
+ }
+ $commit_table->saveTransaction();
+
+ $bar->update(1);
+ }
+
+ $bar->done();
+ }
+
+}
diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php
--- a/src/applications/repository/storage/PhabricatorRepository.php
+++ b/src/applications/repository/storage/PhabricatorRepository.php
@@ -25,6 +25,7 @@
const TABLE_SUMMARY = 'repository_summary';
const TABLE_BADCOMMIT = 'repository_badcommit';
const TABLE_LINTMESSAGE = 'repository_lintmessage';
+ const TABLE_PARENTS = 'repository_parents';
const SERVE_OFF = 'off';
const SERVE_READONLY = 'readonly';
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 17, 2:51 PM (4 d, 10 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
8498089
Default Alt Text
D9044.diff (11 KB)
Attached To
Mode
D9044: Record parent relationships when discovering commits
Attached
Detach File
Event Timeline
Log In to Comment