Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15187398
D16129.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
16 KB
Referenced Files
None
Subscribers
None
D16129.id.diff
View Options
diff --git a/src/applications/diffusion/data/DiffusionRepositoryRef.php b/src/applications/diffusion/data/DiffusionRepositoryRef.php
--- a/src/applications/diffusion/data/DiffusionRepositoryRef.php
+++ b/src/applications/diffusion/data/DiffusionRepositoryRef.php
@@ -7,6 +7,7 @@
private $shortName;
private $commitIdentifier;
+ private $refType;
private $rawFields = array();
public function setRawFields(array $raw_fields) {
@@ -36,6 +37,20 @@
return $this->shortName;
}
+ public function setRefType($ref_type) {
+ $this->refType = $ref_type;
+ return $this;
+ }
+
+ public function getRefType() {
+ return $this->refType;
+ }
+
+ public function isBranch() {
+ $type_branch = PhabricatorRepositoryRefCursor::TYPE_BRANCH;
+ return ($this->getRefType() === $type_branch);
+ }
+
/* -( Serialization )------------------------------------------------------ */
@@ -44,6 +59,7 @@
return array(
'shortName' => $this->shortName,
'commitIdentifier' => $this->commitIdentifier,
+ 'refType' => $this->refType,
'rawFields' => $this->rawFields,
);
}
@@ -52,6 +68,7 @@
return id(new DiffusionRepositoryRef())
->setShortName($dict['shortName'])
->setCommitIdentifier($dict['commitIdentifier'])
+ ->setRefType($dict['refType'])
->setRawFields($dict['rawFields']);
}
diff --git a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php
--- a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php
+++ b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php
@@ -14,96 +14,112 @@
}
protected function executeQuery() {
+ $type_branch = PhabricatorRepositoryRefCursor::TYPE_BRANCH;
+ $type_tag = PhabricatorRepositoryRefCursor::TYPE_TAG;
+ $type_ref = PhabricatorRepositoryRefCursor::TYPE_REF;
+
$ref_types = $this->refTypes;
- if ($ref_types) {
- $type_branch = PhabricatorRepositoryRefCursor::TYPE_BRANCH;
- $type_tag = PhabricatorRepositoryRefCursor::TYPE_TAG;
+ if (!$ref_types) {
+ $ref_types = array($type_branch, $type_tag, $type_ref);
+ }
- $ref_types = array_fuse($ref_types);
+ $ref_types = array_fuse($ref_types);
- $with_branches = isset($ref_types[$type_branch]);
- $with_tags = isset($ref_types[$type_tag]);
- } else {
- $with_branches = true;
- $with_tags = true;
- }
+ $with_branches = isset($ref_types[$type_branch]);
+ $with_tags = isset($ref_types[$type_tag]);
+ $with_refs = isset($refs_types[$type_ref]);
$repository = $this->getRepository();
$prefixes = array();
- if ($with_branches) {
- if ($repository->isWorkingCopyBare()) {
- $prefix = 'refs/heads/';
- } else {
- $remote = DiffusionGitBranch::DEFAULT_GIT_REMOTE;
- $prefix = 'refs/remotes/'.$remote.'/';
- }
- $prefixes[] = $prefix;
+ if ($repository->isWorkingCopyBare()) {
+ $branch_prefix = 'refs/heads/';
+ } else {
+ $remote = DiffusionGitBranch::DEFAULT_GIT_REMOTE;
+ $branch_prefix = 'refs/remotes/'.$remote.'/';
}
- if ($with_tags) {
- $prefixes[] = 'refs/tags/';
- }
+ $tag_prefix = 'refs/tags/';
- $order = '-creatordate';
- $futures = array();
- foreach ($prefixes as $prefix) {
- $futures[$prefix] = $repository->getLocalCommandFuture(
- 'for-each-ref --sort=%s --format=%s %s',
- $order,
- $this->getFormatString(),
- $prefix);
+ if ($with_refs || count($ref_types) > 1) {
+ // If we're loading refs or more than one type of ref, just query
+ // everything.
+ $prefix = 'refs/';
+ } else {
+ if ($with_branches) {
+ $prefix = $branch_prefix;
+ }
+ if ($with_tags) {
+ $prefix = $tag_prefix;
+ }
}
- // Resolve all the futures first. We want to iterate over them in prefix
- // order, not resolution order.
- foreach (new FutureIterator($futures) as $prefix => $future) {
- $future->resolvex();
+ $branch_len = strlen($branch_prefix);
+ $tag_len = strlen($tag_prefix);
+
+ list($stdout) = $repository->execxLocalCommand(
+ 'for-each-ref --sort=%s --format=%s -- %s',
+ '-creatordate',
+ $this->getFormatString(),
+ $prefix);
+
+ $stdout = rtrim($stdout);
+ if (!strlen($stdout)) {
+ return array();
}
+ // NOTE: Although git supports --count, we can't apply any offset or
+ // limit logic until the very end because we may encounter a HEAD which
+ // we want to discard.
+
+ $lines = explode("\n", $stdout);
$results = array();
- foreach ($futures as $prefix => $future) {
- list($stdout) = $future->resolvex();
+ foreach ($lines as $line) {
+ $fields = $this->extractFields($line);
+
+ $refname = $fields['refname'];
+ if (!strncmp($refname, $branch_prefix, $branch_len)) {
+ $short = substr($refname, $branch_len);
+ $type = $type_branch;
+ } else if (!strncmp($refname, $tag_prefix, $tag_len)) {
+ $short = substr($refname, $tag_len);
+ $type = $type_tag;
+ } else {
+ $short = $refname;
+ $type = $type_ref;
+ }
- $stdout = rtrim($stdout);
- if (!strlen($stdout)) {
+ // If this isn't a type of ref we care about, skip it.
+ if (empty($ref_types[$type])) {
continue;
}
- // NOTE: Although git supports --count, we can't apply any offset or
- // limit logic until the very end because we may encounter a HEAD which
- // we want to discard.
-
- $lines = explode("\n", $stdout);
- foreach ($lines as $line) {
- $fields = $this->extractFields($line);
-
- $creator = $fields['creator'];
- $matches = null;
- if (preg_match('/^(.*) ([0-9]+) ([0-9+-]+)$/', $creator, $matches)) {
- $fields['author'] = $matches[1];
- $fields['epoch'] = (int)$matches[2];
- } else {
- $fields['author'] = null;
- $fields['epoch'] = null;
- }
-
- $commit = nonempty($fields['*objectname'], $fields['objectname']);
-
- $short = substr($fields['refname'], strlen($prefix));
- if ($short == 'HEAD') {
- continue;
- }
-
- $ref = id(new DiffusionRepositoryRef())
- ->setShortName($short)
- ->setCommitIdentifier($commit)
- ->setRawFields($fields);
-
- $results[] = $ref;
+ // If this is the local HEAD, skip it.
+ if ($short == 'HEAD') {
+ continue;
}
+
+ $creator = $fields['creator'];
+ $matches = null;
+ if (preg_match('/^(.*) ([0-9]+) ([0-9+-]+)$/', $creator, $matches)) {
+ $fields['author'] = $matches[1];
+ $fields['epoch'] = (int)$matches[2];
+ } else {
+ $fields['author'] = null;
+ $fields['epoch'] = null;
+ }
+
+ $commit = nonempty($fields['*objectname'], $fields['objectname']);
+
+ $ref = id(new DiffusionRepositoryRef())
+ ->setRefType($type)
+ ->setShortName($short)
+ ->setCommitIdentifier($commit)
+ ->setRawFields($fields);
+
+ $results[] = $ref;
}
return $results;
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
@@ -130,39 +130,35 @@
$this->verifyGitOrigin($repository);
}
- // TODO: This should also import tags, but some of the logic is still
- // branch-specific today.
-
- $branches = id(new DiffusionLowLevelGitRefQuery())
+ $heads = id(new DiffusionLowLevelGitRefQuery())
->setRepository($repository)
- ->withRefTypes(
- array(
- PhabricatorRepositoryRefCursor::TYPE_BRANCH,
- ))
->execute();
- if (!$branches) {
- // This repository has no branches at all, so we don't need to do
+ if (!$heads) {
+ // This repository has no heads 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');
+ $heads = $this->sortRefs($heads);
+ $head_commits = mpull($heads, 'getCommitIdentifier');
$this->log(
pht(
'Discovering commits in repository "%s".',
$repository->getDisplayName()));
- $this->fillCommitCache(array_values($branches));
+ $this->fillCommitCache($head_commits);
$refs = array();
- foreach ($branches as $name => $commit) {
- $this->log(pht('Examining branch "%s", at "%s".', $name, $commit));
+ foreach ($heads as $ref) {
+ $name = $ref->getShortName();
+ $commit = $ref->getCommitIdentifier();
- if (!$repository->shouldTrackBranch($name)) {
- $this->log(pht('Skipping, branch is untracked.'));
+ $this->log(pht('Examining ref "%s", at "%s".', $name, $commit));
+
+ if (!$repository->shouldTrackRef($ref)) {
+ $this->log(pht('Skipping, ref is untracked.'));
continue;
}
@@ -173,14 +169,14 @@
$this->log(pht('Looking for new commits.'));
- $branch_refs = $this->discoverStreamAncestry(
+ $head_refs = $this->discoverStreamAncestry(
new PhabricatorGitGraphStream($repository, $commit),
$commit,
- $repository->shouldAutocloseBranch($name));
+ $repository->shouldAutocloseRef($ref));
- $this->didDiscoverRefs($branch_refs);
+ $this->didDiscoverRefs($head_refs);
- $refs[] = $branch_refs;
+ $refs[] = $head_refs;
}
return array_mergev($refs);
@@ -469,25 +465,23 @@
*
* @task internal
*
- * @param list<DiffusionRepositoryRef> List of branch heads.
- * @return list<DiffusionRepositoryRef> Sorted list of branch heads.
+ * @param list<DiffusionRepositoryRef> List of refs.
+ * @return list<DiffusionRepositoryRef> Sorted list of refs.
*/
- private function sortBranches(array $branches) {
+ private function sortRefs(array $refs) {
$repository = $this->getRepository();
- $head_branches = array();
- $tail_branches = array();
- foreach ($branches as $branch) {
- $name = $branch->getShortName();
-
- if ($repository->shouldAutocloseBranch($name)) {
- $head_branches[] = $branch;
+ $head_refs = array();
+ $tail_refs = array();
+ foreach ($refs as $ref) {
+ if ($repository->shouldAutocloseRef($ref)) {
+ $head_refs[] = $ref;
} else {
- $tail_branches[] = $branch;
+ $tail_refs[] = $ref;
}
}
- return array_merge($head_branches, $tail_branches);
+ return array_merge($head_refs, $tail_refs);
}
diff --git a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
--- a/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
+++ b/src/applications/repository/engine/PhabricatorRepositoryPullEngine.php
@@ -347,7 +347,7 @@
// For bare working copies, we need this magic incantation.
$future = $repository->getRemoteCommandFuture(
'fetch origin %s --prune',
- '+refs/heads/*:refs/heads/*');
+ '+refs/*:refs/*');
} else {
$future = $repository->getRemoteCommandFuture(
'fetch --all --prune');
diff --git a/src/applications/repository/engine/PhabricatorRepositoryRefEngine.php b/src/applications/repository/engine/PhabricatorRepositoryRefEngine.php
--- a/src/applications/repository/engine/PhabricatorRepositoryRefEngine.php
+++ b/src/applications/repository/engine/PhabricatorRepositoryRefEngine.php
@@ -25,29 +25,31 @@
switch ($vcs) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
// No meaningful refs of any type in Subversion.
- $branches = array();
- $bookmarks = array();
- $tags = array();
+ $maps = array();
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$branches = $this->loadMercurialBranchPositions($repository);
$bookmarks = $this->loadMercurialBookmarkPositions($repository);
- $tags = array();
+ $maps = array(
+ PhabricatorRepositoryRefCursor::TYPE_BRANCH => $branches,
+ PhabricatorRepositoryRefCursor::TYPE_BOOKMARK => $bookmarks,
+ );
+
$branches_may_close = true;
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
- $branches = $this->loadGitBranchPositions($repository);
- $bookmarks = array();
- $tags = $this->loadGitTagPositions($repository);
+ $maps = $this->loadGitRefPositions($repository);
break;
default:
throw new Exception(pht('Unknown VCS "%s"!', $vcs));
}
- $maps = array(
- PhabricatorRepositoryRefCursor::TYPE_BRANCH => $branches,
- PhabricatorRepositoryRefCursor::TYPE_TAG => $tags,
- PhabricatorRepositoryRefCursor::TYPE_BOOKMARK => $bookmarks,
+ // Fill in any missing types with empty lists.
+ $maps = $maps + array(
+ PhabricatorRepositoryRefCursor::TYPE_BRANCH => array(),
+ PhabricatorRepositoryRefCursor::TYPE_TAG => array(),
+ PhabricatorRepositoryRefCursor::TYPE_BOOKMARK => array(),
+ PhabricatorRepositoryRefCursor::TYPE_REF => array(),
);
$all_cursors = id(new PhabricatorRepositoryRefCursorQuery())
@@ -91,6 +93,7 @@
$this->deadRefs = array();
}
+ $branches = $maps[PhabricatorRepositoryRefCursor::TYPE_BRANCH];
if ($branches && $branches_may_close) {
$this->updateBranchStates($repository, $branches);
}
@@ -449,28 +452,12 @@
/**
* @task git
*/
- private function loadGitBranchPositions(PhabricatorRepository $repository) {
- return id(new DiffusionLowLevelGitRefQuery())
+ private function loadGitRefPositions(PhabricatorRepository $repository) {
+ $refs = id(new DiffusionLowLevelGitRefQuery())
->setRepository($repository)
- ->withRefTypes(
- array(
- PhabricatorRepositoryRefCursor::TYPE_BRANCH,
- ))
->execute();
- }
-
- /**
- * @task git
- */
- private function loadGitTagPositions(PhabricatorRepository $repository) {
- return id(new DiffusionLowLevelGitRefQuery())
- ->setRepository($repository)
- ->withRefTypes(
- array(
- PhabricatorRepositoryRefCursor::TYPE_TAG,
- ))
- ->execute();
+ return mgroup($refs, 'getRefType');
}
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
@@ -910,6 +910,14 @@
return null;
}
+ public function shouldTrackRef(DiffusionRepositoryRef $ref) {
+ if (!$ref->isBranch()) {
+ return true;
+ }
+
+ return $this->shouldTrackBranch($ref->getShortName());
+ }
+
public function shouldTrackBranch($branch) {
return $this->isBranchInFilter($branch, 'branch-filter');
}
@@ -1020,6 +1028,14 @@
/* -( Autoclose )---------------------------------------------------------- */
+ public function shouldAutocloseRef(DiffusionRepositoryRef $ref) {
+ if (!$ref->isBranch()) {
+ return false;
+ }
+
+ return $this->shouldAutocloseBranch($ref->getShortName());
+ }
+
/**
* Determine if autoclose is active for a branch.
*
diff --git a/src/applications/repository/storage/PhabricatorRepositoryRefCursor.php b/src/applications/repository/storage/PhabricatorRepositoryRefCursor.php
--- a/src/applications/repository/storage/PhabricatorRepositoryRefCursor.php
+++ b/src/applications/repository/storage/PhabricatorRepositoryRefCursor.php
@@ -12,6 +12,7 @@
const TYPE_BRANCH = 'branch';
const TYPE_TAG = 'tag';
const TYPE_BOOKMARK = 'bookmark';
+ const TYPE_REF = 'ref';
protected $repositoryPHID;
protected $refType;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Feb 22, 8:42 AM (4 h, 51 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7180082
Default Alt Text
D16129.id.diff (16 KB)
Attached To
Mode
D16129: Fetch and discover all Git ref types, not just branches
Attached
Detach File
Event Timeline
Log In to Comment