##// END OF EJS Templates
wireproto: separate commands tables for version 1 and 2 commands...
wireproto: separate commands tables for version 1 and 2 commands We can't easily reuse existing command handlers for version 2 commands because the response types will be different. e.g. many commands return nodes encoded as hex. Our new wire protocol is binary safe, so we'll wish to encode nodes as binary. We /could/ teach each command handler to look at the protocol handler and change behavior based on the version in use. However, this would make logic a bit unwieldy over time and would make it harder to design a unified protocol handler interface. I think it's better to create a clean break between version 1 and version 2 of commands on the server. What I imagine happening is we will have separate @wireprotocommand functions for each protocol generation. Those functions will parse the request, dispatch to a common function to process it, then generate the response in its own, transport-specific manner. This commit establishes a separate table for tracking version 1 commands from version 2 commands. The HTTP server pieces have been updated to use this new table. Most commands are marked as both version 1 and version 2, so there is little practical impact to this change. A side-effect of this change is we now rely on transport registration in wireprototypes.TRANSPORTS and certain properties of the protocol interface. So a test had to be updated to conform. Differential Revision: https://phab.mercurial-scm.org/D2982

File last commit:

r37022:68fcc550 default
r37311:45b39c69 default
Show More
destutil.py
415 lines | 15.2 KiB | text/x-python | PythonLexer
Pierre-Yves David
update: move default destination computation to a function...
r26569 # destutil.py - Mercurial utility function for command destination
#
# Copyright Matt Mackall <mpm@selenic.com> and other
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Gregory Szorc
destutil: use absolute_import
r27333 from __future__ import absolute_import
Pierre-Yves David
update: move default destination computation to a function...
r26569 from .i18n import _
from . import (
Pierre-Yves David
destupdate: also include bookmark related logic...
r26641 bookmarks,
Pierre-Yves David
update: move default destination computation to a function...
r26569 error,
obsutil: move 'successorssets' to the new modules...
r33143 obsutil,
Yuya Nishihara
scmutil: proxy revrange() through repo to break import cycles...
r31025 scmutil,
Boris Feld
show: use the new stack definition for show stack...
r37020 stack
Pierre-Yves David
update: move default destination computation to a function...
r26569 )
Martin von Zweigbergk
destutil: drop now-unused "check" parameter from destupdate()
r30962 def _destupdateobs(repo, clean):
Pierre-Yves David
destupdate: extract logic based on obsolescence marker in its own function...
r26723 """decide of an update destination from obsolescence markers"""
Pierre-Yves David
update: move default destination computation to a function...
r26569 node = None
wc = repo[None]
p1 = wc.p1()
Pierre-Yves David
destupdate: extract logic based on obsolescence marker in its own function...
r26723 movemark = None
Pierre-Yves David
update: move default destination computation to a function...
r26569
if p1.obsolete() and not p1.children():
# allow updating to successors
obsutil: move 'successorssets' to the new modules...
r33143 successors = obsutil.successorssets(repo, p1.node())
Pierre-Yves David
update: move default destination computation to a function...
r26569
# behavior of certain cases is as follows,
#
# divergent changesets: update to highest rev, similar to what
# is currently done when there are more than one head
# (i.e. 'tip')
#
# replaced changesets: same as divergent except we know there
# is no conflict
#
# pruned changeset: no update is done; though, we could
# consider updating to the first non-obsolete parent,
# similar to what is current done for 'hg prune'
if successors:
# flatten the list here handles both divergent (len > 1)
# and the usual case (len = 1)
successors = [n for sub in successors for n in sub]
# get the max revision for the given successors set,
# i.e. the 'tip' of a set
node = repo.revs('max(%ln)', successors).first()
Pierre-Yves David
destupdate: move obsolete handling first...
r26722 if bookmarks.isactivewdirparent(repo):
movemark = repo['.'].node()
Pierre-Yves David
destupdate: extract logic based on obsolescence marker in its own function...
r26723 return node, movemark, None
Martin von Zweigbergk
destutil: drop now-unused "check" parameter from destupdate()
r30962 def _destupdatebook(repo, clean):
Pierre-Yves David
destupdate: extract logic based on bookmarks in its own function...
r26724 """decide on an update destination from active bookmark"""
# we also move the active bookmark, if any
activemark = None
node, movemark = bookmarks.calculateupdate(repo.ui, repo, None)
if node is not None:
activemark = node
return node, movemark, activemark
Martin von Zweigbergk
destutil: drop now-unused "check" parameter from destupdate()
r30962 def _destupdatebranch(repo, clean):
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 """decide on an update destination from current branch
This ignores closed branch heads.
"""
Pierre-Yves David
destupdate: extract logic based on branch in its own function...
r26725 wc = repo[None]
movemark = node = None
FUJIWARA Katsunori
destutil: replace wc.branch() invocations by cached value for efficiency
r28235 currentbranch = wc.branch()
liscju
update: fix bare --clean to work on new branch (issue5003) (BC)...
r29284
if clean:
currentbranch = repo['.'].branch()
FUJIWARA Katsunori
destutil: use cached branch information instead of query for efficiency...
r28236 if currentbranch in repo.branchmap():
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 heads = repo.branchheads(currentbranch)
FUJIWARA Katsunori
destutil: use cached branch information instead of query for efficiency...
r28236 if heads:
node = repo.revs('max(.::(%ln))', heads).first()
Pierre-Yves David
destupdate: extract logic based on branch in its own function...
r26725 if bookmarks.isactivewdirparent(repo):
movemark = repo['.'].node()
Yuya Nishihara
update: resurrect bare update from null parent to tip-most branch head...
r28924 elif currentbranch == 'default' and not wc.p1():
# "null" parent belongs to "default" branch, but it doesn't exist, so
# update to the tipmost non-closed branch head
node = repo.revs('max(head() and not closed())').first()
FUJIWARA Katsunori
destutil: use cached branch information instead of query for efficiency...
r28236 else:
liscju
update: fix bare update to work on new branch...
r28903 node = repo['.'].node()
Pierre-Yves David
destupdate: extract logic based on branch in its own function...
r26725 return node, movemark, None
Martin von Zweigbergk
destutil: drop now-unused "check" parameter from destupdate()
r30962 def _destupdatebranchfallback(repo, clean):
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 """decide on an update destination from closed heads in current branch"""
wc = repo[None]
currentbranch = wc.branch()
movemark = None
if currentbranch in repo.branchmap():
# here, all descendant branch heads are closed
heads = repo.branchheads(currentbranch, closed=True)
assert heads, "any branch has at least one head"
node = repo.revs('max(.::(%ln))', heads).first()
assert node is not None, ("any revision has at least "
"one descendant branch head")
if bookmarks.isactivewdirparent(repo):
movemark = repo['.'].node()
else:
# here, no "default" branch, and all branches are closed
node = repo.lookup('tip')
assert node is not None, "'tip' exists even in empty repository"
return node, movemark, None
Mads Kiilerich
spelling: fixes of non-dictionary words
r30332 # order in which each step should be evaluated
Pierre-Yves David
destupdate: have a generic and extensible way to run each step...
r26726 # steps are run until one finds a destination
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 destupdatesteps = ['evolution', 'bookmark', 'branch', 'branchfallback']
Pierre-Yves David
destupdate: have a generic and extensible way to run each step...
r26726 # mapping to ease extension overriding steps.
destupdatestepmap = {'evolution': _destupdateobs,
'bookmark': _destupdatebook,
'branch': _destupdatebranch,
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 'branchfallback': _destupdatebranchfallback,
Pierre-Yves David
destupdate: have a generic and extensible way to run each step...
r26726 }
Martin von Zweigbergk
destutil: drop now-unused "check" parameter from destupdate()
r30962 def destupdate(repo, clean=False):
Pierre-Yves David
destupdate: extract logic based on obsolescence marker in its own function...
r26723 """destination for bare update operation
return (rev, movemark, activemark)
- rev: the revision to update to,
- movemark: node to move the active bookmark from
(cf bookmark.calculate update),
- activemark: a bookmark to activate at the end of the update.
"""
Pierre-Yves David
destupdate: have a generic and extensible way to run each step...
r26726 node = movemark = activemark = None
Pierre-Yves David
destupdate: extract logic based on obsolescence marker in its own function...
r26723
Pierre-Yves David
destupdate: have a generic and extensible way to run each step...
r26726 for step in destupdatesteps:
Martin von Zweigbergk
destutil: drop now-unused "check" parameter from destupdate()
r30962 node, movemark, activemark = destupdatestepmap[step](repo, clean)
Pierre-Yves David
destupdate: have a generic and extensible way to run each step...
r26726 if node is not None:
break
Pierre-Yves David
destupdate: move the check related to the "clean" logic in the function...
r26628 rev = repo[node].rev()
Pierre-Yves David
destupdate: also include bookmark related logic...
r26641 return rev, movemark, activemark
Pierre-Yves David
destutil: move default merge destination into a function...
r26714
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 msgdestmerge = {
# too many matching divergent bookmark
'toomanybookmarks':
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 {'merge':
(_("multiple matching bookmarks to merge -"
" please merge with an explicit rev or bookmark"),
_("run 'hg heads' to see all heads")),
Pierre-Yves David
rebase: choose default destination the same way as 'hg merge' (BC)...
r28189 'rebase':
(_("multiple matching bookmarks to rebase -"
" please rebase to an explicit rev or bookmark"),
_("run 'hg heads' to see all heads")),
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 },
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # no other matching divergent bookmark
'nootherbookmarks':
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 {'merge':
(_("no matching bookmark to merge - "
"please merge with an explicit rev or bookmark"),
_("run 'hg heads' to see all heads")),
Pierre-Yves David
rebase: choose default destination the same way as 'hg merge' (BC)...
r28189 'rebase':
(_("no matching bookmark to rebase - "
"please rebase to an explicit rev or bookmark"),
_("run 'hg heads' to see all heads")),
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 },
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # branch have too many unbookmarked heads, no obvious destination
'toomanyheads':
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 {'merge':
(_("branch '%s' has %d heads - please merge with an explicit rev"),
_("run 'hg heads .' to see heads")),
Pierre-Yves David
rebase: choose default destination the same way as 'hg merge' (BC)...
r28189 'rebase':
(_("branch '%s' has %d heads - please rebase to an explicit rev"),
_("run 'hg heads .' to see heads")),
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 },
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # branch have no other unbookmarked heads
'bookmarkedheads':
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 {'merge':
(_("heads are bookmarked - please merge with an explicit rev"),
_("run 'hg heads' to see all heads")),
Pierre-Yves David
rebase: choose default destination the same way as 'hg merge' (BC)...
r28189 'rebase':
(_("heads are bookmarked - please rebase to an explicit rev"),
_("run 'hg heads' to see all heads")),
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 },
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # branch have just a single heads, but there is other branches
'nootherbranchheads':
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 {'merge':
(_("branch '%s' has one head - please merge with an explicit rev"),
_("run 'hg heads' to see all heads")),
Pierre-Yves David
rebase: choose default destination the same way as 'hg merge' (BC)...
r28189 'rebase':
(_("branch '%s' has one head - please rebase to an explicit rev"),
_("run 'hg heads' to see all heads")),
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 },
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # repository have a single head
'nootherheads':
Pierre-Yves David
rebase: choose default destination the same way as 'hg merge' (BC)...
r28189 {'merge':
(_('nothing to merge'),
None),
'rebase':
(_('nothing to rebase'),
None),
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 },
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # repository have a single head and we are not on it
'nootherheadsbehind':
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 {'merge':
(_('nothing to merge'),
_("use 'hg update' instead")),
Pierre-Yves David
rebase: choose default destination the same way as 'hg merge' (BC)...
r28189 'rebase':
(_('nothing to rebase'),
_("use 'hg update' instead")),
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 },
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # We are not on a head
'notatheads':
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 {'merge':
(_('working directory not at a head revision'),
Pierre-Yves David
rebase: choose default destination the same way as 'hg merge' (BC)...
r28189 _("use 'hg update' or merge with an explicit revision")),
'rebase':
(_('working directory not at a head revision'),
_("use 'hg update' or rebase to an explicit revision"))
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 },
Pierre-Yves David
destutil: allow to specify an explicit source for the merge...
r28139 'emptysourceset':
{'merge':
(_('source set is empty'),
Pierre-Yves David
rebase: choose default destination the same way as 'hg merge' (BC)...
r28189 None),
'rebase':
(_('source set is empty'),
None),
Pierre-Yves David
destutil: allow to specify an explicit source for the merge...
r28139 },
'multiplebranchessourceset':
{'merge':
(_('source set is rooted in multiple branches'),
Pierre-Yves David
rebase: choose default destination the same way as 'hg merge' (BC)...
r28189 None),
'rebase':
(_('rebaseset is rooted in multiple named branches'),
_('specify an explicit destination with --dest')),
Pierre-Yves David
destutil: allow to specify an explicit source for the merge...
r28139 },
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 }
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102
Pierre-Yves David
destutil: add the ability to specify a search space for rebase destination...
r29043 def _destmergebook(repo, action='merge', sourceset=None, destspace=None):
Pierre-Yves David
destmerge: extract logic based on bookmark into its own function...
r26727 """find merge destination in the active bookmark case"""
node = None
Augie Fackler
localrepo: extract bookmarkheads method to bookmarks.py...
r32381 bmheads = bookmarks.headsforactive(repo)
Pierre-Yves David
destmerge: extract logic based on bookmark into its own function...
r26727 curhead = repo[repo._activebookmark].node()
if len(bmheads) == 2:
if curhead == bmheads[0]:
node = bmheads[1]
else:
node = bmheads[0]
elif len(bmheads) > 2:
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 msg, hint = msgdestmerge['toomanybookmarks'][action]
Pierre-Yves David
destutil: add more precise error classes for destmerge...
r28141 raise error.ManyMergeDestAbort(msg, hint=hint)
Pierre-Yves David
destmerge: extract logic based on bookmark into its own function...
r26727 elif len(bmheads) <= 1:
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 msg, hint = msgdestmerge['nootherbookmarks'][action]
Pierre-Yves David
destutil: add more precise error classes for destmerge...
r28141 raise error.NoMergeDestAbort(msg, hint=hint)
Pierre-Yves David
destmerge: extract logic based on bookmark into its own function...
r26727 assert node is not None
return node
Pierre-Yves David
destutil: add the ability to specify a search space for rebase destination...
r29043 def _destmergebranch(repo, action='merge', sourceset=None, onheadcheck=True,
destspace=None):
Pierre-Yves David
destmerge: extract logic based on branch heads in its own function...
r26728 """find merge destination based on branch heads"""
node = None
Pierre-Yves David
destutil: allow to specify an explicit source for the merge...
r28139
if sourceset is None:
sourceset = [repo[repo.dirstate.p1()].rev()]
branch = repo.dirstate.branch()
elif not sourceset:
msg, hint = msgdestmerge['emptysourceset'][action]
Pierre-Yves David
destutil: add more precise error classes for destmerge...
r28141 raise error.NoMergeDestAbort(msg, hint=hint)
Pierre-Yves David
destutil: allow to specify an explicit source for the merge...
r28139 else:
branch = None
for ctx in repo.set('roots(%ld::%ld)', sourceset, sourceset):
if branch is not None and ctx.branch() != branch:
msg, hint = msgdestmerge['multiplebranchessourceset'][action]
Pierre-Yves David
destutil: add more precise error classes for destmerge...
r28141 raise error.ManyMergeDestAbort(msg, hint=hint)
Pierre-Yves David
destutil: allow to specify an explicit source for the merge...
r28139 branch = ctx.branch()
Pierre-Yves David
destmerge: extract logic based on branch heads in its own function...
r26728 bheads = repo.branchheads(branch)
Pierre-Yves David
destutil: ensure we offer 'hg update' hint when not at head in all cases...
r28161 onhead = repo.revs('%ld and %ln', sourceset, bheads)
if onheadcheck and not onhead:
Pierre-Yves David
destutil: allow to specify an explicit source for the merge...
r28139 # Case A: working copy if not on a head. (merge only)
Pierre-Yves David
destutil: document various failure cases...
r28105 #
# This is probably a user mistake We bailout pointing at 'hg update'
Pierre-Yves David
merge: give priority to "not at head" failures for bare 'hg merge'...
r28103 if len(repo.heads()) <= 1:
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 msg, hint = msgdestmerge['nootherheadsbehind'][action]
Pierre-Yves David
merge: give priority to "not at head" failures for bare 'hg merge'...
r28103 else:
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 msg, hint = msgdestmerge['notatheads'][action]
Pierre-Yves David
merge: give priority to "not at head" failures for bare 'hg merge'...
r28103 raise error.Abort(msg, hint=hint)
Pierre-Yves David
destutil: allow to specify an explicit source for the merge...
r28139 # remove heads descendants of source from the set
bheads = list(repo.revs('%ln - (%ld::)', bheads, sourceset))
Pierre-Yves David
destutil: remove current head from list of candidates early...
r28138 # filters out bookmarked heads
Pierre-Yves David
destutil: allow to specify an explicit source for the merge...
r28139 nbhs = list(repo.revs('%ld - bookmark()', bheads))
Pierre-Yves David
destutil: add the ability to specify a search space for rebase destination...
r29043
if destspace is not None:
# restrict search space
# used in the 'hg pull --rebase' case, see issue 5214.
nbhs = list(repo.revs('%ld and %ld', destspace, nbhs))
Pierre-Yves David
destutil: remove current head from list of candidates early...
r28138 if len(nbhs) > 1:
# Case B: There is more than 1 other anonymous heads
Pierre-Yves David
destutil: document various failure cases...
r28105 #
# This means that there will be more than 1 candidate. This is
# ambiguous. We abort asking the user to pick as explicit destination
# instead.
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 msg, hint = msgdestmerge['toomanyheads'][action]
Pierre-Yves David
destutil: remove current head from list of candidates early...
r28138 msg %= (branch, len(bheads) + 1)
Pierre-Yves David
destutil: add more precise error classes for destmerge...
r28141 raise error.ManyMergeDestAbort(msg, hint=hint)
Pierre-Yves David
destutil: remove current head from list of candidates early...
r28138 elif not nbhs:
# Case B: There is no other anonymous heads
Pierre-Yves David
destutil: document various failure cases...
r28105 #
# This means that there is no natural candidate to merge with.
# We abort, with various messages for various cases.
Pierre-Yves David
destutil: remove current head from list of candidates early...
r28138 if bheads:
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 msg, hint = msgdestmerge['bookmarkedheads'][action]
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 elif len(repo.heads()) > 1:
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 msg, hint = msgdestmerge['nootherbranchheads'][action]
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 msg %= branch
Pierre-Yves David
destutil: ensure we offer 'hg update' hint when not at head in all cases...
r28161 elif not onhead:
# if 'onheadcheck == False' (rebase case),
# this was not caught in Case A.
msg, hint = msgdestmerge['nootherheadsbehind'][action]
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 else:
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 msg, hint = msgdestmerge['nootherheads'][action]
Pierre-Yves David
destutil: add more precise error classes for destmerge...
r28141 raise error.NoMergeDestAbort(msg, hint=hint)
Pierre-Yves David
destmerge: extract logic based on branch heads in its own function...
r26728 else:
node = nbhs[0]
assert node is not None
return node
Pierre-Yves David
destutil: add the ability to specify a search space for rebase destination...
r29043 def destmerge(repo, action='merge', sourceset=None, onheadcheck=True,
destspace=None):
Pierre-Yves David
destutil: add an 'action' layer to the destmerge message dictionary...
r28137 """return the default destination for a merge
(or raise exception about why it can't pick one)
:action: the action being performed, controls emitted error message
"""
Pierre-Yves David
destutil: add the ability to specify a search space for rebase destination...
r29043 # destspace is here to work around issues with `hg pull --rebase` see
# issue5214 for details
Pierre-Yves David
destutil: move default merge destination into a function...
r26714 if repo._activebookmark:
Pierre-Yves David
destutil: add the ability to specify a search space for rebase destination...
r29043 node = _destmergebook(repo, action=action, sourceset=sourceset,
destspace=destspace)
Pierre-Yves David
destutil: move default merge destination into a function...
r26714 else:
Pierre-Yves David
destutil: allow to disable the "on head check" in destmerge...
r28140 node = _destmergebranch(repo, action=action, sourceset=sourceset,
Pierre-Yves David
destutil: add the ability to specify a search space for rebase destination...
r29043 onheadcheck=onheadcheck, destspace=destspace)
Pierre-Yves David
destutil: move default merge destination into a function...
r26714 return repo[node].rev()
Gregory Szorc
histedit: pick an appropriate base changeset by default (BC)...
r27262
def desthistedit(ui, repo):
"""Default base revision to edit for `hg histedit`."""
Boris Feld
histedit: use the new stack definition for histedit...
r37021 default = ui.config('histedit', 'defaultrev')
if default is None:
revs = stack.getstack(repo)
elif default:
Gregory Szorc
destutil: use scmutil.revrange for desthistedit (issue5001)...
r27559 revs = scmutil.revrange(repo, [default])
Boris Feld
histedit: use the new stack definition for histedit...
r37021
if revs:
# The revset supplied by the user may not be in ascending order nor
# take the first revision. So do this manually.
revs.sort()
return revs.first()
Gregory Szorc
histedit: pick an appropriate base changeset by default (BC)...
r27262
return None
Pierre-Yves David
update: warn about other topological heads on bare update...
r28029
Gregory Szorc
show: implement "stack" view...
r33194 def stackbase(ui, repo):
Boris Feld
show: use the new stack definition for show stack...
r37020 revs = stack.getstack(repo)
Boris Feld
stack: return a sorted smartrev by default...
r37022 return revs.first() if revs else None
Gregory Szorc
show: implement "stack" view...
r33194
Pierre-Yves David
update: warn about other topological heads on bare update...
r28029 def _statusotherbook(ui, repo):
Augie Fackler
localrepo: extract bookmarkheads method to bookmarks.py...
r32381 bmheads = bookmarks.headsforactive(repo)
Pierre-Yves David
update: warn about other topological heads on bare update...
r28029 curhead = repo[repo._activebookmark].node()
if repo.revs('%n and parents()', curhead):
# we are on the active bookmark
bmheads = [b for b in bmheads if curhead != b]
if bmheads:
msg = _('%i other divergent bookmarks for "%s"\n')
ui.status(msg % (len(bmheads), repo._activebookmark))
def _statusotherbranchheads(ui, repo):
currentbranch = repo.dirstate.branch()
FUJIWARA Katsunori
destutil: show message about other branch heads, even if on a closed head...
r28266 allheads = repo.branchheads(currentbranch, closed=True)
Pierre-Yves David
update: warn about other topological heads on bare update...
r28029 heads = repo.branchheads(currentbranch)
FUJIWARA Katsunori
destutil: show message about other branch heads, even if on a closed head...
r28266 if repo.revs('%ln and parents()', allheads):
# we are on a head, even though it might be closed
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 #
# on closed otherheads
# ========= ==========
# o 0 all heads for current branch are closed
# N only descendant branch heads are closed
# x 0 there is only one non-closed branch head
# N there are some non-closed branch heads
# ========= ==========
FUJIWARA Katsunori
destutil: add new local variable to increase readability...
r28233 otherheads = repo.revs('%ln - parents()', heads)
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 if repo['.'].closesbranch():
FUJIWARA Katsunori
destutil: show message and hint at updating to the closed head as warning
r28684 ui.warn(_('no open descendant heads on branch "%s", '
FUJIWARA Katsunori
destutil: make messages at updating to the closed head usual form...
r28683 'updating to a closed head\n') %
(currentbranch))
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 if otherheads:
timeless
update: use single quotes in use warning
r29964 ui.warn(_("(committing will reopen the head, "
"use 'hg heads .' to see %i other heads)\n") %
FUJIWARA Katsunori
destutil: make messages at updating to the closed head usual form...
r28683 (len(otherheads)))
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 else:
FUJIWARA Katsunori
destutil: show message and hint at updating to the closed head as warning
r28684 ui.warn(_('(committing will reopen branch "%s")\n') %
FUJIWARA Katsunori
destutil: make messages at updating to the closed head usual form...
r28683 (currentbranch))
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 elif otherheads:
Pulkit Goyal
update: show the commit to which we updated in case of multiple heads (BC)...
r32698 curhead = repo['.']
ui.status(_('updated to "%s: %s"\n') % (curhead,
curhead.description().split('\n')[0]))
Pierre-Yves David
update: warn about other topological heads on bare update...
r28029 ui.status(_('%i other heads for branch "%s"\n') %
FUJIWARA Katsunori
destutil: add new local variable to increase readability...
r28233 (len(otherheads), currentbranch))
Pierre-Yves David
update: warn about other topological heads on bare update...
r28029
def statusotherdests(ui, repo):
"""Print message about other head"""
# XXX we should probably include a hint:
# - about what to do
# - how to see such heads
if repo._activebookmark:
_statusotherbook(ui, repo)
else:
_statusotherbranchheads(ui, repo)