From ffb027e85ccfffa37e2eb5bda4282aae994fbad3 Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 30 Jun 2020 12:02:37 -0700 Subject: [PATCH] Support generating remote refs in Git Summary: Ref T13546. Allow construction of remote refs in Git; previously they were only supported in Mercurial. Test Plan: Ran "arc inspect remote(origin)" in Git, got a ref. Maniphest Tasks: T13546 Differential Revision: https://secure.phabricator.com/D21375 --- src/__phutil_library_map__.php | 2 + src/repository/api/ArcanistGitAPI.php | 4 ++ src/repository/api/ArcanistMercurialAPI.php | 1 - .../ArcanistGitRepositoryRemoteQuery.php | 63 +++++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/repository/remote/ArcanistGitRepositoryRemoteQuery.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 1f785647..15bb86ce 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -218,6 +218,7 @@ phutil_register_library_map(array( 'ArcanistGitRawCommit' => 'repository/raw/ArcanistGitRawCommit.php', 'ArcanistGitRawCommitTestCase' => 'repository/raw/__tests__/ArcanistGitRawCommitTestCase.php', 'ArcanistGitRepositoryMarkerQuery' => 'repository/marker/ArcanistGitRepositoryMarkerQuery.php', + 'ArcanistGitRepositoryRemoteQuery' => 'repository/remote/ArcanistGitRepositoryRemoteQuery.php', 'ArcanistGitUpstreamPath' => 'repository/api/ArcanistGitUpstreamPath.php', 'ArcanistGitWorkEngine' => 'work/ArcanistGitWorkEngine.php', 'ArcanistGitWorkingCopy' => 'workingcopy/ArcanistGitWorkingCopy.php', @@ -1246,6 +1247,7 @@ phutil_register_library_map(array( 'ArcanistGitRawCommit' => 'Phobject', 'ArcanistGitRawCommitTestCase' => 'PhutilTestCase', 'ArcanistGitRepositoryMarkerQuery' => 'ArcanistRepositoryMarkerQuery', + 'ArcanistGitRepositoryRemoteQuery' => 'ArcanistRepositoryRemoteQuery', 'ArcanistGitUpstreamPath' => 'Phobject', 'ArcanistGitWorkEngine' => 'ArcanistWorkEngine', 'ArcanistGitWorkingCopy' => 'ArcanistWorkingCopy', diff --git a/src/repository/api/ArcanistGitAPI.php b/src/repository/api/ArcanistGitAPI.php index c65257f4..ebd2d1d9 100644 --- a/src/repository/api/ArcanistGitAPI.php +++ b/src/repository/api/ArcanistGitAPI.php @@ -1763,4 +1763,8 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI { return new ArcanistGitRepositoryMarkerQuery(); } + protected function newRemoteRefQueryTemplate() { + return new ArcanistGitRepositoryRemoteQuery(); + } + } diff --git a/src/repository/api/ArcanistMercurialAPI.php b/src/repository/api/ArcanistMercurialAPI.php index e606f6a1..fdb5e1e0 100644 --- a/src/repository/api/ArcanistMercurialAPI.php +++ b/src/repository/api/ArcanistMercurialAPI.php @@ -1014,7 +1014,6 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI { return new ArcanistMercurialRepositoryRemoteQuery(); } - public function getMercurialExtensionArguments() { $path = phutil_get_library_root('arcanist'); $path = dirname($path); diff --git a/src/repository/remote/ArcanistGitRepositoryRemoteQuery.php b/src/repository/remote/ArcanistGitRepositoryRemoteQuery.php new file mode 100644 index 00000000..47b914e9 --- /dev/null +++ b/src/repository/remote/ArcanistGitRepositoryRemoteQuery.php @@ -0,0 +1,63 @@ +getRepositoryAPI(); + + $future = $api->newFuture('remote --verbose'); + list($lines) = $future->resolve(); + + $pattern = + '(^'. + '(?P[^\t]+)'. + '\t'. + '(?P[^\s]+)'. + ' '. + '\((?Pfetch|push)\)'. + '\z'. + ')'; + + $map = array(); + + $lines = phutil_split_lines($lines, false); + foreach ($lines as $line) { + $matches = null; + if (!preg_match($pattern, $line, $matches)) { + throw new Exception( + pht( + 'Failed to match remote pattern against line "%s".', + $line)); + } + + $name = $matches['name']; + $uri = $matches['uri']; + $mode = $matches['mode']; + + $map[$name][$mode] = $uri; + } + + $refs = array(); + foreach ($map as $name => $uris) { + $fetch_uri = idx($uris, 'fetch'); + $push_uri = idx($uris, 'push'); + + $ref = id(new ArcanistRemoteRef()) + ->setRemoteName($name); + + if ($fetch_uri !== null) { + $ref->setFetchURI($fetch_uri); + } + + if ($push_uri !== null) { + $ref->setPushURI($push_uri); + } + + $refs[] = $ref; + } + + return $refs; + } + +}