Page MenuHomePhabricator

D7987.id18088.diff
No OneTemporary

D7987.id18088.diff

Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -1847,6 +1847,7 @@
'PhabricatorRepositoryEngine' => 'applications/repository/engine/PhabricatorRepositoryEngine.php',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php',
+ 'PhabricatorRepositoryGraphStream' => 'applications/repository/daemon/PhabricatorRepositoryGraphStream.php',
'PhabricatorRepositoryListController' => 'applications/repository/controller/PhabricatorRepositoryListController.php',
'PhabricatorRepositoryManagementDeleteWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDeleteWorkflow.php',
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDiscoverWorkflow.php',
@@ -4154,6 +4155,7 @@
'PhabricatorGarbageCollectorConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorGarbageCollectorDaemon' => 'PhabricatorDaemon',
'PhabricatorGestureExample' => 'PhabricatorUIExample',
+ 'PhabricatorGitGraphStream' => 'PhabricatorRepositoryGraphStream',
'PhabricatorGlobalLock' => 'PhutilLock',
'PhabricatorGlobalUploadTargetView' => 'AphrontView',
'PhabricatorHandleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
@@ -4241,6 +4243,7 @@
'PhabricatorMarkupCache' => 'PhabricatorCacheDAO',
'PhabricatorMarkupOneOff' => 'PhabricatorMarkupInterface',
'PhabricatorMarkupPreviewController' => 'PhabricatorController',
+ 'PhabricatorMercurialGraphStream' => 'PhabricatorRepositoryGraphStream',
'PhabricatorMetaMTAActorQuery' => 'PhabricatorQuery',
'PhabricatorMetaMTAConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorMetaMTAController' => 'PhabricatorController',
@@ -4516,6 +4519,7 @@
'PhabricatorRepositoryEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
+ 'PhabricatorRepositoryGraphStream' => 'Phobject',
'PhabricatorRepositoryListController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryManagementDeleteWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
Index: src/applications/repository/daemon/PhabricatorGitGraphStream.php
===================================================================
--- src/applications/repository/daemon/PhabricatorGitGraphStream.php
+++ src/applications/repository/daemon/PhabricatorGitGraphStream.php
@@ -1,6 +1,7 @@
<?php
-final class PhabricatorGitGraphStream {
+final class PhabricatorGitGraphStream
+ extends PhabricatorRepositoryGraphStream {
private $repository;
private $iterator;
Index: src/applications/repository/daemon/PhabricatorMercurialGraphStream.php
===================================================================
--- src/applications/repository/daemon/PhabricatorMercurialGraphStream.php
+++ src/applications/repository/daemon/PhabricatorMercurialGraphStream.php
@@ -5,7 +5,8 @@
* the Mercurial commit graph with one nonblocking invocation of "hg". See
* @{class:PhabricatorRepositoryPullLocalDaemon}.
*/
-final class PhabricatorMercurialGraphStream {
+final class PhabricatorMercurialGraphStream
+ extends PhabricatorRepositoryGraphStream {
private $repository;
private $iterator;
@@ -15,11 +16,13 @@
private $local = array();
private $localParents = array();
- public function __construct(PhabricatorRepository $repository) {
+ public function __construct(PhabricatorRepository $repository, $commit) {
$this->repository = $repository;
$future = $repository->getLocalCommandFuture(
- "log --template '{rev}\1{node}\1{date}\1{parents}\2'");
+ 'log --template %s --rev %s',
+ '{rev}\1{node}\1{date}\1{parents}\2',
+ hgsprintf('reverse(ancestors(%s))', $commit));
$this->iterator = new LinesOfALargeExecFuture($future);
$this->iterator->setDelimiter("\2");
Index: src/applications/repository/daemon/PhabricatorRepositoryGraphStream.php
===================================================================
--- /dev/null
+++ src/applications/repository/daemon/PhabricatorRepositoryGraphStream.php
@@ -0,0 +1,8 @@
+<?php
+
+abstract class PhabricatorRepositoryGraphStream extends Phobject {
+
+ abstract public function getParents($commit);
+ abstract public function getCommitDate($commit);
+
+}
Index: src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
===================================================================
--- src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
+++ src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
@@ -29,7 +29,6 @@
final class PhabricatorRepositoryPullLocalDaemon
extends PhabricatorDaemon {
- private $commitCache = array();
private $repair;
private $discoveryEngines = array();
@@ -223,31 +222,15 @@
}
public function discoverRepository(PhabricatorRepository $repository) {
- $vcs = $repository->getVersionControlSystem();
-
- $result = null;
- $refs = null;
- switch ($vcs) {
- case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
- $result = $this->executeGitDiscover($repository);
- break;
- case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
- case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
- $refs = $this->getDiscoveryEngine($repository)
- ->discoverCommits();
- break;
- default:
- throw new Exception("Unknown VCS '{$vcs}'!");
- }
+ $refs = $this->getDiscoveryEngine($repository)
+ ->discoverCommits();
- if ($refs !== null) {
- foreach ($refs as $ref) {
- $this->recordCommit(
- $repository,
- $ref->getIdentifier(),
- $ref->getEpoch(),
- $close_immediately = true);
- }
+ foreach ($refs as $ref) {
+ $this->recordCommit(
+ $repository,
+ $ref->getIdentifier(),
+ $ref->getEpoch(),
+ $ref->getCanCloseImmediately());
}
$this->checkIfRepositoryIsFullyImported($repository);
@@ -258,14 +241,15 @@
// TODO: We should report these into the UI properly, but for
// now just complain. These errors are much less severe than
// pull errors.
- phlog($ex);
+ $proxy = new PhutilProxyException(
+ pht(
+ 'Error while pushing "%s" repository to a mirror.',
+ $repository->getCallsign()),
+ $ex);
+ phlog($proxy);
}
- if ($refs !== null) {
- return (bool)count($refs);
- } else {
- return $result;
- }
+ return (bool)count($refs);
}
private function updateRepositoryRefs(PhabricatorRepository $repository) {
@@ -287,38 +271,6 @@
return $this->discoveryEngines[$id];
}
- private function isKnownCommit(
- PhabricatorRepository $repository,
- $target) {
-
- if ($this->getCache($repository, $target)) {
- return true;
- }
-
- if ($this->repair) {
- // In repair mode, rediscover the entire repository, ignoring the
- // database state. We can hit the local cache above, but if we miss it
- // stop the script from going to the database cache.
- return false;
- }
-
- $commit = id(new PhabricatorRepositoryCommit())->loadOneWhere(
- 'repositoryID = %d AND commitIdentifier = %s',
- $repository->getID(),
- $target);
-
- if (!$commit) {
- return false;
- }
-
- $this->setCache($repository, $target);
- while (count($this->commitCache) > 2048) {
- array_shift($this->commitCache);
- }
-
- return true;
- }
-
private function recordCommit(
PhabricatorRepository $repository,
$commit_identifier,
@@ -364,8 +316,6 @@
$this->log("Repaired commit '{$commit_identifier}'.");
}
- $this->setCache($repository, $commit_identifier);
-
PhutilEventEngine::dispatchEvent(
new PhabricatorEvent(
PhabricatorEventType::TYPE_DIFFUSION_DIDDISCOVERCOMMIT,
@@ -380,7 +330,6 @@
// more than once when looking at history, or because of races or
// data inconsistency or cosmic radiation; in any case, we're still
// in a good state if we ignore the failure.
- $this->setCache($repository, $commit_identifier);
}
}
@@ -409,30 +358,6 @@
PhabricatorWorker::scheduleTask($class, $data);
}
-
- private function setCache(
- PhabricatorRepository $repository,
- $commit_identifier) {
-
- $key = $this->getCacheKey($repository, $commit_identifier);
- $this->commitCache[$key] = true;
- }
-
- private function getCache(
- PhabricatorRepository $repository,
- $commit_identifier) {
-
- $key = $this->getCacheKey($repository, $commit_identifier);
- return idx($this->commitCache, $key, false);
- }
-
- private function getCacheKey(
- PhabricatorRepository $repository,
- $commit_identifier) {
-
- return $repository->getID().':'.$commit_identifier;
- }
-
private function checkIfRepositoryIsFullyImported(
PhabricatorRepository $repository) {
@@ -468,239 +393,6 @@
$repository->saveTransaction();
}
-/* -( Git Implementation )------------------------------------------------- */
-
-
- /**
- * @task git
- */
- private function executeGitDiscover(
- PhabricatorRepository $repository) {
-
- if (!$repository->isHosted()) {
- $this->verifyOrigin($repository);
- }
-
- $refs = id(new DiffusionLowLevelGitRefQuery())
- ->setRepository($repository)
- ->withIsOriginBranch(true)
- ->execute();
-
- $branches = mpull($refs, 'getCommitIdentifier', 'getShortName');
-
- if (!$branches) {
- // This repository has no branches at all, so we don't need to do
- // anything. Generally, this means the repository is empty.
- return;
- }
-
- $branches = $this->sortBranches($repository, $branches);
-
- $callsign = $repository->getCallsign();
-
- $tracked_something = false;
-
- $this->log("Discovering commits in repository '{$callsign}'...");
- foreach ($branches as $name => $commit) {
- $this->log("Examining branch '{$name}', at {$commit}.");
- if (!$repository->shouldTrackBranch($name)) {
- $this->log("Skipping, branch is untracked.");
- continue;
- }
-
- $tracked_something = true;
-
- if ($this->isKnownCommit($repository, $commit)) {
- $this->log("Skipping, HEAD is known.");
- continue;
- }
-
- $this->log("Looking for new commits.");
- $this->executeGitDiscoverCommit(
- $repository,
- $commit,
- $repository->shouldAutocloseBranch($name));
- }
-
- if (!$tracked_something) {
- $repo_name = $repository->getName();
- $repo_callsign = $repository->getCallsign();
- throw new Exception(
- "Repository r{$repo_callsign} '{$repo_name}' has no tracked branches! ".
- "Verify that your branch filtering settings are correct.");
- }
- }
-
- /**
- * Sort branches so we process closeable branches first. This makes the
- * whole import process a little cheaper, since we can close these commits
- * the first time through rather than catching them in the refs step.
- */
- private function sortBranches(
- PhabricatorRepository $repository,
- array $branches) {
-
- $head_branches = array();
- $tail_branches = array();
- foreach ($branches as $name => $commit) {
- if ($repository->shouldAutocloseBranch($name)) {
- $head_branches[$name] = $commit;
- } else {
- $tail_branches[$name] = $commit;
- }
- }
-
- return $head_branches + $tail_branches;
- }
-
-
- /**
- * @task git
- */
- private function executeGitDiscoverCommit(
- PhabricatorRepository $repository,
- $commit,
- $close_immediately) {
-
- $discover = array($commit);
- $insert = array($commit);
-
- $seen_parent = array();
-
- $stream = new PhabricatorGitGraphStream($repository, $commit);
-
- while (true) {
- $target = array_pop($discover);
- $parents = $stream->getParents($target);
- foreach ($parents as $parent) {
- if (isset($seen_parent[$parent])) {
- // We end up in a loop here somehow when we parse Arcanist if we
- // don't do this. TODO: Figure out why and draw a pretty diagram
- // since it's not evident how parsing a DAG with this causes the
- // loop to stop terminating.
- continue;
- }
- $seen_parent[$parent] = true;
- $known = $this->isKnownCommit($repository, $parent);
- if (!$known) {
- $this->log(pht('Discovered commit "%s".', $parent));
- $discover[] = $parent;
- $insert[] = $parent;
- }
- }
- if (empty($discover)) {
- break;
- }
- }
-
- $n = count($insert);
- $this->log(pht('Found %d new commits.', new PhutilNumber($n)));
-
- while (true) {
- $target = array_pop($insert);
- $epoch = $stream->getCommitDate($target);
- $epoch = trim($epoch);
-
- $this->recordCommit($repository, $target, $epoch, $close_immediately);
-
- if (empty($insert)) {
- break;
- }
- }
- }
-
-
- /**
- * Verify that the "origin" remote exists, and points at the correct URI.
- *
- * This catches or corrects some types of misconfiguration, and also repairs
- * an issue where Git 1.7.1 does not create an "origin" for `--bare` clones.
- * See T4041.
- *
- * @param PhabricatorRepository Repository to verify.
- * @return void
- */
- private function verifyOrigin(PhabricatorRepository $repository) {
- list($remotes) = $repository->execxLocalCommand(
- 'remote show -n origin');
-
- $matches = null;
- if (!preg_match('/^\s*Fetch URL:\s*(.*?)\s*$/m', $remotes, $matches)) {
- throw new Exception(
- "Expected 'Fetch URL' in 'git remote show -n origin'.");
- }
-
- $remote_uri = $matches[1];
- $expect_remote = $repository->getRemoteURI();
-
- if ($remote_uri == "origin") {
- // If a remote does not exist, git pretends it does and prints out a
- // made up remote where the URI is the same as the remote name. This is
- // definitely not correct.
-
- // Possibly, we should use `git remote --verbose` instead, which does not
- // suffer from this problem (but is a little more complicated to parse).
- $valid = false;
- $exists = false;
- } else {
- $normal_type_git = PhabricatorRepositoryURINormalizer::TYPE_GIT;
-
- $remote_normal = id(new PhabricatorRepositoryURINormalizer(
- $normal_type_git,
- $remote_uri))->getNormalizedPath();
-
- $expect_normal = id(new PhabricatorRepositoryURINormalizer(
- $normal_type_git,
- $expect_remote))->getNormalizedPath();
-
- $valid = ($remote_normal == $expect_normal);
- $exists = true;
- }
-
- if (!$valid) {
- if (!$exists) {
- // If there's no "origin" remote, just create it regardless of how
- // strongly we own the working copy. There is almost no conceivable
- // scenario in which this could do damage.
- $this->log(
- pht(
- 'Remote "origin" does not exist. Creating "origin", with '.
- 'URI "%s".',
- $expect_remote));
- $repository->execxLocalCommand(
- 'remote add origin %P',
- $repository->getRemoteURIEnvelope());
-
- // NOTE: This doesn't fetch the origin (it just creates it), so we won't
- // know about origin branches until the next "pull" happens. That's fine
- // for our purposes, but might impact things in the future.
- } else {
- if ($repository->canDestroyWorkingCopy()) {
- // Bad remote, but we can try to repair it.
- $this->log(
- pht(
- 'Remote "origin" exists, but is pointed at the wrong URI, "%s". '.
- 'Resetting origin URI to "%s.',
- $remote_uri,
- $expect_remote));
- $repository->execxLocalCommand(
- 'remote set-url origin %P',
- $repository->getRemoteURIEnvelope());
- } else {
- // Bad remote and we aren't comfortable repairing it.
- $message = pht(
- 'Working copy at "%s" has a mismatched origin URI, "%s". '.
- 'The expected origin URI is "%s". Fix your configuration, or '.
- 'set the remote URI correctly. To avoid breaking anything, '.
- 'Phabricator will not automatically fix this.',
- $repository->getLocalPath(),
- $remote_uri,
- $expect_remote);
- throw new Exception($message);
- }
- }
- }
- }
private function pushToMirrors(PhabricatorRepository $repository) {
if (!$repository->canMirror()) {
Index: src/applications/repository/engine/PhabricatorRepositoryCommitRef.php
===================================================================
--- src/applications/repository/engine/PhabricatorRepositoryCommitRef.php
+++ src/applications/repository/engine/PhabricatorRepositoryCommitRef.php
@@ -5,6 +5,7 @@
private $identifier;
private $epoch;
private $branch;
+ private $canCloseImmediately;
public function setIdentifier($identifier) {
$this->identifier = $identifier;
@@ -33,4 +34,13 @@
return $this->branch;
}
+ public function setCanCloseImmediately($can_close_immediately) {
+ $this->canCloseImmediately = $can_close_immediately;
+ return $this;
+ }
+
+ public function getCanCloseImmediately() {
+ return $this->canCloseImmediately;
+ }
+
}
Index: src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php
===================================================================
--- src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php
+++ src/applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php
@@ -43,13 +43,9 @@
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$refs = $this->discoverMercurialCommits();
break;
-/*
- TODO: Implement this!
-
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$refs = $this->discoverGitCommits();
break;
-*/
default:
throw new Exception("Unknown VCS '{$vcs}'!");
}
@@ -63,6 +59,157 @@
}
+/* -( Discovering Git Repositories )--------------------------------------- */
+
+
+ /**
+ * @task git
+ */
+ private function discoverGitCommits() {
+ $repository = $this->getRepository();
+
+ if (!$repository->isHosted()) {
+ $this->verifyGitOrigin($repository);
+ }
+
+ $branches = id(new DiffusionLowLevelGitRefQuery())
+ ->setRepository($repository)
+ ->withIsOriginBranch(true)
+ ->execute();
+
+ if (!$branches) {
+ // This repository has no branches at all, so we don't need to do
+ // anything. Generally, this means the repository is empty.
+ return array();
+ }
+
+ $branches = $this->sortBranches($branches);
+ $branches = mpull($branches, 'getCommitIdentifier', 'getShortName');
+
+ $this->log(
+ pht(
+ 'Discovering commits in repository %s.',
+ $repository->getCallsign()));
+
+ $refs = array();
+ foreach ($branches as $name => $commit) {
+ $this->log(pht('Examining branch "%s", at "%s".', $name, $commit));
+
+ if (!$repository->shouldTrackBranch($name)) {
+ $this->log(pht("Skipping, branch is untracked."));
+ continue;
+ }
+
+ if ($this->isKnownCommit($commit)) {
+ $this->log(pht("Skipping, HEAD is known."));
+ continue;
+ }
+
+ $this->log(pht("Looking for new commits."));
+
+ $refs[] = $this->discoverStreamAncestry(
+ new PhabricatorGitGraphStream($repository, $commit),
+ $commit,
+ $repository->shouldAutocloseBranch($name));
+ }
+
+ return array_mergev($refs);
+ }
+
+
+ /**
+ * Verify that the "origin" remote exists, and points at the correct URI.
+ *
+ * This catches or corrects some types of misconfiguration, and also repairs
+ * an issue where Git 1.7.1 does not create an "origin" for `--bare` clones.
+ * See T4041.
+ *
+ * @param PhabricatorRepository Repository to verify.
+ * @return void
+ */
+ private function verifyGitOrigin(PhabricatorRepository $repository) {
+ list($remotes) = $repository->execxLocalCommand(
+ 'remote show -n origin');
+
+ $matches = null;
+ if (!preg_match('/^\s*Fetch URL:\s*(.*?)\s*$/m', $remotes, $matches)) {
+ throw new Exception(
+ "Expected 'Fetch URL' in 'git remote show -n origin'.");
+ }
+
+ $remote_uri = $matches[1];
+ $expect_remote = $repository->getRemoteURI();
+
+ if ($remote_uri == "origin") {
+ // If a remote does not exist, git pretends it does and prints out a
+ // made up remote where the URI is the same as the remote name. This is
+ // definitely not correct.
+
+ // Possibly, we should use `git remote --verbose` instead, which does not
+ // suffer from this problem (but is a little more complicated to parse).
+ $valid = false;
+ $exists = false;
+ } else {
+ $normal_type_git = PhabricatorRepositoryURINormalizer::TYPE_GIT;
+
+ $remote_normal = id(new PhabricatorRepositoryURINormalizer(
+ $normal_type_git,
+ $remote_uri))->getNormalizedPath();
+
+ $expect_normal = id(new PhabricatorRepositoryURINormalizer(
+ $normal_type_git,
+ $expect_remote))->getNormalizedPath();
+
+ $valid = ($remote_normal == $expect_normal);
+ $exists = true;
+ }
+
+ if (!$valid) {
+ if (!$exists) {
+ // If there's no "origin" remote, just create it regardless of how
+ // strongly we own the working copy. There is almost no conceivable
+ // scenario in which this could do damage.
+ $this->log(
+ pht(
+ 'Remote "origin" does not exist. Creating "origin", with '.
+ 'URI "%s".',
+ $expect_remote));
+ $repository->execxLocalCommand(
+ 'remote add origin %P',
+ $repository->getRemoteURIEnvelope());
+
+ // NOTE: This doesn't fetch the origin (it just creates it), so we won't
+ // know about origin branches until the next "pull" happens. That's fine
+ // for our purposes, but might impact things in the future.
+ } else {
+ if ($repository->canDestroyWorkingCopy()) {
+ // Bad remote, but we can try to repair it.
+ $this->log(
+ pht(
+ 'Remote "origin" exists, but is pointed at the wrong URI, "%s". '.
+ 'Resetting origin URI to "%s.',
+ $remote_uri,
+ $expect_remote));
+ $repository->execxLocalCommand(
+ 'remote set-url origin %P',
+ $repository->getRemoteURIEnvelope());
+ } else {
+ // Bad remote and we aren't comfortable repairing it.
+ $message = pht(
+ 'Working copy at "%s" has a mismatched origin URI, "%s". '.
+ 'The expected origin URI is "%s". Fix your configuration, or '.
+ 'set the remote URI correctly. To avoid breaking anything, '.
+ 'Phabricator will not automatically fix this.',
+ $repository->getLocalPath(),
+ $remote_uri,
+ $expect_remote);
+ throw new Exception($message);
+ }
+ }
+ }
+ }
+
+
/* -( Discovering Subversion Repositories )-------------------------------- */
@@ -108,7 +255,8 @@
$epoch = (int)strtotime((string)$entry->date[0]);
$refs[$identifier] = id(new PhabricatorRepositoryCommitRef())
->setIdentifier($identifier)
- ->setEpoch($epoch);
+ ->setEpoch($epoch)
+ ->setCanCloseImmediately(true);
if ($upper_bound === null) {
$upper_bound = $identifier;
@@ -147,42 +295,49 @@
$branches = id(new DiffusionLowLevelMercurialBranchesQuery())
->setRepository($repository)
->execute();
- $branches = mpull($branches, 'getHeadCommitIdentifier', 'getName');
$refs = array();
- foreach ($branches as $name => $commit) {
- $this->log("Examining branch '{$name}', at {$commit}'.");
+ foreach ($branches as $branch) {
+ // NOTE: Mercurial branches may have multiple heads, so the names may
+ // not be unique.
+ $name = $branch->getShortName();
+ $commit = $branch->getCommitIdentifier();
+
+ $this->log(pht('Examining branch "%s" head "%s".', $name, $commit));
if (!$repository->shouldTrackBranch($name)) {
- $this->log("Skipping, branch is untracked.");
+ $this->log(pht("Skipping, branch is untracked."));
continue;
}
if ($this->isKnownCommit($commit)) {
- $this->log("Skipping, tip is a known commit.");
+ $this->log(pht("Skipping, this head is a known commit."));
continue;
}
- $this->log("Looking for new commits.");
- $refs[] = $this->discoverMercurialAncestry($repository, $commit);
+ $this->log(pht("Looking for new commits."));
+
+ $refs[] = $this->discoverStreamAncestry(
+ new PhabricatorMercurialGraphStream($repository, $commit),
+ $commit,
+ $close_immediately = true);
}
return array_mergev($refs);
}
- /**
- * @task hg
- */
- private function discoverMercurialAncestry(
- PhabricatorRepository $repository,
- $commit) {
+/* -( Internals )---------------------------------------------------------- */
+
+
+ private function discoverStreamAncestry(
+ PhabricatorRepositoryGraphStream $stream,
+ $commit,
+ $close_immediately) {
$discover = array($commit);
$graph = array();
$seen = array();
- $stream = new PhabricatorMercurialGraphStream($repository);
-
// Find all the reachable, undiscovered commits. Build a graph of the
// edges.
while ($discover) {
@@ -214,16 +369,14 @@
foreach ($commits as $commit) {
$refs[] = id(new PhabricatorRepositoryCommitRef())
->setIdentifier($commit)
- ->setEpoch($stream->getCommitDate($commit));
+ ->setEpoch($stream->getCommitDate($commit))
+ ->setCanCloseImmediately($close_immediately);
}
return $refs;
}
-/* -( Internals )---------------------------------------------------------- */
-
-
private function reduceGraph(array $edges) {
foreach ($edges as $commit => $parents) {
$edges[$commit] = array_keys($parents);
@@ -271,4 +424,33 @@
return true;
}
+
+ /**
+ * Sort branches so we process closeable branches first. This makes the
+ * whole import process a little cheaper, since we can close these commits
+ * the first time through rather than catching them in the refs step.
+ *
+ * @task internal
+ *
+ * @param list<DiffusionRepositoryRef> List of branch heads.
+ * @return list<DiffusionRepositoryRef> Sorted list of branch heads.
+ */
+ private function sortBranches(array $branches) {
+ $repository = $this->getRepository();
+
+ $head_branches = array();
+ $tail_branches = array();
+ foreach ($branches as $branch) {
+ $name = $branch->getShortName();
+
+ if ($repository->shouldAutocloseBranch($name)) {
+ $head_branches[] = $branch;
+ } else {
+ $tail_branches[] = $branch;
+ }
+ }
+
+ return array_merge($head_branches, $tail_branches);
+ }
+
}
Index: src/applications/repository/engine/__tests__/PhabricatorWorkingCopyDiscoveryTestCase.php
===================================================================
--- src/applications/repository/engine/__tests__/PhabricatorWorkingCopyDiscoveryTestCase.php
+++ src/applications/repository/engine/__tests__/PhabricatorWorkingCopyDiscoveryTestCase.php
@@ -4,12 +4,7 @@
extends PhabricatorWorkingCopyTestCase {
public function testSubversionCommitDiscovery() {
- $repo = $this->buildPulledRepository('ST');
-
- $engine = id(new PhabricatorRepositoryDiscoveryEngine())
- ->setRepository($repo);
-
- $refs = $engine->discoverCommits($repo);
+ $refs = $this->discoverRefs('ST');
$this->assertEqual(
array(
1368319433,
@@ -17,11 +12,41 @@
),
mpull($refs, 'getEpoch'),
'Commit Epochs');
+ }
- // The next time through, these should be cached as already discovered.
+ public function testMercurialCommitDiscovery() {
+ $refs = $this->discoverRefs('HT');
+ $this->assertEqual(
+ array(
+ '4a110ae879f473f2e82ffd032475caedd6cdba91',
+ ),
+ mpull($refs, 'getIdentifier'));
+ }
+
+ public function testGitCommitDiscovery() {
+ $refs = $this->discoverRefs('GT');
+ $this->assertEqual(
+ array(
+ '763d4ab372445551c95fb5cccd1a7a223f5b2ac8',
+ ),
+ mpull($refs, 'getIdentifier'));
+ }
+
+ private function discoverRefs($callsign) {
+ $repo = $this->buildPulledRepository($callsign);
+
+ $engine = id(new PhabricatorRepositoryDiscoveryEngine())
+ ->setRepository($repo);
$refs = $engine->discoverCommits($repo);
- $this->assertEqual(array(), $refs);
+
+ // The next time through, these should be cached as already discovered.
+
+ $new_refs = $engine->discoverCommits($repo);
+ $this->assertEqual(array(), $new_refs);
+
+ return $refs;
}
+
}

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 21, 6:43 AM (3 d, 21 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7387606
Default Alt Text
D7987.id18088.diff (29 KB)

Event Timeline