diff --git a/src/work/ArcanistWorkEngine.php b/src/work/ArcanistWorkEngine.php --- a/src/work/ArcanistWorkEngine.php +++ b/src/work/ArcanistWorkEngine.php @@ -198,18 +198,61 @@ ArcanistSymbolRef::HARDPOINT_OBJECT); $task_ref = $task_symbol->getObject(); + if (!$task_ref) { throw new PhutilArgumentUsageException( pht( 'No task "%s" exists, or you do not have permission to view it.', $symbol)); } + // check if branch exists + $api = $this->getRepositoryAPI(); + $old_branches = $api->execxLocal('branch --list %s*', $symbol); + $branch_name = ''; + + $old_branches = array_map(function ($v) { + $v = ltrim($v, ' +*'); // `git branch --list` can give + or * + return trim($v); + }, $old_branches); + + if (count($old_branches)) { + $old_branch = array_shift($old_branches); + $branch_name = $old_branch; // will be '' if no matches + } - throw new Exception(pht('TODO: Implement this workflow.')); + if ($branch_name !== '') { + $api->execxLocal('checkout %s', $branch_name); + } else { + $task_name = $task_ref->getName(); + + // TODO: check mercurial and subversion. This is just git + // see https://git-scm.com/docs/git-check-ref-format + $pattern = '#(^[./]+|//|/\.+|\.{2,}|@{|[/.]+$|^@$|[~^:\x00-\x20\x7F?*\[\\\\])#u'; + $branch_name = preg_replace($pattern, '-', $task_name); + $branch_name = trim($branch_name, '-'); + $branch_name = mb_convert_case($branch_name, MB_CASE_LOWER, 'UTF-8'); + $branch_name = $task_ref->getMonogram().'-'.$branch_name; + // to reduce multiple '-' to single '-' + $branch_name = preg_replace('#-+#', '-', $branch_name); + // keep length to GitHub max + $branch_name = rtrim(mb_substr($branch_name, 0, 244), '-'); + + // below should work unless in detached HEAD state?? + $start = id($api)->getBranchName(); + if (!$start) { + // test detached HEAD?? + $start = id($api)->getWorkingCopyRevision(); + $this->newMarker($branch_name, $start); + } + } - $this->loadHardpoints( + return id(new ArcanistMarkerRef()) + ->setName($branch_name) + ->setMarkerType(ArcanistMarkerRef::TYPE_BRANCH); + /* $this->loadHardpoints( $task_ref, ArcanistTaskRef::HARDPOINT_REVISIONREFS); + */ } }