Page MenuHomePhabricator

D21396.id50932.diff
No OneTemporary

D21396.id50932.diff

diff --git a/src/repository/marker/ArcanistMarkerRef.php b/src/repository/marker/ArcanistMarkerRef.php
--- a/src/repository/marker/ArcanistMarkerRef.php
+++ b/src/repository/marker/ArcanistMarkerRef.php
@@ -9,6 +9,8 @@
const TYPE_BRANCH = 'branch';
const TYPE_BOOKMARK = 'bookmark';
+ const TYPE_COMMIT_STATE = 'commit-state';
+ const TYPE_BRANCH_STATE = 'branch-state';
private $name;
private $markerType;
@@ -148,6 +150,14 @@
return ($this->getMarkerType() === self::TYPE_BRANCH);
}
+ public function isCommitState() {
+ return ($this->getMarkerType() === self::TYPE_COMMIT_STATE);
+ }
+
+ public function isBranchState() {
+ return ($this->getMarkerType() === self::TYPE_BRANCH_STATE);
+ }
+
public function attachCommitRef(ArcanistCommitRef $ref) {
return $this->attachHardpoint(self::HARDPOINT_COMMITREF, $ref);
}
diff --git a/src/repository/marker/ArcanistMercurialRepositoryMarkerQuery.php b/src/repository/marker/ArcanistMercurialRepositoryMarkerQuery.php
--- a/src/repository/marker/ArcanistMercurialRepositoryMarkerQuery.php
+++ b/src/repository/marker/ArcanistMercurialRepositoryMarkerQuery.php
@@ -71,10 +71,6 @@
}
$node = $item['node'];
- if (!$node) {
- // NOTE: For now, we ignore the virtual "current branch" marker.
- continue;
- }
switch ($item['type']) {
case 'branch':
@@ -83,8 +79,11 @@
case 'bookmark':
$marker_type = ArcanistMarkerRef::TYPE_BOOKMARK;
break;
- case 'commit':
- $marker_type = null;
+ case 'commit-state':
+ $marker_type = ArcanistMarkerRef::TYPE_COMMIT_STATE;
+ break;
+ case 'branch-state':
+ $marker_type = ArcanistMarkerRef::TYPE_BRANCH_STATE;
break;
default:
throw new Exception(
@@ -94,11 +93,6 @@
$item['type']));
}
- if ($marker_type === null) {
- // NOTE: For now, we ignore the virtual "head" marker.
- continue;
- }
-
$commit_ref = $api->newCommitRef()
->setCommitHash($node);
diff --git a/src/repository/state/ArcanistMercurialLocalState.php b/src/repository/state/ArcanistMercurialLocalState.php
--- a/src/repository/state/ArcanistMercurialLocalState.php
+++ b/src/repository/state/ArcanistMercurialLocalState.php
@@ -5,40 +5,105 @@
private $localCommit;
private $localBranch;
+ private $localBookmark;
protected function executeSaveLocalState() {
$api = $this->getRepositoryAPI();
$log = $this->getWorkflow()->getLogEngine();
- // TODO: Both of these can be pulled from "hg arc-ls-markers" more
- // efficiently.
-
- $this->localCommit = $api->getCanonicalRevisionName('.');
-
- list($branch) = $api->execxLocal('branch');
- $this->localBranch = trim($branch);
-
- $log->writeTrace(
- pht('SAVE STATE'),
- pht(
+ $markers = $api->newMarkerRefQuery()
+ ->execute();
+
+ $local_commit = null;
+ foreach ($markers as $marker) {
+ if ($marker->isCommitState()) {
+ $local_commit = $marker->getCommitHash();
+ }
+ }
+
+ if ($local_commit === null) {
+ throw new Exception(
+ pht(
+ 'Unable to identify the current commit in the working copy.'));
+ }
+
+ $this->localCommit = $local_commit;
+
+ $local_branch = null;
+ foreach ($markers as $marker) {
+ if ($marker->isBranchState()) {
+ $local_branch = $marker->getName();
+ break;
+ }
+ }
+
+ if ($local_branch === null) {
+ throw new Exception(
+ pht(
+ 'Unable to identify the current branch in the working copy.'));
+ }
+
+ if ($local_branch !== null) {
+ $this->localBranch = $local_branch;
+ }
+
+ $local_bookmark = null;
+ foreach ($markers as $marker) {
+ if ($marker->isBookmark()) {
+ if ($marker->getIsActive()) {
+ $local_bookmark = $marker->getName();
+ break;
+ }
+ }
+ }
+
+ if ($local_bookmark !== null) {
+ $this->localBookmark = $local_bookmark;
+ }
+
+ $has_bookmark = ($this->localBookmark !== null);
+
+ if ($has_bookmark) {
+ $location = pht(
+ 'Saving local state (at "%s" on branch "%s", bookmarked as "%s").',
+ $api->getDisplayHash($this->localCommit),
+ $this->localBranch,
+ $this->localBookmark);
+ } else {
+ $location = pht(
'Saving local state (at "%s" on branch "%s").',
$api->getDisplayHash($this->localCommit),
- $this->localBranch));
+ $this->localBranch);
+ }
+
+ $log->writeTrace(pht('SAVE STATE'), $location);
}
protected function executeRestoreLocalState() {
$api = $this->getRepositoryAPI();
$log = $this->getWorkflow()->getLogEngine();
- $log->writeStatus(
- pht('LOAD STATE'),
- pht(
+ if ($this->localBookmark !== null) {
+ $location = pht(
+ 'Restoring local state (at "%s" on branch "%s", bookmarked as "%s").',
+ $api->getDisplayHash($this->localCommit),
+ $this->localBranch,
+ $this->localBookmark);
+ } else {
+ $location = pht(
'Restoring local state (at "%s" on branch "%s").',
$api->getDisplayHash($this->localCommit),
- $this->localBranch));
+ $this->localBranch);
+ }
+
+ $log->writeStatus(pht('LOAD STATE'), $location);
$api->execxLocal('update -- %s', $this->localCommit);
$api->execxLocal('branch --force -- %s', $this->localBranch);
+
+ if ($this->localBookmark !== null) {
+ $api->execxLocal('bookmark --force -- %s', $this->localBookmark);
+ }
}
protected function executeDiscardLocalState() {
@@ -70,6 +135,12 @@
'hg branch --force -- %s',
$this->localBranch);
+ if ($this->localBookmark !== null) {
+ $commands[] = csprintf(
+ 'hg bookmark --force -- %s',
+ $this->localBookmark);
+ }
+
return $commands;
}
diff --git a/support/hg/arc-hg.py b/support/hg/arc-hg.py
--- a/support/hg/arc-hg.py
+++ b/support/hg/arc-hg.py
@@ -85,21 +85,17 @@
active_node = repo[b'.'].node()
all_heads = set(repo.heads())
current_name = repo.dirstate.branch()
- saw_current = False
- saw_active = False
branch_list = repo.branchmap().iterbranches()
for branch_name, branch_heads, tip_node, is_closed in branch_list:
for head_node in branch_heads:
- is_active = (head_node == active_node)
- is_tip = (head_node == tip_node)
- is_current = (branch_name == current_name)
- if is_current:
- saw_current = True
+ is_active = False
+ if branch_name == current_name:
+ if head_node == active_node:
+ is_active = True
- if is_active:
- saw_active = True
+ is_tip = (head_node == tip_node)
if is_closed:
head_closed = True
@@ -115,26 +111,9 @@
'isActive': is_active,
'isClosed': head_closed,
'isTip': is_tip,
- 'isCurrent': is_current,
'description': description,
})
- # If the current branch (selected with "hg branch X") is not reflected in
- # the list of heads we selected, add a virtual head for it so callers get
- # a complete picture of repository marker state.
-
- if not saw_current:
- markers.append({
- 'type': 'branch',
- 'name': current_name,
- 'node': None,
- 'isActive': False,
- 'isClosed': False,
- 'isTip': False,
- 'isCurrent': True,
- 'description': None,
- })
-
bookmarks = repo._bookmarks
active_bookmark = repo._activebookmark
@@ -142,9 +121,6 @@
is_active = (active_bookmark == bookmark_name)
description = repo[bookmark_node].description()
- if is_active:
- saw_active = True
-
markers.append({
'type': 'bookmark',
'name': bookmark_name,
@@ -153,21 +129,36 @@
'description': description,
})
- # If the current working copy state is not the head of a branch and there is
- # also no active bookmark, add a virtual marker for it so callers can figure
- # out exactly where we are.
-
- if not saw_active:
- markers.append({
- 'type': 'commit',
- 'name': None,
- 'node': node.hex(active_node),
- 'isActive': False,
- 'isClosed': False,
- 'isTip': False,
- 'isCurrent': True,
- 'description': repo[b'.'].description(),
- })
+ # Add virtual markers for the current commit state and current branch state
+ # so callers can figure out exactly where we are.
+
+ # Common cases where this matters include:
+
+ # You run "hg update 123" to update to an older revision. Your working
+ # copy commit will not be a branch head or a bookmark.
+
+ # You run "hg branch X" to create a new branch, but have not made any commits
+ # yet. Your working copy branch will not be reflected in any commits.
+
+ markers.append({
+ 'type': 'branch-state',
+ 'name': current_name,
+ 'node': None,
+ 'isActive': True,
+ 'isClosed': False,
+ 'isTip': False,
+ 'description': None,
+ })
+
+ markers.append({
+ 'type': 'commit-state',
+ 'name': None,
+ 'node': node.hex(active_node),
+ 'isActive': True,
+ 'isClosed': False,
+ 'isTip': False,
+ 'description': repo[b'.'].description(),
+ })
return markers

File Metadata

Mime Type
text/plain
Expires
Thu, May 9, 4:57 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6265915
Default Alt Text
D21396.id50932.diff (9 KB)

Event Timeline