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,73 @@
       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));
     }
+    $monogram = $task_ref->getMonogram();
+    $task_name = $task_ref->getName();
+    $api = $this->getRepositoryAPI();
+
+    // Check if the branch exists
+    $existing_branches =
+      $api->execxLocal('branch --list \'%s-*\' --format \'%%(refname:short)\''
+        , $monogram);
+    $existing_branches = trim($existing_branches[0]);
+    $existing_branches = explode("\n", $existing_branches);
+    $existing_branches = array_filter($existing_branches, function ($e) {
+      return $e !== '';
+    });
+
+    $branch_name = '';
+    if (count($existing_branches) === 1) {
+      $branch_name = trim($existing_branches[0]);
+    } else if (count($existing_branches) > 1 ) {
+      // error more than one branch
+      throw new InvalidArgumentException(
+        pht(
+          "More than one branch matching task ID '%s' exists.".
+          " Use 'git checkout' instead.",
+          $monogram));
+    }
 
-    throw new Exception(pht('TODO: Implement this workflow.'));
+    if ($branch_name !== '') {
+      $api->execxLocal('checkout %s', $branch_name);
+    } else {
+      // TODO: break this out into named function in class ArcanistGitWorkEngine
+      // e.g. sanitizeBranchName($monogram, $task_name)
+
+      // 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 = $monogram.'-'.$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(
-      $task_ref,
-      ArcanistTaskRef::HARDPOINT_REVISIONREFS);
+    return id(new ArcanistMarkerRef())
+      ->setName($branch_name)
+      ->setMarkerType(ArcanistMarkerRef::TYPE_BRANCH);
+    /* $this->loadHardpoints(
+       $task_ref,
+       ArcanistTaskRef::HARDPOINT_REVISIONREFS);
+    */
   }
 
 }