private function parseData($name, $data) { switch ($name) { case 'branches-basic.txt': $output = ArcanistMercurialParser::parseMercurialBranches($data); $this->assertEqual(array('default', 'stable'), array_keys($output)); $this->assertEqual(array('a21ccf4412d5', 'ec222a29bdf0'), array_values(ipull($output, 'rev'))); break; case 'branches-with-spaces.txt': $output = ArcanistMercurialParser::parseMercurialBranches($data); $this->assertEqual(array('m m m m m 2:ffffffffffff (inactive)', 'xxx yyy zzz', 'default', "'"), array_keys($output)); $this->assertEqual(array('0b9d8290c4e0', '78963faacfc7', '5db03c5500c6', 'ffffffffffff'), array_values(ipull($output, 'rev'))); break; case 'branches-empty.txt': $output = ArcanistMercurialParser::parseMercurialBranches($data); $this->assertEqual(array(), $output); break; case 'log-basic.txt': $output = ArcanistMercurialParser::parseMercurialLog($data); $this->assertEqual(3, count($output)); $this->assertEqual(array('a21ccf4412d5', 'a051f8a6a7cc', 'b1f49efeab65'), array_values(ipull($output, 'rev'))); break; case 'log-empty.txt': // Empty logs (e.g., "hg parents" for a root revision) should parse // correctly. $output = ArcanistMercurialParser::parseMercurialLog($data); $this->assertEqual(array(), $output); break; case 'status-basic.txt': $output = ArcanistMercurialParser::parseMercurialStatus($data); $this->assertEqual(4, count($output)); $this->assertEqual(array('changed', 'added', 'removed', 'untracked'), array_keys($output)); break; case 'status-moves.txt': $output = ArcanistMercurialParser::parseMercurialStatusDetails($data); $this->assertEqual('move_source', $output['moved_file']['from']); $this->assertEqual(null, $output['changed_file']['from']); $this->assertEqual('copy_source', $output['copied_file']['from']); $this->assertEqual(null, idx($output, 'copy_source')); break; default: throw new Exception(pht("No test information for test data '%s'!", $name)); } }
public function getWorkingCopyStatus() { if (!isset($this->status)) { // A reviewable revision spans multiple local commits in Mercurial, but // there is no way to get file change status across multiple commits, so // just take the entire diff and parse it to figure out what's changed. $diff = $this->getFullMercurialDiff(); if (!$diff) { $this->status = array(); return $this->status; } $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($diff); $status_map = array(); foreach ($changes as $change) { $flags = 0; switch ($change->getType()) { case ArcanistDiffChangeType::TYPE_ADD: case ArcanistDiffChangeType::TYPE_MOVE_HERE: case ArcanistDiffChangeType::TYPE_COPY_HERE: $flags |= self::FLAG_ADDED; break; case ArcanistDiffChangeType::TYPE_CHANGE: case ArcanistDiffChangeType::TYPE_COPY_AWAY: // Check for changes? $flags |= self::FLAG_MODIFIED; break; case ArcanistDiffChangeType::TYPE_DELETE: case ArcanistDiffChangeType::TYPE_MOVE_AWAY: case ArcanistDiffChangeType::TYPE_MULTICOPY: $flags |= self::FLAG_DELETED; break; } $status_map[$change->getCurrentPath()] = $flags; } list($stdout) = $this->execxLocal('status'); $working_status = ArcanistMercurialParser::parseMercurialStatus($stdout); foreach ($working_status as $path => $status) { if ($status & ArcanistRepositoryAPI::FLAG_UNTRACKED) { // If the file is untracked, don't mark it uncommitted. continue; } $status |= self::FLAG_UNCOMMITTED; if (!empty($status_map[$path])) { $status_map[$path] |= $status; } else { $status_map[$path] = $status; } } $this->status = $status_map; } return $this->status; }
protected function buildUncommittedStatus() { list($stdout) = $this->execxLocal('status'); $results = new PhutilArrayWithDefaultValue(); $working_status = ArcanistMercurialParser::parseMercurialStatus($stdout); foreach ($working_status as $path => $mask) { if (!($mask & ArcanistRepositoryAPI::FLAG_UNTRACKED)) { // Mark tracked files as uncommitted. $mask |= self::FLAG_UNCOMMITTED; } $results[$path] |= $mask; } return $results->toArray(); }