Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15491019
D21716.id51763.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D21716.id51763.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -346,6 +346,7 @@
'ArcanistMercurialAPI' => 'repository/api/ArcanistMercurialAPI.php',
'ArcanistMercurialCommitGraphQuery' => 'repository/graph/query/ArcanistMercurialCommitGraphQuery.php',
'ArcanistMercurialCommitMessageHardpointQuery' => 'query/ArcanistMercurialCommitMessageHardpointQuery.php',
+ 'ArcanistMercurialCommitSymbolCommitHardpointQuery' => 'ref/commit/ArcanistMercurialCommitSymbolCommitHardpointQuery.php',
'ArcanistMercurialLandEngine' => 'land/engine/ArcanistMercurialLandEngine.php',
'ArcanistMercurialLocalState' => 'repository/state/ArcanistMercurialLocalState.php',
'ArcanistMercurialParser' => 'repository/parser/ArcanistMercurialParser.php',
@@ -1404,6 +1405,7 @@
'ArcanistMercurialAPI' => 'ArcanistRepositoryAPI',
'ArcanistMercurialCommitGraphQuery' => 'ArcanistCommitGraphQuery',
'ArcanistMercurialCommitMessageHardpointQuery' => 'ArcanistWorkflowMercurialHardpointQuery',
+ 'ArcanistMercurialCommitSymbolCommitHardpointQuery' => 'ArcanistWorkflowMercurialHardpointQuery',
'ArcanistMercurialLandEngine' => 'ArcanistLandEngine',
'ArcanistMercurialLocalState' => 'ArcanistRepositoryLocalState',
'ArcanistMercurialParser' => 'Phobject',
diff --git a/src/ref/commit/ArcanistMercurialCommitSymbolCommitHardpointQuery.php b/src/ref/commit/ArcanistMercurialCommitSymbolCommitHardpointQuery.php
new file mode 100644
--- /dev/null
+++ b/src/ref/commit/ArcanistMercurialCommitSymbolCommitHardpointQuery.php
@@ -0,0 +1,158 @@
+<?php
+
+final class ArcanistMercurialCommitSymbolCommitHardpointQuery
+ extends ArcanistWorkflowMercurialHardpointQuery {
+
+ public function getHardpoints() {
+ return array(
+ ArcanistCommitSymbolRef::HARDPOINT_OBJECT,
+ );
+ }
+
+ protected function canLoadRef(ArcanistRef $ref) {
+ return ($ref instanceof ArcanistCommitSymbolRef);
+ }
+
+ public function loadHardpoint(array $refs, $hardpoint) {
+ $symbol_map = array();
+ foreach ($refs as $key => $ref) {
+ $symbol_map[$key] = $ref->getSymbol();
+ }
+
+ $symbol_set = array_fuse($symbol_map);
+ foreach ($symbol_set as $symbol) {
+ $this->validateSymbol($symbol);
+ }
+
+ $api = $this->getRepositoryAPI();
+
+ // Using "hg log" with repeated "--rev arguments will have the following
+ // behaviors which need accounted for:
+ // 1. If any one revision is invalid then the entire command will fail. To
+ // work around this the revset uses a trick where specifying a pattern
+ // for the bookmark() or tag() predicates instead of a literal won't
+ // result in failure if the pattern isn't found.
+ // 2. Multiple markers that resolve to the same node will only be included
+ // once in the output. Because of this the order of output can't be
+ // relied upon to match up with the requested symbol. To work around
+ // this, the template used will also include tags and bookmarks as the
+ // possible symbols being checked then build a map of used symbols to be
+ // the lookup for the ones requested. Here we lump both tags and
+ // bookmarks together as it's not important to distinguish between them.
+ // However Mercurial does permit bookmarks and tags to share the same
+ // name~.
+ // 3. The working directory can't be identified directly, instead a special
+ // template conditional is used to include 'CWD' as the second item in
+ // the output if the node is also the working directory, or 'NOTCWD'
+ // otherwise. This needs included before the tags/bookmarks in order to
+ // distinguish it from some repository using that same name for a tag or
+ // bookmark.
+
+ $pattern = array();
+ $arguments = array();
+
+ $pattern[] = 'log';
+
+ $pattern[] = '--template %s';
+ $arguments[] = "{node}\1".
+ "{ifcontains(rev, revset('parents()'), 'CWD', 'NOTCWD')}\1".
+ "{tags % '{tag}\2'}{bookmarks % '{bookmark}\2'}\3";
+
+ foreach ($symbol_set as $symbol) {
+ // This is the one symbol that wouldn't be a bookmark or tag
+ if ($symbol === '.') {
+ $pattern[] = '--rev .';
+ continue;
+ }
+ $pattern[] = '--rev \'bookmark("re:^%s$") or tag("re:^%s$")\'';
+ $symbol = preg_quote($symbol);
+ $arguments[] = $symbol;
+ $arguments[] = $symbol;
+ }
+
+ $pattern = implode(' ', $pattern);
+ array_unshift($arguments, $pattern);
+
+ $future = call_user_func_array(
+ array($api, 'newFuture'),
+ $arguments);
+
+ list($stdout) = (yield $this->yieldFuture($future));
+
+ $lines = explode("\3", $stdout);
+
+ $hash_map = array();
+ $symmap = array();
+
+ foreach ($lines as $line) {
+ $parts = array_filter(explode("\1", $line, 4));
+
+ if (empty($parts)) {
+ continue;
+ } else if (count($parts) === 2) {
+ list($node, $cwd) = $parts;
+ $markers = array();
+ } else if (count($parts) === 3) {
+ list($node, $cwd, $markers) = $parts;
+ $markers = array_filter(explode("\2", $markers));
+ } else {
+ throw new Exception(
+ pht('Execution of "hg log" emitted an unexpected line ("%s").',
+ $line));
+ }
+
+ foreach ($markers as $marker) {
+ if (!isset($hash_map[$marker])) {
+ $hash_map[$marker] = $node;
+ } else if ($hash_map[$marker] !== $node) {
+ $hash_map[$marker] = '';
+ }
+ }
+
+ // The log template will mark the working directory node with 'CWD' which
+ // we insert for the special marker '.' for the working directory, used
+ // by ArcanistMercurialAPI::newCurrentCommitSymbol().
+ if ($cwd === 'CWD') {
+ if (!isset($hash_map['.'])) {
+ $hash_map['.'] = $node;
+ } else if ($hash_map['.'] !== $node) {
+ $hash_map['.'] = '';
+ }
+ }
+ }
+
+ // Remove entries resulting in collisions, which set empty string values
+ $hash_map = array_filter($hash_map);
+
+ $results = array();
+ foreach ($symbol_map as $key => $symbol) {
+ if (isset($hash_map[$symbol])) {
+ $results[$key] = $hash_map[$symbol];
+ }
+ }
+
+ foreach ($results as $key => $result) {
+ if ($result === null) {
+ continue;
+ }
+
+ $ref = id(new ArcanistCommitRef())
+ ->setCommitHash($result);
+
+ $results[$key] = $ref;
+ }
+
+ yield $this->yieldMap($results);
+ }
+
+ private function validateSymbol($symbol) {
+ if (strpos($symbol, "\n") !== false) {
+ throw new Exception(
+ pht(
+ 'Commit symbol "%s" contains a newline. This is not a valid '.
+ 'character in a Mercurial commit symbol.',
+ addcslashes($symbol, "\\\n")));
+ }
+ }
+
+}
diff --git a/src/repository/api/ArcanistMercurialAPI.php b/src/repository/api/ArcanistMercurialAPI.php
--- a/src/repository/api/ArcanistMercurialAPI.php
+++ b/src/repository/api/ArcanistMercurialAPI.php
@@ -454,6 +454,10 @@
}
}
+ protected function newCurrentCommitSymbol() {
+ return $this->getWorkingCopyRevision();
+ }
+
public function getWorkingCopyRevision() {
return '.';
}
diff --git a/src/workflow/ArcanistAmendWorkflow.php b/src/workflow/ArcanistAmendWorkflow.php
--- a/src/workflow/ArcanistAmendWorkflow.php
+++ b/src/workflow/ArcanistAmendWorkflow.php
@@ -164,8 +164,6 @@
->execute();
}
- return;
-
if ($api->getUncommittedChanges()) {
// TODO: Make this class of error show the uncommitted changes.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 12, 10:37 PM (3 d, 5 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7706251
Default Alt Text
D21716.id51763.diff (7 KB)
Attached To
Mode
D21716: Update ArcanistMercurialAPI to support getting the current commit ref
Attached
Detach File
Event Timeline
Log In to Comment