/**
  * Construct fields to select any commit
  *
  * @param DNProject $project
  * @param DataList|null $pipelineCommits Optional list of pipeline-filtered commits to include
  * @return FormField
  */
 protected function buildCommitSelector($project, $pipelineCommits = null)
 {
     // Branches
     $branches = array();
     foreach ($project->DNBranchList() as $branch) {
         $sha = $branch->SHA();
         $name = $branch->Name();
         $branchValue = sprintf("%s (%s, %s old)", $name, substr($sha, 0, 8), $branch->LastUpdated()->TimeDiff());
         $branches[$sha . '-' . $name] = $branchValue;
     }
     // Tags
     $tags = array();
     foreach ($project->DNTagList()->setLimit(null) as $tag) {
         $sha = $tag->SHA();
         $name = $tag->Name();
         $tagValue = sprintf("%s (%s, %s old)", $name, substr($sha, 0, 8), $branch->LastUpdated()->TimeDiff());
         $tags[$sha . '-' . $tag] = $tagValue;
     }
     $tags = array_reverse($tags);
     // Past deployments
     $redeploy = array();
     foreach ($project->DNEnvironmentList() as $dnEnvironment) {
         $envName = $dnEnvironment->Name;
         foreach ($dnEnvironment->DeployHistory() as $deploy) {
             $sha = $deploy->SHA;
             if (!isset($redeploy[$envName])) {
                 $redeploy[$envName] = array();
             }
             if (!isset($redeploy[$envName][$sha])) {
                 $pastValue = sprintf("%s (deployed %s)", substr($sha, 0, 8), $deploy->obj('LastEdited')->Ago());
                 $redeploy[$envName][$sha] = $pastValue;
             }
         }
     }
     // Merge fields
     $releaseMethods = array();
     if ($pipelineCommits) {
         $releaseMethods[] = new SelectionGroup_Item('FilteredCommits', $this->buildPipelineField($pipelineCommits), 'Deploy a commit prepared for this pipeline');
     }
     if (!empty($branches)) {
         $releaseMethods[] = new SelectionGroup_Item('Branch', new DropdownField('Branch', 'Select a branch', $branches), 'Deploy the latest version of a branch');
     }
     if ($tags) {
         $releaseMethods[] = new SelectionGroup_Item('Tag', new DropdownField('Tag', 'Select a tag', $tags), 'Deploy a tagged release');
     }
     if ($redeploy) {
         $releaseMethods[] = new SelectionGroup_Item('Redeploy', new GroupedDropdownField('Redeploy', 'Redeploy', $redeploy), 'Redeploy a release that was previously deployed (to any environment)');
     }
     $releaseMethods[] = new SelectionGroup_Item('SHA', new Textfield('SHA', 'Please specify the full SHA'), 'Deploy a specific SHA');
     $field = new TabbedSelectionGroup('SelectRelease', $releaseMethods);
     $field->setValue(reset($releaseMethods)->getValue());
     return $field;
 }