Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15415570
D7987.id18088.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
29 KB
Referenced Files
None
Subscribers
None
D7987.id18088.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D7987: Move Git discovery into DiscoveryEngine
Attached
Detach File
Event Timeline
Log In to Comment