Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2889355
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
7 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/repository/parser/ArcanistMercurialParser.php b/src/repository/parser/ArcanistMercurialParser.php
index 4eb10e2f..33e59c5c 100644
--- a/src/repository/parser/ArcanistMercurialParser.php
+++ b/src/repository/parser/ArcanistMercurialParser.php
@@ -1,240 +1,241 @@
<?php
/**
* Parses output from various "hg" commands into structured data. This class
* provides low-level APIs for reading "hg" output.
*
* @task parse Parsing "hg" Output
*/
final class ArcanistMercurialParser extends Phobject {
/* -( Parsing "hg" Output )------------------------------------------------ */
/**
* Parse the output of "hg status". This provides detailed information, you
* can get less detailed information with @{method:parseMercurialStatus}. In
* particular, this will parse copy sources as per "hg status -C".
*
* @param string The stdout from running an "hg status" command.
* @return dict Map of paths to status dictionaries.
* @task parse
*/
public static function parseMercurialStatusDetails($stdout) {
$result = array();
$stdout = trim($stdout);
if (!strlen($stdout)) {
return $result;
}
$last_path = null;
$lines = explode("\n", $stdout);
foreach ($lines as $line) {
$flags = 0;
if ($line[1] !== ' ') {
throw new Exception(
pht(
"Unparsable Mercurial status line '%s'.",
$line));
}
$code = $line[0];
$path = substr($line, 2);
switch ($code) {
case 'A':
$flags |= ArcanistRepositoryAPI::FLAG_ADDED;
break;
case 'R':
$flags |= ArcanistRepositoryAPI::FLAG_DELETED;
break;
case 'M':
$flags |= ArcanistRepositoryAPI::FLAG_MODIFIED;
break;
case 'C':
// This is "clean" and included only for completeness, these files
// have not been changed.
break;
case '!':
$flags |= ArcanistRepositoryAPI::FLAG_MISSING;
break;
case '?':
$flags |= ArcanistRepositoryAPI::FLAG_UNTRACKED;
break;
case 'I':
// This is "ignored" and included only for completeness.
break;
case ' ':
// This shows the source of a file move, so update the last file we
// parsed to set its source.
if ($last_path === null) {
throw new Exception(
pht(
"Unexpected copy source in %s, '%s'.",
'hg status',
$line));
}
$result[$last_path]['from'] = $path;
continue 2;
default:
throw new Exception(pht("Unknown Mercurial status '%s'.", $code));
}
$result[$path] = array(
'flags' => $flags,
'from' => null,
);
$last_path = $path;
}
return $result;
}
/**
* Parse the output of "hg status". This provides only basic information, you
* can get more detailed information by invoking
* @{method:parseMercurialStatusDetails}.
*
* @param string The stdout from running an "hg status" command.
* @return dict Map of paths to ArcanistRepositoryAPI status flags.
* @task parse
*/
public static function parseMercurialStatus($stdout) {
$result = self::parseMercurialStatusDetails($stdout);
return ipull($result, 'flags');
}
/**
* Parse the output of "hg log". This also parses "hg outgoing", "hg parents",
* and other similar commands. This assumes "--style default".
*
* @param string The stdout from running an "hg log" command.
* @return list List of dictionaries with commit information.
* @task parse
*/
public static function parseMercurialLog($stdout) {
$result = array();
$stdout = trim($stdout);
if (!strlen($stdout)) {
return $result;
}
$chunks = explode("\n\n", $stdout);
foreach ($chunks as $chunk) {
$commit = array();
$lines = explode("\n", $chunk);
foreach ($lines as $line) {
if (preg_match('/^(comparing with|searching for changes)/', $line)) {
// These are sent to stdout when you run "hg outgoing" although the
// format is otherwise identical to "hg log".
continue;
}
if (preg_match('/^remote:/', $line)) {
// This indicates remote error in "hg outgoing".
continue;
}
list($name, $value) = explode(':', $line, 2);
$value = trim($value);
switch ($name) {
case 'user':
$commit['user'] = $value;
break;
case 'date':
$commit['date'] = strtotime($value);
break;
case 'summary':
$commit['summary'] = $value;
break;
case 'changeset':
list($local, $rev) = explode(':', $value, 2);
$commit['local'] = $local;
$commit['rev'] = $rev;
break;
case 'parent':
if (empty($commit['parents'])) {
$commit['parents'] = array();
}
list($local, $rev) = explode(':', $value, 2);
$commit['parents'][] = array(
'local' => $local,
'rev' => $rev,
);
break;
case 'branch':
$commit['branch'] = $value;
break;
case 'tag':
$commit['tag'] = $value;
break;
case 'bookmark':
$commit['bookmark'] = $value;
break;
case 'obsolete':
- // This is an extra field added by the "evolve" extension even
- // if HGPLAIN=1 is set. See PHI502.
+ case 'instability':
+ // These are extra fields added by the "evolve" extension even
+ // if HGPLAIN=1 is set. See PHI502 and PHI718.
break;
default:
throw new Exception(
pht("Unknown Mercurial log field '%s'!", $name));
}
}
$result[] = $commit;
}
return $result;
}
/**
* Parse the output of "hg branches".
*
* @param string The stdout from running an "hg branches" command.
* @return list A list of dictionaries with branch information.
* @task parse
*/
public static function parseMercurialBranches($stdout) {
$stdout = rtrim($stdout, "\n");
if (!strlen($stdout)) {
// No branches; commonly, this occurs in a newly initialized repository.
return array();
}
$lines = explode("\n", $stdout);
$branches = array();
foreach ($lines as $line) {
$matches = null;
// Output of "hg branches" normally looks like:
//
// default 15101:a21ccf4412d5
//
// ...but may also have human-readable cues like:
//
// stable 15095:ec222a29bdf0 (inactive)
//
// See the unit tests for more examples.
$regexp = '/^(\S+(?:\s+\S+)*)\s+(\d+):([a-f0-9]+)(\s+\\(inactive\\))?$/';
if (!preg_match($regexp, $line, $matches)) {
throw new Exception(
pht(
"Failed to parse '%s' output: %s",
'hg branches',
$line));
}
$branches[$matches[1]] = array(
'local' => $matches[2],
'rev' => $matches[3],
);
}
return $branches;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Jan 19 2025, 12:02 (4 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1124352
Default Alt Text
(7 KB)
Attached To
Mode
rARC Arcanist
Attached
Detach File
Event Timeline
Log In to Comment