mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-22 06:42:41 +01:00
Remove "arc feature", "arc branch", "arc bookmark", and significant chunks of obsolete marker code
Summary: Ref T13546. Moves away from the older workflows in favor of "arc branches", "arc bookmarks", and "arc work". Test Plan: Grepped for affected symbols, didn't find any callers. Maniphest Tasks: T13546 Differential Revision: https://secure.phabricator.com/D21337
This commit is contained in:
parent
3d64140ff3
commit
b003cf9310
10 changed files with 12 additions and 581 deletions
|
@ -49,12 +49,10 @@ phutil_register_library_map(array(
|
||||||
'ArcanistBlacklistedFunctionXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistBlacklistedFunctionXHPASTLinterRule.php',
|
'ArcanistBlacklistedFunctionXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistBlacklistedFunctionXHPASTLinterRule.php',
|
||||||
'ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase.php',
|
'ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase.php',
|
||||||
'ArcanistBlindlyTrustHTTPEngineExtension' => 'configuration/ArcanistBlindlyTrustHTTPEngineExtension.php',
|
'ArcanistBlindlyTrustHTTPEngineExtension' => 'configuration/ArcanistBlindlyTrustHTTPEngineExtension.php',
|
||||||
'ArcanistBookmarkWorkflow' => 'workflow/ArcanistBookmarkWorkflow.php',
|
|
||||||
'ArcanistBookmarksWorkflow' => 'workflow/ArcanistBookmarksWorkflow.php',
|
'ArcanistBookmarksWorkflow' => 'workflow/ArcanistBookmarksWorkflow.php',
|
||||||
'ArcanistBoolConfigOption' => 'config/option/ArcanistBoolConfigOption.php',
|
'ArcanistBoolConfigOption' => 'config/option/ArcanistBoolConfigOption.php',
|
||||||
'ArcanistBraceFormattingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistBraceFormattingXHPASTLinterRule.php',
|
'ArcanistBraceFormattingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistBraceFormattingXHPASTLinterRule.php',
|
||||||
'ArcanistBraceFormattingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistBraceFormattingXHPASTLinterRuleTestCase.php',
|
'ArcanistBraceFormattingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistBraceFormattingXHPASTLinterRuleTestCase.php',
|
||||||
'ArcanistBranchWorkflow' => 'workflow/ArcanistBranchWorkflow.php',
|
|
||||||
'ArcanistBranchesWorkflow' => 'workflow/ArcanistBranchesWorkflow.php',
|
'ArcanistBranchesWorkflow' => 'workflow/ArcanistBranchesWorkflow.php',
|
||||||
'ArcanistBrowseCommitHardpointQuery' => 'browse/query/ArcanistBrowseCommitHardpointQuery.php',
|
'ArcanistBrowseCommitHardpointQuery' => 'browse/query/ArcanistBrowseCommitHardpointQuery.php',
|
||||||
'ArcanistBrowseCommitURIHardpointQuery' => 'browse/query/ArcanistBrowseCommitURIHardpointQuery.php',
|
'ArcanistBrowseCommitURIHardpointQuery' => 'browse/query/ArcanistBrowseCommitURIHardpointQuery.php',
|
||||||
|
@ -194,8 +192,6 @@ phutil_register_library_map(array(
|
||||||
'ArcanistExternalLinterTestCase' => 'lint/linter/__tests__/ArcanistExternalLinterTestCase.php',
|
'ArcanistExternalLinterTestCase' => 'lint/linter/__tests__/ArcanistExternalLinterTestCase.php',
|
||||||
'ArcanistExtractUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistExtractUseXHPASTLinterRule.php',
|
'ArcanistExtractUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistExtractUseXHPASTLinterRule.php',
|
||||||
'ArcanistExtractUseXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistExtractUseXHPASTLinterRuleTestCase.php',
|
'ArcanistExtractUseXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistExtractUseXHPASTLinterRuleTestCase.php',
|
||||||
'ArcanistFeatureBaseWorkflow' => 'workflow/ArcanistFeatureBaseWorkflow.php',
|
|
||||||
'ArcanistFeatureWorkflow' => 'workflow/ArcanistFeatureWorkflow.php',
|
|
||||||
'ArcanistFileConfigurationSource' => 'config/source/ArcanistFileConfigurationSource.php',
|
'ArcanistFileConfigurationSource' => 'config/source/ArcanistFileConfigurationSource.php',
|
||||||
'ArcanistFileDataRef' => 'upload/ArcanistFileDataRef.php',
|
'ArcanistFileDataRef' => 'upload/ArcanistFileDataRef.php',
|
||||||
'ArcanistFileRef' => 'ref/file/ArcanistFileRef.php',
|
'ArcanistFileRef' => 'ref/file/ArcanistFileRef.php',
|
||||||
|
@ -1068,12 +1064,10 @@ phutil_register_library_map(array(
|
||||||
'ArcanistBlacklistedFunctionXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
'ArcanistBlacklistedFunctionXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
'ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
'ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||||
'ArcanistBlindlyTrustHTTPEngineExtension' => 'PhutilHTTPEngineExtension',
|
'ArcanistBlindlyTrustHTTPEngineExtension' => 'PhutilHTTPEngineExtension',
|
||||||
'ArcanistBookmarkWorkflow' => 'ArcanistFeatureBaseWorkflow',
|
|
||||||
'ArcanistBookmarksWorkflow' => 'ArcanistMarkersWorkflow',
|
'ArcanistBookmarksWorkflow' => 'ArcanistMarkersWorkflow',
|
||||||
'ArcanistBoolConfigOption' => 'ArcanistSingleSourceConfigOption',
|
'ArcanistBoolConfigOption' => 'ArcanistSingleSourceConfigOption',
|
||||||
'ArcanistBraceFormattingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
'ArcanistBraceFormattingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
'ArcanistBraceFormattingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
'ArcanistBraceFormattingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||||
'ArcanistBranchWorkflow' => 'ArcanistFeatureBaseWorkflow',
|
|
||||||
'ArcanistBranchesWorkflow' => 'ArcanistMarkersWorkflow',
|
'ArcanistBranchesWorkflow' => 'ArcanistMarkersWorkflow',
|
||||||
'ArcanistBrowseCommitHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
|
'ArcanistBrowseCommitHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
|
||||||
'ArcanistBrowseCommitURIHardpointQuery' => 'ArcanistBrowseURIHardpointQuery',
|
'ArcanistBrowseCommitURIHardpointQuery' => 'ArcanistBrowseURIHardpointQuery',
|
||||||
|
@ -1224,8 +1218,6 @@ phutil_register_library_map(array(
|
||||||
'ArcanistExternalLinterTestCase' => 'ArcanistLinterTestCase',
|
'ArcanistExternalLinterTestCase' => 'ArcanistLinterTestCase',
|
||||||
'ArcanistExtractUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
'ArcanistExtractUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
'ArcanistExtractUseXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
'ArcanistExtractUseXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||||
'ArcanistFeatureBaseWorkflow' => 'ArcanistArcWorkflow',
|
|
||||||
'ArcanistFeatureWorkflow' => 'ArcanistFeatureBaseWorkflow',
|
|
||||||
'ArcanistFileConfigurationSource' => 'ArcanistFilesystemConfigurationSource',
|
'ArcanistFileConfigurationSource' => 'ArcanistFilesystemConfigurationSource',
|
||||||
'ArcanistFileDataRef' => 'Phobject',
|
'ArcanistFileDataRef' => 'Phobject',
|
||||||
'ArcanistFileRef' => array(
|
'ArcanistFileRef' => array(
|
||||||
|
|
|
@ -22,14 +22,6 @@ final class ArcanistArcConfigurationEngineExtension
|
||||||
'default' => array(),
|
'default' => array(),
|
||||||
'example' => '["/var/arc/customlib/src"]',
|
'example' => '["/var/arc/customlib/src"]',
|
||||||
),
|
),
|
||||||
|
|
||||||
'arc.feature.start.default' => array(
|
|
||||||
'type' => 'string',
|
|
||||||
'help' => pht(
|
|
||||||
'The name of the default branch to create the new feature branch '.
|
|
||||||
'off of.'),
|
|
||||||
'example' => '"develop"',
|
|
||||||
),
|
|
||||||
'editor' => array(
|
'editor' => array(
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'help' => pht(
|
'help' => pht(
|
||||||
|
|
|
@ -65,13 +65,6 @@ final class ArcanistSettings extends Phobject {
|
||||||
'engine is specified by the current project.'),
|
'engine is specified by the current project.'),
|
||||||
'example' => '"ExampleUnitTestEngine"',
|
'example' => '"ExampleUnitTestEngine"',
|
||||||
),
|
),
|
||||||
'arc.feature.start.default' => array(
|
|
||||||
'type' => 'string',
|
|
||||||
'help' => pht(
|
|
||||||
'The name of the default branch to create the new feature branch '.
|
|
||||||
'off of.'),
|
|
||||||
'example' => '"develop"',
|
|
||||||
),
|
|
||||||
'arc.land.onto.default' => array(
|
'arc.land.onto.default' => array(
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'help' => pht(
|
'help' => pht(
|
||||||
|
|
|
@ -597,16 +597,16 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
||||||
|
|
||||||
public function getCanonicalRevisionName($string) {
|
public function getCanonicalRevisionName($string) {
|
||||||
$match = null;
|
$match = null;
|
||||||
|
|
||||||
if (preg_match('/@([0-9]+)$/', $string, $match)) {
|
if (preg_match('/@([0-9]+)$/', $string, $match)) {
|
||||||
$stdout = $this->getHashFromFromSVNRevisionNumber($match[1]);
|
$stdout = $this->getHashFromFromSVNRevisionNumber($match[1]);
|
||||||
} else {
|
} else {
|
||||||
list($stdout) = $this->execxLocal(
|
list($stdout) = $this->execxLocal(
|
||||||
phutil_is_windows()
|
'show -s --format=%s %s --',
|
||||||
? 'show -s --format=%C %s --'
|
|
||||||
: 'show -s --format=%s %s --',
|
|
||||||
'%H',
|
'%H',
|
||||||
$string);
|
$string);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rtrim($stdout);
|
return rtrim($stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1056,7 +1056,7 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
||||||
*
|
*
|
||||||
* @return list<dict<string, string>> Dictionary of branch information.
|
* @return list<dict<string, string>> Dictionary of branch information.
|
||||||
*/
|
*/
|
||||||
public function getAllBranches() {
|
private function getAllBranches() {
|
||||||
$field_list = array(
|
$field_list = array(
|
||||||
'%(refname)',
|
'%(refname)',
|
||||||
'%(objectname)',
|
'%(objectname)',
|
||||||
|
@ -1102,26 +1102,6 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllBranchRefs() {
|
|
||||||
$branches = $this->getAllBranches();
|
|
||||||
|
|
||||||
$refs = array();
|
|
||||||
foreach ($branches as $branch) {
|
|
||||||
$commit_ref = $this->newCommitRef()
|
|
||||||
->setCommitHash($branch['hash'])
|
|
||||||
->setTreeHash($branch['tree'])
|
|
||||||
->setCommitEpoch($branch['epoch'])
|
|
||||||
->attachMessage($branch['text']);
|
|
||||||
|
|
||||||
$refs[] = $this->newMarkerRef()
|
|
||||||
->setName($branch['name'])
|
|
||||||
->setIsActive($branch['current'])
|
|
||||||
->attachCommitRef($commit_ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $refs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBaseCommitRef() {
|
public function getBaseCommitRef() {
|
||||||
$base_commit = $this->getBaseCommit();
|
$base_commit = $this->getBaseCommit();
|
||||||
|
|
||||||
|
@ -1783,5 +1763,4 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
||||||
return new ArcanistGitRepositoryMarkerQuery();
|
return new ArcanistGitRepositoryMarkerQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,12 +49,6 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCanonicalRevisionName($string) {
|
public function getCanonicalRevisionName($string) {
|
||||||
$match = null;
|
|
||||||
if ($this->isHgSubversionRepo() &&
|
|
||||||
preg_match('/@([0-9]+)$/', $string, $match)) {
|
|
||||||
$string = hgsprintf('svnrev(%s)', $match[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
list($stdout) = $this->execxLocal(
|
list($stdout) = $this->execxLocal(
|
||||||
'log -l 1 --template %s -r %s --',
|
'log -l 1 --template %s -r %s --',
|
||||||
'{node}',
|
'{node}',
|
||||||
|
@ -63,32 +57,6 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
||||||
return $stdout;
|
return $stdout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHashFromFromSVNRevisionNumber($revision_id) {
|
|
||||||
$matches = array();
|
|
||||||
$string = hgsprintf('svnrev(%s)', $revision_id);
|
|
||||||
list($stdout) = $this->execxLocal(
|
|
||||||
'log -l 1 --template %s -r %s --',
|
|
||||||
'{node}',
|
|
||||||
$string);
|
|
||||||
if (!$stdout) {
|
|
||||||
throw new ArcanistUsageException(
|
|
||||||
pht('Cannot find the HG equivalent of %s given.', $revision_id));
|
|
||||||
}
|
|
||||||
return $stdout;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getSVNRevisionNumberFromHash($hash) {
|
|
||||||
$matches = array();
|
|
||||||
list($stdout) = $this->execxLocal(
|
|
||||||
'log -r %s --template {svnrev}', $hash);
|
|
||||||
if (!$stdout) {
|
|
||||||
throw new ArcanistUsageException(
|
|
||||||
pht('Cannot find the SVN equivalent of %s given.', $hash));
|
|
||||||
}
|
|
||||||
return $stdout;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSourceControlPath() {
|
public function getSourceControlPath() {
|
||||||
return '/';
|
return '/';
|
||||||
}
|
}
|
||||||
|
@ -505,53 +473,6 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllBranches() {
|
|
||||||
// TODO: This is wrong, and returns bookmarks.
|
|
||||||
|
|
||||||
list($branch_info) = $this->execxLocal('bookmarks');
|
|
||||||
if (trim($branch_info) == 'no bookmarks set') {
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
$matches = null;
|
|
||||||
preg_match_all(
|
|
||||||
'/^\s*(\*?)\s*(.+)\s(\S+)$/m',
|
|
||||||
$branch_info,
|
|
||||||
$matches,
|
|
||||||
PREG_SET_ORDER);
|
|
||||||
|
|
||||||
$return = array();
|
|
||||||
foreach ($matches as $match) {
|
|
||||||
list(, $current, $name, $hash) = $match;
|
|
||||||
|
|
||||||
list($id, $hash) = explode(':', $hash);
|
|
||||||
|
|
||||||
$return[] = array(
|
|
||||||
'current' => (bool)$current,
|
|
||||||
'name' => rtrim($name),
|
|
||||||
'hash' => $hash,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllBranchRefs() {
|
|
||||||
$branches = $this->getAllBranches();
|
|
||||||
|
|
||||||
$refs = array();
|
|
||||||
foreach ($branches as $branch) {
|
|
||||||
$commit_ref = $this->newCommitRef()
|
|
||||||
->setCommitHash($branch['hash']);
|
|
||||||
|
|
||||||
$refs[] = $this->newMarkerRef()
|
|
||||||
->setBranchName($branch['name'])
|
|
||||||
->setIsCurrentBranch($branch['current'])
|
|
||||||
->attachCommitRef($commit_ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $refs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBaseCommitRef() {
|
public function getBaseCommitRef() {
|
||||||
$base_commit = $this->getBaseCommit();
|
$base_commit = $this->getBaseCommit();
|
||||||
|
|
||||||
|
@ -937,10 +858,6 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isHgSubversionRepo() {
|
|
||||||
return file_exists($this->getPath('.hg/svn/rev_map'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSubversionInfo() {
|
public function getSubversionInfo() {
|
||||||
$info = array();
|
$info = array();
|
||||||
$base_path = null;
|
$base_path = null;
|
||||||
|
@ -972,133 +889,16 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getActiveBookmark() {
|
public function getActiveBookmark() {
|
||||||
$bookmarks = $this->getBookmarks();
|
$bookmark = $this->newMarkerRefQuery()
|
||||||
foreach ($bookmarks as $bookmark) {
|
->withMarkerTypes(ArcanistMarkerRef::TYPE_BOOKMARK)
|
||||||
if ($bookmark['is_active']) {
|
->withIsActive(true)
|
||||||
return $bookmark['name'];
|
->executeOne();
|
||||||
}
|
|
||||||
|
if (!$bookmark) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return $bookmark->getName();
|
||||||
}
|
|
||||||
|
|
||||||
public function isBookmark($name) {
|
|
||||||
$bookmarks = $this->getBookmarks();
|
|
||||||
foreach ($bookmarks as $bookmark) {
|
|
||||||
if ($bookmark['name'] === $name) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isBranch($name) {
|
|
||||||
$branches = $this->getBranches();
|
|
||||||
foreach ($branches as $branch) {
|
|
||||||
if ($branch['name'] === $name) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBranches() {
|
|
||||||
list($stdout) = $this->execxLocal('--debug branches');
|
|
||||||
$lines = ArcanistMercurialParser::parseMercurialBranches($stdout);
|
|
||||||
|
|
||||||
$branches = array();
|
|
||||||
foreach ($lines as $name => $spec) {
|
|
||||||
$branches[] = array(
|
|
||||||
'name' => $name,
|
|
||||||
'revision' => $spec['rev'],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $branches;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBookmarks() {
|
|
||||||
$bookmarks = array();
|
|
||||||
|
|
||||||
list($raw_output) = $this->execxLocal('bookmarks');
|
|
||||||
$raw_output = trim($raw_output);
|
|
||||||
if ($raw_output !== 'no bookmarks set') {
|
|
||||||
foreach (explode("\n", $raw_output) as $line) {
|
|
||||||
// example line: * mybook 2:6b274d49be97
|
|
||||||
list($name, $revision) = $this->splitBranchOrBookmarkLine($line);
|
|
||||||
|
|
||||||
$is_active = false;
|
|
||||||
if ('*' === $name[0]) {
|
|
||||||
$is_active = true;
|
|
||||||
$name = substr($name, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
$bookmarks[] = array(
|
|
||||||
'is_active' => $is_active,
|
|
||||||
'name' => $name,
|
|
||||||
'revision' => $revision,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $bookmarks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBookmarkCommitHash($name) {
|
|
||||||
// TODO: Cache this.
|
|
||||||
|
|
||||||
$bookmarks = $this->getBookmarks($name);
|
|
||||||
$bookmarks = ipull($bookmarks, null, 'name');
|
|
||||||
|
|
||||||
foreach ($bookmarks as $bookmark) {
|
|
||||||
if ($bookmark['name'] === $name) {
|
|
||||||
return $bookmark['revision'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Exception(pht('No bookmark "%s".', $name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBranchCommitHash($name) {
|
|
||||||
// TODO: Cache this.
|
|
||||||
// TODO: This won't work when there are multiple branch heads with the
|
|
||||||
// same name.
|
|
||||||
|
|
||||||
$branches = $this->getBranches($name);
|
|
||||||
|
|
||||||
$heads = array();
|
|
||||||
foreach ($branches as $branch) {
|
|
||||||
if ($branch['name'] === $name) {
|
|
||||||
$heads[] = $branch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($heads) === 1) {
|
|
||||||
return idx(head($heads), 'revision');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$heads) {
|
|
||||||
throw new Exception(pht('No branch "%s".', $name));
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Exception(pht('Too many branch heads for "%s".', $name));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function splitBranchOrBookmarkLine($line) {
|
|
||||||
// branches and bookmarks are printed in the format:
|
|
||||||
// default 0:a5ead76cdf85 (inactive)
|
|
||||||
// * mybook 2:6b274d49be97
|
|
||||||
// this code divides the name half from the revision half
|
|
||||||
// it does not parse the * and (inactive) bits
|
|
||||||
$colon_index = strrpos($line, ':');
|
|
||||||
$before_colon = substr($line, 0, $colon_index);
|
|
||||||
$start_rev_index = strrpos($before_colon, ' ');
|
|
||||||
$name = substr($line, 0, $start_rev_index);
|
|
||||||
$rev = substr($line, $start_rev_index);
|
|
||||||
|
|
||||||
return array(trim($name), trim($rev));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRemoteURI() {
|
public function getRemoteURI() {
|
||||||
|
|
|
@ -369,15 +369,6 @@ abstract class ArcanistRepositoryAPI extends Phobject {
|
||||||
throw new ArcanistCapabilityNotSupportedException($this);
|
throw new ArcanistCapabilityNotSupportedException($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllBranches() {
|
|
||||||
// TODO: Implement for Mercurial/SVN and make abstract.
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllBranchRefs() {
|
|
||||||
throw new ArcanistCapabilityNotSupportedException($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBaseCommitRef() {
|
public function getBaseCommitRef() {
|
||||||
throw new ArcanistCapabilityNotSupportedException($this);
|
throw new ArcanistCapabilityNotSupportedException($this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class ArcanistBookmarkWorkflow
|
|
||||||
extends ArcanistFeatureBaseWorkflow {
|
|
||||||
|
|
||||||
public function getWorkflowName() {
|
|
||||||
return 'bookmark';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class ArcanistBranchWorkflow
|
|
||||||
extends ArcanistFeatureBaseWorkflow {
|
|
||||||
|
|
||||||
public function getWorkflowName() {
|
|
||||||
return 'branch';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,286 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
abstract class ArcanistFeatureBaseWorkflow
|
|
||||||
extends ArcanistArcWorkflow {
|
|
||||||
|
|
||||||
private $branches;
|
|
||||||
|
|
||||||
public function getWorkflowArguments() {
|
|
||||||
return array(
|
|
||||||
$this->newWorkflowArgument('view-all')
|
|
||||||
->setHelp(pht('Include closed and abandoned revisions.')),
|
|
||||||
$this->newWorkflowArgument('by-status')
|
|
||||||
->setParameter('status')
|
|
||||||
->setHelp(pht('Sort branches by status instead of time.')),
|
|
||||||
$this->newWorkflowArgument('output')
|
|
||||||
->setParameter('format')
|
|
||||||
->setHelp(
|
|
||||||
pht(
|
|
||||||
'With "json", show features in machine-readable JSON format.')),
|
|
||||||
$this->newWorkflowArgument('branch')
|
|
||||||
->setWildcard(true),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getWorkflowInformation() {
|
|
||||||
return $this->newWorkflowInformation()
|
|
||||||
->setSynopsis(pht('Wrapper on "git branch" or "hg bookmark".'))
|
|
||||||
->addExample(pht('**%s** [__options__]', $this->getWorkflowName()))
|
|
||||||
->addExample(pht('**%s** __name__ [__start__]', $this->getWorkflowName()))
|
|
||||||
->setHelp(
|
|
||||||
pht(<<<EOHELP
|
|
||||||
A wrapper on 'git branch' or 'hg bookmark'.
|
|
||||||
|
|
||||||
Without __name__, it lists the available branches and their revision status.
|
|
||||||
|
|
||||||
With __name__, it creates or checks out a branch. If the branch __name__
|
|
||||||
doesn't exist and is in format D123 then the branch of revision D123 is
|
|
||||||
checked out. Use __start__ to specify where the new branch will start. Use
|
|
||||||
'arc.feature.start.default' to set the default feature start location.
|
|
||||||
EOHELP
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function runWorkflow() {
|
|
||||||
$repository_api = $this->getRepositoryAPI();
|
|
||||||
if (!$repository_api) {
|
|
||||||
throw new PhutilArgumentUsageException(
|
|
||||||
pht(
|
|
||||||
'This command must be run in a Git or Mercurial working copy.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$names = $this->getArgument('branch');
|
|
||||||
if ($names) {
|
|
||||||
if (count($names) > 2) {
|
|
||||||
throw new ArcanistUsageException(pht('Specify only one branch.'));
|
|
||||||
}
|
|
||||||
return $this->checkoutBranch($names);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Everything in this whole workflow that says "branch" means
|
|
||||||
// "bookmark" in Mercurial.
|
|
||||||
|
|
||||||
$branches = $repository_api->getAllBranchRefs();
|
|
||||||
if (!$branches) {
|
|
||||||
throw new ArcanistUsageException(
|
|
||||||
pht('No branches in this working copy.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$states = array();
|
|
||||||
foreach ($branches as $branch_key => $branch) {
|
|
||||||
$state_ref = id(new ArcanistWorkingCopyStateRef())
|
|
||||||
->setCommitRef($branch->getCommitRef());
|
|
||||||
|
|
||||||
$states[] = array(
|
|
||||||
'branch' => $branch,
|
|
||||||
'state' => $state_ref,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->loadHardpoints(
|
|
||||||
ipull($states, 'state'),
|
|
||||||
ArcanistWorkingCopyStateRef::HARDPOINT_REVISIONREFS);
|
|
||||||
|
|
||||||
$this->printBranches($states);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function checkoutBranch(array $names) {
|
|
||||||
$api = $this->getRepositoryAPI();
|
|
||||||
|
|
||||||
if ($api instanceof ArcanistMercurialAPI) {
|
|
||||||
$command = 'update %s';
|
|
||||||
} else {
|
|
||||||
$command = 'checkout %s';
|
|
||||||
}
|
|
||||||
|
|
||||||
$err = 1;
|
|
||||||
|
|
||||||
$name = $names[0];
|
|
||||||
if (isset($names[1])) {
|
|
||||||
$start = $names[1];
|
|
||||||
} else {
|
|
||||||
$start = $this->getConfigFromAnySource('arc.feature.start.default');
|
|
||||||
}
|
|
||||||
|
|
||||||
$branches = $api->getAllBranches();
|
|
||||||
if (in_array($name, ipull($branches, 'name'))) {
|
|
||||||
list($err, $stdout, $stderr) = $api->execManualLocal($command, $name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($err) {
|
|
||||||
$match = null;
|
|
||||||
if (preg_match('/^D(\d+)$/', $name, $match)) {
|
|
||||||
$diff = $this->getConduitEngine()->resolveCall(
|
|
||||||
'differential.querydiffs',
|
|
||||||
array(
|
|
||||||
'revisionIDs' => array($match[1]),
|
|
||||||
));
|
|
||||||
$diff = head($diff);
|
|
||||||
|
|
||||||
if ($diff['branch'] != '') {
|
|
||||||
$name = $diff['branch'];
|
|
||||||
list($err, $stdout, $stderr) = $api->execManualLocal(
|
|
||||||
$command,
|
|
||||||
$name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($err) {
|
|
||||||
if ($api instanceof ArcanistMercurialAPI) {
|
|
||||||
$rev = '';
|
|
||||||
if ($start) {
|
|
||||||
$rev = csprintf('-r %s', $start);
|
|
||||||
}
|
|
||||||
|
|
||||||
$exec = $api->execManualLocal('bookmark %C %s', $rev, $name);
|
|
||||||
|
|
||||||
if (!$exec[0] && $start) {
|
|
||||||
$api->execxLocal('update %s', $name);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$startarg = $start ? csprintf('%s', $start) : '';
|
|
||||||
$exec = $api->execManualLocal(
|
|
||||||
'checkout --track -b %s %C',
|
|
||||||
$name,
|
|
||||||
$startarg);
|
|
||||||
}
|
|
||||||
|
|
||||||
list($err, $stdout, $stderr) = $exec;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $stdout;
|
|
||||||
fprintf(STDERR, '%s', $stderr);
|
|
||||||
return $err;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function printBranches(array $states) {
|
|
||||||
static $color_map = array(
|
|
||||||
'Closed' => 'cyan',
|
|
||||||
'Needs Review' => 'magenta',
|
|
||||||
'Needs Revision' => 'red',
|
|
||||||
'Accepted' => 'green',
|
|
||||||
'No Revision' => 'blue',
|
|
||||||
'Abandoned' => 'default',
|
|
||||||
);
|
|
||||||
|
|
||||||
static $ssort_map = array(
|
|
||||||
'Closed' => 1,
|
|
||||||
'No Revision' => 2,
|
|
||||||
'Needs Review' => 3,
|
|
||||||
'Needs Revision' => 4,
|
|
||||||
'Accepted' => 5,
|
|
||||||
);
|
|
||||||
|
|
||||||
$out = array();
|
|
||||||
foreach ($states as $objects) {
|
|
||||||
$state = $objects['state'];
|
|
||||||
$branch = $objects['branch'];
|
|
||||||
|
|
||||||
$revision = null;
|
|
||||||
if ($state->hasAmbiguousRevisionRefs()) {
|
|
||||||
$status = pht('Ambiguous Revision');
|
|
||||||
} else {
|
|
||||||
$revision = $state->getRevisionRef();
|
|
||||||
if ($revision) {
|
|
||||||
$status = $revision->getStatusDisplayName();
|
|
||||||
} else {
|
|
||||||
$status = pht('No Revision');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$this->getArgument('view-all') && !$branch->getIsActive()) {
|
|
||||||
if ($status == 'Closed' || $status == 'Abandoned') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$commit = $branch->getCommitRef();
|
|
||||||
$epoch = $commit->getCommitEpoch();
|
|
||||||
|
|
||||||
$color = idx($color_map, $status, 'default');
|
|
||||||
|
|
||||||
$epoch_vector = id(new PhutilSortVector())
|
|
||||||
->addInt($epoch);
|
|
||||||
|
|
||||||
$status_vector = id(new PhutilSortVector())
|
|
||||||
->addInt(idx($ssort_map, $status, 0))
|
|
||||||
->addInt($epoch);
|
|
||||||
|
|
||||||
if ($revision) {
|
|
||||||
$desc = $revision->getFullName();
|
|
||||||
} else {
|
|
||||||
$desc = $commit->getSummary();
|
|
||||||
}
|
|
||||||
|
|
||||||
$out[] = array(
|
|
||||||
'name' => $branch->getName(),
|
|
||||||
'current' => $branch->getIsActive(),
|
|
||||||
'status' => $status,
|
|
||||||
'desc' => $desc,
|
|
||||||
'revision' => $revision ? $revision->getID() : null,
|
|
||||||
'color' => $color,
|
|
||||||
'epoch' => $epoch,
|
|
||||||
|
|
||||||
'esort' => $epoch_vector,
|
|
||||||
'ssort' => $status_vector,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$out) {
|
|
||||||
// All of the revisions are closed or abandoned.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$len_name = max(array_map('strlen', ipull($out, 'name'))) + 2;
|
|
||||||
$len_status = max(array_map('strlen', ipull($out, 'status'))) + 2;
|
|
||||||
|
|
||||||
// Sort the list in natural order first. When we apply a stable sort to
|
|
||||||
// the list below, branches which were last updated at the same time will
|
|
||||||
// retain this ordering. This allows "feature1", "feature2", etc., to
|
|
||||||
// display in the correct order if they were touched at the same second,
|
|
||||||
// which is common when "arc land" performs a cascading rebase.
|
|
||||||
|
|
||||||
$name_map = ipull($out, 'name');
|
|
||||||
natcasesort($name_map);
|
|
||||||
$out = array_select_keys($out, array_keys($name_map));
|
|
||||||
|
|
||||||
if ($this->getArgument('by-status')) {
|
|
||||||
$vectors = ipull($out, 'ssort');
|
|
||||||
} else {
|
|
||||||
$vectors = ipull($out, 'esort');
|
|
||||||
}
|
|
||||||
|
|
||||||
$vectors = msortv($vectors, 'getSelf');
|
|
||||||
$out = array_select_keys($out, array_keys($vectors));
|
|
||||||
|
|
||||||
if ($this->getArgument('output') == 'json') {
|
|
||||||
foreach ($out as &$feature) {
|
|
||||||
unset($feature['color'], $feature['ssort'], $feature['esort']);
|
|
||||||
}
|
|
||||||
echo json_encode(ipull($out, null, 'name'))."\n";
|
|
||||||
} else {
|
|
||||||
$table = id(new PhutilConsoleTable())
|
|
||||||
->setShowHeader(false)
|
|
||||||
->addColumn('current', array('title' => ''))
|
|
||||||
->addColumn('name', array('title' => pht('Name')))
|
|
||||||
->addColumn('status', array('title' => pht('Status')))
|
|
||||||
->addColumn('descr', array('title' => pht('Description')));
|
|
||||||
|
|
||||||
foreach ($out as $line) {
|
|
||||||
$table->addRow(array(
|
|
||||||
'current' => $line['current'] ? '*' : '',
|
|
||||||
'name' => tsprintf('**%s**', $line['name']),
|
|
||||||
'status' => tsprintf(
|
|
||||||
"<fg:{$line['color']}>%s</fg>", $line['status']),
|
|
||||||
'descr' => $line['desc'],
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$table->draw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class ArcanistFeatureWorkflow
|
|
||||||
extends ArcanistFeatureBaseWorkflow {
|
|
||||||
|
|
||||||
public function getWorkflowName() {
|
|
||||||
return 'feature';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue