2020-06-09 19:23:25 +02:00
|
|
|
from __future__ import absolute_import
|
2020-07-07 00:24:30 +02:00
|
|
|
import sys
|
|
|
|
|
|
|
|
is_python_3 = sys.version_info[0] >= 3
|
|
|
|
|
|
|
|
if is_python_3:
|
|
|
|
def arc_items(dict):
|
|
|
|
return dict.items()
|
|
|
|
else:
|
|
|
|
def arc_items(dict):
|
|
|
|
return dict.iteritems()
|
2020-06-09 19:23:25 +02:00
|
|
|
|
|
|
|
import os
|
|
|
|
import json
|
|
|
|
|
|
|
|
from mercurial import (
|
|
|
|
cmdutil,
|
|
|
|
bookmarks,
|
|
|
|
bundlerepo,
|
|
|
|
error,
|
|
|
|
hg,
|
|
|
|
i18n,
|
|
|
|
node,
|
|
|
|
)
|
|
|
|
|
|
|
|
_ = i18n._
|
|
|
|
cmdtable = {}
|
Update "arc diff" to amend non-head commits with Mercurial
Summary:
After `arc diff` creates a revision in Phabricator it amends the commit to include a link to the revision in the commit message. For Mercurial this is done with `hg commit --amend --logfile` however this will fail when trying to create a diff for a non-head commit.
This updates `ArcanistMercurialAPI::amendCommit()` to allow amending a non-head commit in two ways, depending on whether `evolve` is in use:
No evolve:
1. Rebasing the current commit onto the current commit's parent, using the new commit message
2. Rebasing all children + descendants of the current commit onto the new resulting commit
3. Stripping the original commit
With evolve:
1. Amend the commit with `hg amend --logfile`
2. Run `hg evolve` to tidy up all commits
Test Plan:
I created 6 commits in a row placing a bookmark at commits 2 `bookmark1`, 4 `bookmark2`, and 6 `bookmark3`, and ensured I had `arc:bookmark` in my base ruleset.
No evolve, non-head changeset:
1. I verified I did not have `evolve` enabled by running `hg debugextensions` and did not see `evolve` in the listed active extensions.
2. I updated to `bookmark1` and modified a file to leave a dirty working state.
3. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
4. I checked the status of my repository and verified it was still linear and the bookmarks pointed to the proper commits.
5. I ran `hg log -r bookmark1 --template {desc}` to view the full commit message and verified it contained both `Summary: ...` and `Differential Revision: https://...`.
6. I ran `hg diff -c bookmark1` and verified the changes for that commit included the changes I made in step 2.
No evolve, head changeset:
1. I updated to `bookmark3` which is the head commit and modified a file to leave a dirty working state.
2. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
3. I checked the status of my repository and verified it was still linear and all the bookmarks pointed to the proper commits.
4. I ran `hg log -r bookmark3 --template {desc}` to view the full commit message and verified it contained both `Summary: ...` and `Differential Revision: https://...`.
5. I ran `hg diff -c bookmar3` and verified the changes for that commit included the changes I made in step 1.
With evolve:
1. I enabled `evolve` and verified it was enabled by running `hg debugextensions` and saw `evolve` in the listed active extensions.
2. I updated to `bookmark2` and modified a file to leave a dirty working state.
3. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
4. I checked the status of my repository and verified it was still linear and all the bookmarks pointed to the proper commits.
5. I ran `hg log -r bookmark2 --template {desc}` to view the full commit message and verfieid it contained both `Summary: ...` and `Differential Revision: https://...`.
6. I ran `hg diff -c bookmark2` and verified the changes for that commit included the changes I made in step 2.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin, epriestley
Differential Revision: https://secure.phabricator.com/D21686
2021-07-15 06:14:08 +02:00
|
|
|
|
|
|
|
# Older veresions of Mercurial (~4.7) moved the command function and the
|
|
|
|
# remoteopts object to different modules. Using try/except here to attempt
|
|
|
|
# allowing this module to load properly, despite whether individual commands
|
|
|
|
# will work properly on older versions of Mercurial or not.
|
|
|
|
# https://phab.mercurial-scm.org/rHG46ba2cdda476ac53a8a8f50e4d9435d88267db60
|
|
|
|
# https://phab.mercurial-scm.org/rHG04baab18d60a5c833ab3190506147e01b3c6d12c
|
|
|
|
try:
|
|
|
|
from mercurial import registrar
|
|
|
|
command = registrar.command(cmdtable)
|
|
|
|
except:
|
|
|
|
command = cmdutil.command(cmdtable)
|
|
|
|
|
|
|
|
try:
|
2022-03-11 18:55:56 +01:00
|
|
|
remoteopts = cmdutil.remoteopts
|
Update "arc diff" to amend non-head commits with Mercurial
Summary:
After `arc diff` creates a revision in Phabricator it amends the commit to include a link to the revision in the commit message. For Mercurial this is done with `hg commit --amend --logfile` however this will fail when trying to create a diff for a non-head commit.
This updates `ArcanistMercurialAPI::amendCommit()` to allow amending a non-head commit in two ways, depending on whether `evolve` is in use:
No evolve:
1. Rebasing the current commit onto the current commit's parent, using the new commit message
2. Rebasing all children + descendants of the current commit onto the new resulting commit
3. Stripping the original commit
With evolve:
1. Amend the commit with `hg amend --logfile`
2. Run `hg evolve` to tidy up all commits
Test Plan:
I created 6 commits in a row placing a bookmark at commits 2 `bookmark1`, 4 `bookmark2`, and 6 `bookmark3`, and ensured I had `arc:bookmark` in my base ruleset.
No evolve, non-head changeset:
1. I verified I did not have `evolve` enabled by running `hg debugextensions` and did not see `evolve` in the listed active extensions.
2. I updated to `bookmark1` and modified a file to leave a dirty working state.
3. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
4. I checked the status of my repository and verified it was still linear and the bookmarks pointed to the proper commits.
5. I ran `hg log -r bookmark1 --template {desc}` to view the full commit message and verified it contained both `Summary: ...` and `Differential Revision: https://...`.
6. I ran `hg diff -c bookmark1` and verified the changes for that commit included the changes I made in step 2.
No evolve, head changeset:
1. I updated to `bookmark3` which is the head commit and modified a file to leave a dirty working state.
2. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
3. I checked the status of my repository and verified it was still linear and all the bookmarks pointed to the proper commits.
4. I ran `hg log -r bookmark3 --template {desc}` to view the full commit message and verified it contained both `Summary: ...` and `Differential Revision: https://...`.
5. I ran `hg diff -c bookmar3` and verified the changes for that commit included the changes I made in step 1.
With evolve:
1. I enabled `evolve` and verified it was enabled by running `hg debugextensions` and saw `evolve` in the listed active extensions.
2. I updated to `bookmark2` and modified a file to leave a dirty working state.
3. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
4. I checked the status of my repository and verified it was still linear and all the bookmarks pointed to the proper commits.
5. I ran `hg log -r bookmark2 --template {desc}` to view the full commit message and verfieid it contained both `Summary: ...` and `Differential Revision: https://...`.
6. I ran `hg diff -c bookmark2` and verified the changes for that commit included the changes I made in step 2.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin, epriestley
Differential Revision: https://secure.phabricator.com/D21686
2021-07-15 06:14:08 +02:00
|
|
|
except:
|
|
|
|
from mercurial import commands
|
|
|
|
remoteopts = commands.remoteopts
|
|
|
|
|
2022-03-11 18:55:56 +01:00
|
|
|
try:
|
|
|
|
parseurl = hg.parseurl
|
|
|
|
except:
|
|
|
|
from mercurial import utils
|
|
|
|
parseurl = utils.urlutil.parseurl
|
|
|
|
|
Update "arc diff" to amend non-head commits with Mercurial
Summary:
After `arc diff` creates a revision in Phabricator it amends the commit to include a link to the revision in the commit message. For Mercurial this is done with `hg commit --amend --logfile` however this will fail when trying to create a diff for a non-head commit.
This updates `ArcanistMercurialAPI::amendCommit()` to allow amending a non-head commit in two ways, depending on whether `evolve` is in use:
No evolve:
1. Rebasing the current commit onto the current commit's parent, using the new commit message
2. Rebasing all children + descendants of the current commit onto the new resulting commit
3. Stripping the original commit
With evolve:
1. Amend the commit with `hg amend --logfile`
2. Run `hg evolve` to tidy up all commits
Test Plan:
I created 6 commits in a row placing a bookmark at commits 2 `bookmark1`, 4 `bookmark2`, and 6 `bookmark3`, and ensured I had `arc:bookmark` in my base ruleset.
No evolve, non-head changeset:
1. I verified I did not have `evolve` enabled by running `hg debugextensions` and did not see `evolve` in the listed active extensions.
2. I updated to `bookmark1` and modified a file to leave a dirty working state.
3. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
4. I checked the status of my repository and verified it was still linear and the bookmarks pointed to the proper commits.
5. I ran `hg log -r bookmark1 --template {desc}` to view the full commit message and verified it contained both `Summary: ...` and `Differential Revision: https://...`.
6. I ran `hg diff -c bookmark1` and verified the changes for that commit included the changes I made in step 2.
No evolve, head changeset:
1. I updated to `bookmark3` which is the head commit and modified a file to leave a dirty working state.
2. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
3. I checked the status of my repository and verified it was still linear and all the bookmarks pointed to the proper commits.
4. I ran `hg log -r bookmark3 --template {desc}` to view the full commit message and verified it contained both `Summary: ...` and `Differential Revision: https://...`.
5. I ran `hg diff -c bookmar3` and verified the changes for that commit included the changes I made in step 1.
With evolve:
1. I enabled `evolve` and verified it was enabled by running `hg debugextensions` and saw `evolve` in the listed active extensions.
2. I updated to `bookmark2` and modified a file to leave a dirty working state.
3. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
4. I checked the status of my repository and verified it was still linear and all the bookmarks pointed to the proper commits.
5. I ran `hg log -r bookmark2 --template {desc}` to view the full commit message and verfieid it contained both `Summary: ...` and `Differential Revision: https://...`.
6. I ran `hg diff -c bookmark2` and verified the changes for that commit included the changes I made in step 2.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin, epriestley
Differential Revision: https://secure.phabricator.com/D21686
2021-07-15 06:14:08 +02:00
|
|
|
@command(
|
|
|
|
b'arc-amend',
|
|
|
|
[
|
|
|
|
(b'l',
|
|
|
|
b'logfile',
|
|
|
|
b'',
|
|
|
|
_(b'read commit message from file'),
|
|
|
|
_(b'FILE')),
|
|
|
|
(b'm',
|
|
|
|
b'message',
|
|
|
|
b'',
|
|
|
|
_(b'use text as commit message'),
|
|
|
|
_(b'TEXT')),
|
|
|
|
(b'u',
|
|
|
|
b'user',
|
|
|
|
b'',
|
|
|
|
_(b'record the specified user as committer'),
|
|
|
|
_(b'USER')),
|
|
|
|
(b'd',
|
|
|
|
b'date',
|
|
|
|
b'',
|
|
|
|
_(b'record the specified date as commit date'),
|
|
|
|
_(b'DATE')),
|
|
|
|
(b'A',
|
|
|
|
b'addremove',
|
|
|
|
False,
|
|
|
|
_(b'mark new/missing files as added/removed before committing')),
|
|
|
|
(b'n',
|
|
|
|
b'note',
|
|
|
|
b'',
|
|
|
|
_(b'store a note on amend'),
|
|
|
|
_(b'TEXT')),
|
|
|
|
],
|
|
|
|
_(b'[OPTION]'))
|
|
|
|
def amend(ui, repo, source=None, **opts):
|
|
|
|
"""amend
|
|
|
|
|
|
|
|
Uses Mercurial internal API to amend changes to a non-head commit.
|
|
|
|
|
|
|
|
(This is an Arcanist extension to Mercurial.)
|
|
|
|
|
|
|
|
Returns 0 if amending succeeds, 1 otherwise.
|
|
|
|
"""
|
|
|
|
|
|
|
|
# The option keys seem to come in as 'str' type but the cmdutil.amend() code
|
|
|
|
# expects them as binary. To account for both Python 2 and Python 3
|
|
|
|
# compatibility, insert the value under both 'str' and binary type.
|
|
|
|
newopts = {}
|
|
|
|
for key in opts:
|
|
|
|
val = opts.get(key)
|
|
|
|
newopts[key] = val
|
|
|
|
if isinstance(key, str):
|
|
|
|
newkey = key.encode('UTF-8')
|
|
|
|
newopts[newkey] = val
|
|
|
|
|
|
|
|
orig = repo[b'.']
|
|
|
|
extra = {}
|
|
|
|
pats = []
|
|
|
|
cmdutil.amend(ui, repo, orig, extra, pats, newopts)
|
|
|
|
|
|
|
|
"""
|
|
|
|
# This will allow running amend on older versions of Mercurial, ~3.5, however
|
|
|
|
# the behavior on those versions will squash child commits of the working
|
|
|
|
# directory into the amended commit which is undesired.
|
|
|
|
try:
|
|
|
|
cmdutil.amend(ui, repo, orig, extra, pats, newopts)
|
|
|
|
except:
|
|
|
|
def commitfunc(ui, repo, message, match, opts):
|
|
|
|
return repo.commit(
|
|
|
|
message,
|
|
|
|
opts.get('user') or orig.user(),
|
|
|
|
opts.get('date') or orig.date(),
|
|
|
|
match,
|
|
|
|
extra=extra)
|
|
|
|
cmdutil.amend(ui, repo, commitfunc, orig, extra, pats, newopts)
|
|
|
|
"""
|
|
|
|
|
|
|
|
return 0
|
2020-06-09 19:23:25 +02:00
|
|
|
|
|
|
|
@command(
|
2020-07-07 00:24:30 +02:00
|
|
|
b'arc-ls-markers',
|
Update "arc diff" to amend non-head commits with Mercurial
Summary:
After `arc diff` creates a revision in Phabricator it amends the commit to include a link to the revision in the commit message. For Mercurial this is done with `hg commit --amend --logfile` however this will fail when trying to create a diff for a non-head commit.
This updates `ArcanistMercurialAPI::amendCommit()` to allow amending a non-head commit in two ways, depending on whether `evolve` is in use:
No evolve:
1. Rebasing the current commit onto the current commit's parent, using the new commit message
2. Rebasing all children + descendants of the current commit onto the new resulting commit
3. Stripping the original commit
With evolve:
1. Amend the commit with `hg amend --logfile`
2. Run `hg evolve` to tidy up all commits
Test Plan:
I created 6 commits in a row placing a bookmark at commits 2 `bookmark1`, 4 `bookmark2`, and 6 `bookmark3`, and ensured I had `arc:bookmark` in my base ruleset.
No evolve, non-head changeset:
1. I verified I did not have `evolve` enabled by running `hg debugextensions` and did not see `evolve` in the listed active extensions.
2. I updated to `bookmark1` and modified a file to leave a dirty working state.
3. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
4. I checked the status of my repository and verified it was still linear and the bookmarks pointed to the proper commits.
5. I ran `hg log -r bookmark1 --template {desc}` to view the full commit message and verified it contained both `Summary: ...` and `Differential Revision: https://...`.
6. I ran `hg diff -c bookmark1` and verified the changes for that commit included the changes I made in step 2.
No evolve, head changeset:
1. I updated to `bookmark3` which is the head commit and modified a file to leave a dirty working state.
2. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
3. I checked the status of my repository and verified it was still linear and all the bookmarks pointed to the proper commits.
4. I ran `hg log -r bookmark3 --template {desc}` to view the full commit message and verified it contained both `Summary: ...` and `Differential Revision: https://...`.
5. I ran `hg diff -c bookmar3` and verified the changes for that commit included the changes I made in step 1.
With evolve:
1. I enabled `evolve` and verified it was enabled by running `hg debugextensions` and saw `evolve` in the listed active extensions.
2. I updated to `bookmark2` and modified a file to leave a dirty working state.
3. I ran `arc diff` and when prompted to amend my changes I said "yes", and verified a phab revision was created properly.
4. I checked the status of my repository and verified it was still linear and all the bookmarks pointed to the proper commits.
5. I ran `hg log -r bookmark2 --template {desc}` to view the full commit message and verfieid it contained both `Summary: ...` and `Differential Revision: https://...`.
6. I ran `hg diff -c bookmark2` and verified the changes for that commit included the changes I made in step 2.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: Korvin, epriestley
Differential Revision: https://secure.phabricator.com/D21686
2021-07-15 06:14:08 +02:00
|
|
|
[
|
|
|
|
(b'',
|
|
|
|
b'output',
|
|
|
|
b'',
|
|
|
|
_(b'file to output refs to'),
|
|
|
|
_(b'FILE')),
|
|
|
|
] + remoteopts,
|
2020-07-07 19:12:09 +02:00
|
|
|
_(b'[--output FILENAME] [SOURCE]'))
|
2020-06-10 22:43:08 +02:00
|
|
|
def lsmarkers(ui, repo, source=None, **opts):
|
|
|
|
"""list markers
|
2020-06-09 19:23:25 +02:00
|
|
|
|
2020-06-10 22:43:08 +02:00
|
|
|
Show the current branch heads and bookmarks in the local working copy, or
|
|
|
|
a specified path/URL.
|
2020-06-09 19:23:25 +02:00
|
|
|
|
|
|
|
Markers are printed to stdout in JSON.
|
|
|
|
|
|
|
|
(This is an Arcanist extension to Mercurial.)
|
|
|
|
|
|
|
|
Returns 0 if listing the markers succeeds, 1 otherwise.
|
|
|
|
"""
|
|
|
|
|
2020-06-10 22:43:08 +02:00
|
|
|
if source is None:
|
|
|
|
markers = localmarkers(ui, repo)
|
|
|
|
else:
|
|
|
|
markers = remotemarkers(ui, repo, source, opts)
|
|
|
|
|
2020-07-07 00:24:30 +02:00
|
|
|
for m in markers:
|
|
|
|
if m['name'] != None:
|
|
|
|
m['name'] = m['name'].decode('utf-8')
|
|
|
|
|
|
|
|
if m['node'] != None:
|
|
|
|
m['node'] = m['node'].decode('utf-8')
|
|
|
|
|
|
|
|
if m['description'] != None:
|
|
|
|
m['description'] = m['description'].decode('utf-8')
|
|
|
|
|
2020-06-10 22:43:08 +02:00
|
|
|
json_opts = {
|
|
|
|
'indent': 2,
|
|
|
|
'sort_keys': True,
|
|
|
|
}
|
|
|
|
|
|
|
|
output_file = opts.get('output')
|
|
|
|
if output_file:
|
|
|
|
if os.path.exists(output_file):
|
|
|
|
raise error.Abort(_('File "%s" already exists.' % output_file))
|
|
|
|
with open(output_file, 'w+') as f:
|
|
|
|
json.dump(markers, f, **json_opts)
|
|
|
|
else:
|
2020-07-07 00:24:30 +02:00
|
|
|
json_data = json.dumps(markers, **json_opts)
|
|
|
|
print(json_data)
|
2020-06-10 22:43:08 +02:00
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
def localmarkers(ui, repo):
|
|
|
|
markers = []
|
|
|
|
|
2020-07-07 00:24:30 +02:00
|
|
|
active_node = repo[b'.'].node()
|
2020-06-10 22:43:08 +02:00
|
|
|
all_heads = set(repo.heads())
|
|
|
|
current_name = repo.dirstate.branch()
|
|
|
|
|
|
|
|
branch_list = repo.branchmap().iterbranches()
|
|
|
|
for branch_name, branch_heads, tip_node, is_closed in branch_list:
|
|
|
|
for head_node in branch_heads:
|
|
|
|
|
When saving and restoring local state in Mercurial, also save and restore bookmarks
Summary:
Ref PHI1808. In Mercurial, we must save and restore bookmark state explicitly.
- Save and restore bookmarks.
- Clean up concepts in "arc-ls-markers" slightly, so we don't need separate "isCurrent" and "isActive" flags, hopefully.
I believe the totality of Mercurial state is:
- A (non-bare) working copy points at exactly one commit (which might be the empty/null commit, in an empty repository).
- A working copy has exactly one active branch.
- Each branch has zero or more heads.
- Each head may be closed.
- Each (non-null) commit belongs to exactly one branch.
- Note that the active branch may have zero heads and zero commits which belong to it!
- A working copy has zero or one active bookmark.
To capture this, we now emit:
- A list of branch heads. If a branch head is a working copy commit, that head is flagged as active.
- A list of bookmarks. If a bookmark is the current bookmark, that bookmark is flagged as active.
- A single "branch-state" virtual marker. This covers the case where you have run "hg branch X" to create X, but no objects in the working copy actually correspond to X yet. It also covers the case where you are on a concrete branch, but not any head of that branch.
- A single "commit-state" virtual marker. This always shows the current commit in the working copy.
Test Plan:
- Useful states to test are:
- Empty repository (not all commands currently work here).
- Normal repository, on a bookmark.
- Normal repository, no bookmark.
- "hg up 123" to update to somewhere in history.
- "hg branch X", to start a new branch with no commits.
- Ran "arc branches" and "arc bookmarks" in various states. Saw generally sensible output.
- Ran "arc land --hold ..." in various states against a failing remote. Saw generally sensible output, and saw working properly restored to the original state.
Differential Revision: https://secure.phabricator.com/D21396
2020-07-08 23:10:00 +02:00
|
|
|
is_active = False
|
|
|
|
if branch_name == current_name:
|
|
|
|
if head_node == active_node:
|
|
|
|
is_active = True
|
2020-06-10 22:43:08 +02:00
|
|
|
|
When saving and restoring local state in Mercurial, also save and restore bookmarks
Summary:
Ref PHI1808. In Mercurial, we must save and restore bookmark state explicitly.
- Save and restore bookmarks.
- Clean up concepts in "arc-ls-markers" slightly, so we don't need separate "isCurrent" and "isActive" flags, hopefully.
I believe the totality of Mercurial state is:
- A (non-bare) working copy points at exactly one commit (which might be the empty/null commit, in an empty repository).
- A working copy has exactly one active branch.
- Each branch has zero or more heads.
- Each head may be closed.
- Each (non-null) commit belongs to exactly one branch.
- Note that the active branch may have zero heads and zero commits which belong to it!
- A working copy has zero or one active bookmark.
To capture this, we now emit:
- A list of branch heads. If a branch head is a working copy commit, that head is flagged as active.
- A list of bookmarks. If a bookmark is the current bookmark, that bookmark is flagged as active.
- A single "branch-state" virtual marker. This covers the case where you have run "hg branch X" to create X, but no objects in the working copy actually correspond to X yet. It also covers the case where you are on a concrete branch, but not any head of that branch.
- A single "commit-state" virtual marker. This always shows the current commit in the working copy.
Test Plan:
- Useful states to test are:
- Empty repository (not all commands currently work here).
- Normal repository, on a bookmark.
- Normal repository, no bookmark.
- "hg up 123" to update to somewhere in history.
- "hg branch X", to start a new branch with no commits.
- Ran "arc branches" and "arc bookmarks" in various states. Saw generally sensible output.
- Ran "arc land --hold ..." in various states against a failing remote. Saw generally sensible output, and saw working properly restored to the original state.
Differential Revision: https://secure.phabricator.com/D21396
2020-07-08 23:10:00 +02:00
|
|
|
is_tip = (head_node == tip_node)
|
2020-06-10 22:43:08 +02:00
|
|
|
|
|
|
|
if is_closed:
|
|
|
|
head_closed = True
|
|
|
|
else:
|
|
|
|
head_closed = bool(head_node not in all_heads)
|
|
|
|
|
|
|
|
description = repo[head_node].description()
|
|
|
|
|
|
|
|
markers.append({
|
|
|
|
'type': 'branch',
|
|
|
|
'name': branch_name,
|
|
|
|
'node': node.hex(head_node),
|
|
|
|
'isActive': is_active,
|
|
|
|
'isClosed': head_closed,
|
|
|
|
'isTip': is_tip,
|
|
|
|
'description': description,
|
|
|
|
})
|
|
|
|
|
|
|
|
bookmarks = repo._bookmarks
|
|
|
|
active_bookmark = repo._activebookmark
|
|
|
|
|
2020-07-07 00:24:30 +02:00
|
|
|
for bookmark_name, bookmark_node in arc_items(bookmarks):
|
2020-06-10 22:43:08 +02:00
|
|
|
is_active = (active_bookmark == bookmark_name)
|
|
|
|
description = repo[bookmark_node].description()
|
|
|
|
|
|
|
|
markers.append({
|
|
|
|
'type': 'bookmark',
|
|
|
|
'name': bookmark_name,
|
|
|
|
'node': node.hex(bookmark_node),
|
|
|
|
'isActive': is_active,
|
|
|
|
'description': description,
|
|
|
|
})
|
|
|
|
|
When saving and restoring local state in Mercurial, also save and restore bookmarks
Summary:
Ref PHI1808. In Mercurial, we must save and restore bookmark state explicitly.
- Save and restore bookmarks.
- Clean up concepts in "arc-ls-markers" slightly, so we don't need separate "isCurrent" and "isActive" flags, hopefully.
I believe the totality of Mercurial state is:
- A (non-bare) working copy points at exactly one commit (which might be the empty/null commit, in an empty repository).
- A working copy has exactly one active branch.
- Each branch has zero or more heads.
- Each head may be closed.
- Each (non-null) commit belongs to exactly one branch.
- Note that the active branch may have zero heads and zero commits which belong to it!
- A working copy has zero or one active bookmark.
To capture this, we now emit:
- A list of branch heads. If a branch head is a working copy commit, that head is flagged as active.
- A list of bookmarks. If a bookmark is the current bookmark, that bookmark is flagged as active.
- A single "branch-state" virtual marker. This covers the case where you have run "hg branch X" to create X, but no objects in the working copy actually correspond to X yet. It also covers the case where you are on a concrete branch, but not any head of that branch.
- A single "commit-state" virtual marker. This always shows the current commit in the working copy.
Test Plan:
- Useful states to test are:
- Empty repository (not all commands currently work here).
- Normal repository, on a bookmark.
- Normal repository, no bookmark.
- "hg up 123" to update to somewhere in history.
- "hg branch X", to start a new branch with no commits.
- Ran "arc branches" and "arc bookmarks" in various states. Saw generally sensible output.
- Ran "arc land --hold ..." in various states against a failing remote. Saw generally sensible output, and saw working properly restored to the original state.
Differential Revision: https://secure.phabricator.com/D21396
2020-07-08 23:10:00 +02:00
|
|
|
# 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(),
|
|
|
|
})
|
2020-06-10 22:43:08 +02:00
|
|
|
|
|
|
|
return markers
|
|
|
|
|
|
|
|
def remotemarkers(ui, repo, source, opts):
|
2020-06-09 19:23:25 +02:00
|
|
|
# Disable status output from fetching a remote.
|
|
|
|
ui.quiet = True
|
|
|
|
|
2020-06-10 22:43:08 +02:00
|
|
|
markers = []
|
|
|
|
|
2023-05-18 02:43:52 +02:00
|
|
|
# Determine the remote to use based on the default path configured in
|
|
|
|
# [ui.paths] for this local repository.
|
|
|
|
#
|
|
|
|
# The expandpath function in the ui module was deprecated in 5.8 and removed
|
|
|
|
# in 6.4. NOTE: There is also an expandpath function in mercurial.util (not
|
|
|
|
# plural mercurial.utils...) however that function behaves differently from
|
|
|
|
# the old ui.expandpath. Reviewing the source comments for the old
|
|
|
|
# ui.expandpath function points to using urilutils.get_ functions.
|
|
|
|
try:
|
|
|
|
remote_path, branches = parseurl(ui.expandpath(source))
|
|
|
|
except:
|
|
|
|
from mercurial import utils
|
|
|
|
origsource, remote_path, branch = utils.urlutil.get_clone_path(ui, source)
|
|
|
|
|
|
|
|
remote = hg.peer(repo, opts, remote_path)
|
2020-06-09 19:23:25 +02:00
|
|
|
|
2020-06-11 00:30:51 +02:00
|
|
|
with remote.commandexecutor() as e:
|
2020-07-07 19:12:09 +02:00
|
|
|
branchmap = e.callcommand(b'branchmap', {}).result()
|
2020-06-11 00:30:51 +02:00
|
|
|
|
|
|
|
for branch_name in branchmap:
|
|
|
|
for branch_node in branchmap[branch_name]:
|
2020-06-09 19:23:25 +02:00
|
|
|
markers.append({
|
|
|
|
'type': 'branch',
|
2020-06-11 00:30:51 +02:00
|
|
|
'name': branch_name,
|
|
|
|
'node': node.hex(branch_node),
|
2020-07-07 19:12:09 +02:00
|
|
|
'description': None,
|
2020-06-09 19:23:25 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
with remote.commandexecutor() as e:
|
2020-07-07 19:12:09 +02:00
|
|
|
remotemarks = bookmarks.unhexlifybookmarks(e.callcommand(b'listkeys', {
|
|
|
|
b'namespace': b'bookmarks',
|
2020-06-09 19:23:25 +02:00
|
|
|
}).result())
|
|
|
|
|
|
|
|
for mark in remotemarks:
|
|
|
|
markers.append({
|
|
|
|
'type': 'bookmark',
|
|
|
|
'name': mark,
|
|
|
|
'node': node.hex(remotemarks[mark]),
|
2020-07-07 19:12:09 +02:00
|
|
|
'description': None,
|
2020-06-09 19:23:25 +02:00
|
|
|
})
|
|
|
|
|
2020-06-10 22:43:08 +02:00
|
|
|
return markers
|