Page MenuHomePhabricator

D14360.diff
No OneTemporary

D14360.diff

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
@@ -113,6 +113,7 @@
'ArcanistGetConfigWorkflow' => 'workflow/ArcanistGetConfigWorkflow.php',
'ArcanistGitAPI' => 'repository/api/ArcanistGitAPI.php',
'ArcanistGitLandEngine' => 'land/ArcanistGitLandEngine.php',
+ 'ArcanistGitUpstreamPath' => 'repository/api/ArcanistGitUpstreamPath.php',
'ArcanistGlobalVariableXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistGlobalVariableXHPASTLinterRule.php',
'ArcanistGoLintLinter' => 'lint/linter/ArcanistGoLintLinter.php',
'ArcanistGoLintLinterTestCase' => 'lint/linter/__tests__/ArcanistGoLintLinterTestCase.php',
@@ -401,6 +402,7 @@
'ArcanistGetConfigWorkflow' => 'ArcanistWorkflow',
'ArcanistGitAPI' => 'ArcanistRepositoryAPI',
'ArcanistGitLandEngine' => 'ArcanistLandEngine',
+ 'ArcanistGitUpstreamPath' => 'Phobject',
'ArcanistGlobalVariableXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistGoLintLinter' => 'ArcanistExternalLinter',
'ArcanistGoLintLinterTestCase' => 'ArcanistExternalLinterTestCase',
diff --git a/src/repository/api/ArcanistGitAPI.php b/src/repository/api/ArcanistGitAPI.php
--- a/src/repository/api/ArcanistGitAPI.php
+++ b/src/repository/api/ArcanistGitAPI.php
@@ -1342,7 +1342,7 @@
*/
public function getPathToUpstream($start) {
$cursor = $start;
- $path = array();
+ $path = new ArcanistGitUpstreamPath();
while (true) {
list($err, $upstream) = $this->execManualLocal(
'rev-parse --symbolic-full-name %s@{upstream}',
@@ -1358,13 +1358,15 @@
if (preg_match('(^refs/heads/)', $upstream)) {
$upstream = preg_replace('(^refs/heads/)', '', $upstream);
- $is_cycle = isset($path[$upstream]);
+ $is_cycle = $path->getUpstream($upstream);
- $path[$cursor] = array(
- 'type' => 'local',
- 'name' => $upstream,
- 'cycle' => $is_cycle,
- );
+ $path->addUpstream(
+ $cursor,
+ array(
+ 'type' => ArcanistGitUpstreamPath::TYPE_LOCAL,
+ 'name' => $upstream,
+ 'cycle' => $is_cycle,
+ ));
if ($is_cycle) {
// We ran into a local cycle, so we're done.
@@ -1380,11 +1382,13 @@
$upstream = preg_replace('(^refs/remotes/)', '', $upstream);
list($remote, $branch) = explode('/', $upstream, 2);
- $path[$cursor] = array(
- 'type' => 'remote',
- 'name' => $branch,
- 'remote' => $remote,
- );
+ $path->addUpstream(
+ $cursor,
+ array(
+ 'type' => ArcanistGitUpstreamPath::TYPE_REMOTE,
+ 'name' => $branch,
+ 'remote' => $remote,
+ ));
// We found a remote, so we're done.
break;
diff --git a/src/repository/api/ArcanistGitUpstreamPath.php b/src/repository/api/ArcanistGitUpstreamPath.php
new file mode 100644
--- /dev/null
+++ b/src/repository/api/ArcanistGitUpstreamPath.php
@@ -0,0 +1,82 @@
+<?php
+
+final class ArcanistGitUpstreamPath extends Phobject {
+
+ private $path = array();
+
+ const TYPE_LOCAL = 'local';
+ const TYPE_REMOTE = 'remote';
+
+
+ public function addUpstream($key, array $spec) {
+ $this->path[$key] = $spec;
+ return $this;
+ }
+
+ public function getUpstream($key) {
+ return idx($this->path, $key);
+ }
+
+ public function getLength() {
+ return count($this->path);
+ }
+
+ /**
+ * Test if this path eventually connects to a remote.
+ *
+ * @return bool True if the path connects to a remote.
+ */
+ public function isConnectedToRemote() {
+ $last = last($this->path);
+
+ if (!$last) {
+ return false;
+ }
+
+ return ($last['type'] == self::TYPE_REMOTE);
+ }
+
+
+ public function getRemoteBranchName() {
+ if (!$this->isConnectedToRemote()) {
+ return null;
+ }
+
+ return idx(last($this->path), 'name');
+ }
+
+ public function getRemoteRemoteName() {
+ if (!$this->isConnectedToRemote()) {
+ return null;
+ }
+
+ return idx(last($this->path), 'remote');
+ }
+
+
+ /**
+ * If this path contains a cycle, return a description of it.
+ *
+ * @return list<string>|null Cycle, if the path contains one.
+ */
+ public function getCycle() {
+ $last = last($this->path);
+ if (!$last) {
+ return null;
+ }
+
+ if (empty($last['cycle'])) {
+ return null;
+ }
+
+ $parts = array();
+ foreach ($this->path as $key => $item) {
+ $parts[] = $key;
+ }
+ $parts[] = $item['name'];
+ $parts[] = pht('...');
+
+ return $parts;
+ }
+
+}
diff --git a/src/workflow/ArcanistLandWorkflow.php b/src/workflow/ArcanistLandWorkflow.php
--- a/src/workflow/ArcanistLandWorkflow.php
+++ b/src/workflow/ArcanistLandWorkflow.php
@@ -386,9 +386,9 @@
$api = $this->getRepositoryAPI();
$path = $api->getPathToUpstream($this->branch);
- if ($path) {
- $last = last($path);
- if (isset($last['cycle'])) {
+ if ($path->getLength()) {
+ $cycle = $path->getCycle();
+ if ($cycle) {
$this->writeWarn(
pht('LOCAL CYCLE'),
pht(
@@ -397,11 +397,11 @@
echo tsprintf(
"\n %s\n\n",
- $this->formatUpstreamPathCycle($path));
+ implode(' -> ', $cycle));
} else {
- if ($last['type'] == 'remote') {
- $onto = $last['name'];
+ if ($path->isConnectedToRemote()) {
+ $onto = $path->getRemoteBranchName();
$this->writeInfo(
pht('TARGET'),
pht(
@@ -454,18 +454,15 @@
$api = $this->getRepositoryAPI();
$path = $api->getPathToUpstream($this->branch);
- if ($path) {
- $last = last($path);
- if ($last['type'] == 'remote') {
- $remote = $last['remote'];
- $this->writeInfo(
- pht('REMOTE'),
- pht(
- 'Using remote "%s", selected by following tracking branches '.
- 'upstream to the closest remote.',
- $remote));
- return $remote;
- }
+ $remote = $path->getRemoteRemoteName();
+ if ($remote !== null) {
+ $this->writeInfo(
+ pht('REMOTE'),
+ pht(
+ 'Using remote "%s", selected by following tracking branches '.
+ 'upstream to the closest remote.',
+ $remote));
+ return $remote;
}
$remote = 'origin';
@@ -477,17 +474,6 @@
return $remote;
}
- private function formatUpstreamPathCycle(array $cycle) {
- $parts = array();
- foreach ($cycle as $key => $value) {
- $parts[] = $key;
- }
- $parts[] = idx(last($cycle), 'name');
- $parts[] = pht('...');
-
- return implode(' -> ', $parts);
- }
-
private function readArguments() {
$repository_api = $this->getRepositoryAPI();

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 19, 4:45 PM (4 d, 9 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7691753
Default Alt Text
D14360.diff (6 KB)

Event Timeline