##// END OF EJS Templates
auto-upgrade: add a test case with no permission to lock the repository...
auto-upgrade: add a test case with no permission to lock the repository This show the current behavior when the repository is unlockable. The current behavior is to abort, which is probably not great. Now that we have a proper test, we can think about the behavior we want in a later changeset. Differential Revision: https://phab.mercurial-scm.org/D12615

File last commit:

r49730:6000f5b2 default
r50091:1c233af9 default
Show More
destutil.py
495 lines | 17.0 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
#
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright Olivia Mackall <olivia@selenic.com> and other
Pierre-Yves David
update: move default destination computation to a function...
r26569 #
# 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
Pierre-Yves David
update: move default destination computation to a function...
r26569 from .i18n import _
Augie Fackler
formatting: blacken the codebase...
r43346 from . import bookmarks, error, obsutil, scmutil, stack
Pierre-Yves David
update: move default destination computation to a function...
r26569
Augie Fackler
rebase: introduce support for automatically rebasing orphan changes...
r37805 def orphanpossibledestination(repo, rev):
"""Return all changesets that may be a new parent for orphan `rev`.
This function works fine on non-orphan revisions, it's just silly
because there's no destination implied by obsolete markers, so
it'll return nothing.
"""
tonode = repo.changelog.node
parents = repo.changelog.parentrevs
torev = repo.changelog.rev
dest = set()
tovisit = list(parents(rev))
while tovisit:
r = tovisit.pop()
succsets = obsutil.successorssets(repo, tonode(r))
if not succsets:
# if there are no successors for r, r was probably pruned
# and we should walk up to r's parents to try and find
# some successors.
tovisit.extend(parents(r))
else:
# We should probably pick only one destination from split
# (case where '1 < len(ss)'), This could be the currently
# tipmost, but the correct result is less clear when
# results of the split have been moved such that they
# reside on multiple branches.
for ss in succsets:
for n in ss:
dr = torev(n)
if dr != -1:
dest.add(dr)
return dest
Augie Fackler
formatting: blacken the codebase...
r43346
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
#
av6
destutil: if wdp is obsolete, update to the closest non-obsolete ancestor...
r49538 # pruned changeset: update to the closest non-obsolete ancestor,
# similar to what 'hg prune' currently does
Pierre-Yves David
update: move default destination computation to a function...
r26569
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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 node = repo.revs(b'max(%ln)', successors).first()
av6
branchmap: skip obsolete revisions while computing heads...
r49536 else:
av6
destutil: if wdp is obsolete, update to the closest non-obsolete ancestor...
r49538 p1 = p1.p1()
while p1.obsolete():
p1 = p1.p1()
node = p1.node()
if node is not None and bookmarks.isactivewdirparent(repo):
movemark = repo[b'.'].node()
Pierre-Yves David
destupdate: extract logic based on obsolescence marker in its own function...
r26723 return node, movemark, None
Augie Fackler
formatting: blacken the codebase...
r43346
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
Martin von Zweigbergk
bookmarks: calculateupdate() returns a bookmark, not a rev...
r37377 node = None
Martin von Zweigbergk
bookmarks: drop always-None argument from calculateupdate()...
r37393 activemark, movemark = bookmarks.calculateupdate(repo.ui, repo)
Martin von Zweigbergk
bookmarks: calculateupdate() returns a bookmark, not a rev...
r37377 if activemark is not None:
Martin von Zweigbergk
destutil: look up bookmarks only among bookmarks...
r37470 node = repo._bookmarks[activemark]
Pierre-Yves David
destupdate: extract logic based on bookmarks in its own function...
r26724 return node, movemark, activemark
Augie Fackler
formatting: blacken the codebase...
r43346
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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 currentbranch = repo[b'.'].branch()
liscju
update: fix bare --clean to work on new branch (issue5003) (BC)...
r29284
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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 node = repo.revs(b'max(.::(%ln))', heads).first()
Pierre-Yves David
destupdate: extract logic based on branch in its own function...
r26725 if bookmarks.isactivewdirparent(repo):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 movemark = repo[b'.'].node()
elif currentbranch == b'default' and not wc.p1():
Yuya Nishihara
update: resurrect bare update from null parent to tip-most branch head...
r28924 # "null" parent belongs to "default" branch, but it doesn't exist, so
# update to the tipmost non-closed branch head
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 node = repo.revs(b'max(head() and not closed())').first()
FUJIWARA Katsunori
destutil: use cached branch information instead of query for efficiency...
r28236 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 node = repo[b'.'].node()
Pierre-Yves David
destupdate: extract logic based on branch in its own function...
r26725 return node, movemark, None
Augie Fackler
formatting: blacken the codebase...
r43346
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)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 assert heads, b"any branch has at least one head"
node = repo.revs(b'max(.::(%ln))', heads).first()
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 assert (
node is not None
), b"any revision has at least one descendant branch head"
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 if bookmarks.isactivewdirparent(repo):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 movemark = repo[b'.'].node()
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 else:
# here, no "default" branch, and all branches are closed
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 node = repo.lookup(b'tip')
assert node is not None, b"'tip' exists even in empty repository"
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 return node, movemark, None
Augie Fackler
formatting: blacken the codebase...
r43346
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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 destupdatesteps = [b'evolution', b'bookmark', b'branch', b'branchfallback']
Pierre-Yves David
destupdate: have a generic and extensible way to run each step...
r26726 # mapping to ease extension overriding steps.
Augie Fackler
formatting: blacken the codebase...
r43346 destupdatestepmap = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'evolution': _destupdateobs,
b'bookmark': _destupdatebook,
b'branch': _destupdatebranch,
b'branchfallback': _destupdatebranchfallback,
Augie Fackler
formatting: blacken the codebase...
r43346 }
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
Augie Fackler
formatting: blacken the codebase...
r43346
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 msgdestmerge = {
# too many matching divergent bookmark
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'toomanybookmarks': {
b'merge': (
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"multiple matching bookmarks to merge -"
b" please merge with an explicit rev or bookmark"
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Kyle Lippincott
destutil: provide hint on rebase+merge for how to specify destination/rev...
r43384 _(b"run 'hg heads' to see all heads, specify rev with -r"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'rebase': (
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"multiple matching bookmarks to rebase -"
b" please rebase to an explicit rev or bookmark"
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Kyle Lippincott
destutil: provide hint on rebase+merge for how to specify destination/rev...
r43384 _(b"run 'hg heads' to see all heads, specify destination with -d"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
},
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # no other matching divergent bookmark
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'nootherbookmarks': {
b'merge': (
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"no matching bookmark to merge - "
b"please merge with an explicit rev or bookmark"
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Kyle Lippincott
destutil: provide hint on rebase+merge for how to specify destination/rev...
r43384 _(b"run 'hg heads' to see all heads, specify rev with -r"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'rebase': (
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"no matching bookmark to rebase - "
b"please rebase to an explicit rev or bookmark"
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Kyle Lippincott
destutil: provide hint on rebase+merge for how to specify destination/rev...
r43384 _(b"run 'hg heads' to see all heads, specify destination with -d"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
},
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # branch have too many unbookmarked heads, no obvious destination
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'toomanyheads': {
b'merge': (
_(b"branch '%s' has %d heads - please merge with an explicit rev"),
Kyle Lippincott
destutil: provide hint on rebase+merge for how to specify destination/rev...
r43384 _(b"run 'hg heads .' to see heads, specify rev with -r"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'rebase': (
_(b"branch '%s' has %d heads - please rebase to an explicit rev"),
Kyle Lippincott
destutil: provide hint on rebase+merge for how to specify destination/rev...
r43384 _(b"run 'hg heads .' to see heads, specify destination with -d"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
},
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # branch have no other unbookmarked heads
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'bookmarkedheads': {
b'merge': (
_(b"heads are bookmarked - please merge with an explicit rev"),
Kyle Lippincott
destutil: provide hint on rebase+merge for how to specify destination/rev...
r43384 _(b"run 'hg heads' to see all heads, specify rev with -r"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'rebase': (
_(b"heads are bookmarked - please rebase to an explicit rev"),
Kyle Lippincott
destutil: provide hint on rebase+merge for how to specify destination/rev...
r43384 _(b"run 'hg heads' to see all heads, specify destination with -d"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
},
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # branch have just a single heads, but there is other branches
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'nootherbranchheads': {
b'merge': (
_(b"branch '%s' has one head - please merge with an explicit rev"),
Kyle Lippincott
destutil: provide hint on rebase+merge for how to specify destination/rev...
r43384 _(b"run 'hg heads' to see all heads, specify rev with -r"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'rebase': (
_(b"branch '%s' has one head - please rebase to an explicit rev"),
Kyle Lippincott
destutil: provide hint on rebase+merge for how to specify destination/rev...
r43384 _(b"run 'hg heads' to see all heads, specify destination with -d"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
},
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # repository have a single head
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'nootherheads': {
b'merge': (_(b'nothing to merge'), None),
b'rebase': (_(b'nothing to rebase'), None),
Augie Fackler
formatting: blacken the codebase...
r43346 },
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # repository have a single head and we are not on it
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'nootherheadsbehind': {
b'merge': (_(b'nothing to merge'), _(b"use 'hg update' instead")),
b'rebase': (_(b'nothing to rebase'), _(b"use 'hg update' instead")),
Augie Fackler
formatting: blacken the codebase...
r43346 },
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 # We are not on a head
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'notatheads': {
b'merge': (
_(b'working directory not at a head revision'),
_(b"use 'hg update' or merge with an explicit revision"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'rebase': (
_(b'working directory not at a head revision'),
_(b"use 'hg update' or rebase to an explicit revision"),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
},
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'emptysourceset': {
b'merge': (_(b'source set is empty'), None),
b'rebase': (_(b'source set is empty'), None),
Augie Fackler
formatting: blacken the codebase...
r43346 },
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'multiplebranchessourceset': {
b'merge': (_(b'source set is rooted in multiple branches'), None),
b'rebase': (
_(b'rebaseset is rooted in multiple named branches'),
_(b'specify an explicit destination with --dest'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
},
}
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 def _destmergebook(repo, action=b'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)
Martin von Zweigbergk
destutil: look up bookmarks only among bookmarks...
r37470 curhead = repo._bookmarks[repo._activebookmark]
Pierre-Yves David
destmerge: extract logic based on bookmark into its own function...
r26727 if len(bmheads) == 2:
if curhead == bmheads[0]:
node = bmheads[1]
else:
node = bmheads[0]
elif len(bmheads) > 2:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg, hint = msgdestmerge[b'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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg, hint = msgdestmerge[b'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
Augie Fackler
formatting: blacken the codebase...
r43346
def _destmergebranch(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo, action=b'merge', sourceset=None, onheadcheck=True, destspace=None
Augie Fackler
formatting: blacken the codebase...
r43346 ):
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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg, hint = msgdestmerge[b'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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for ctx in repo.set(b'roots(%ld::%ld)', sourceset, sourceset):
Pierre-Yves David
destutil: allow to specify an explicit source for the merge...
r28139 if branch is not None and ctx.branch() != branch:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg, hint = msgdestmerge[b'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)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 onhead = repo.revs(b'%ld and %ln', sourceset, bheads)
Pierre-Yves David
destutil: ensure we offer 'hg update' hint when not at head in all cases...
r28161 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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg, hint = msgdestmerge[b'nootherheadsbehind'][action]
Pierre-Yves David
merge: give priority to "not at head" failures for bare 'hg merge'...
r28103 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg, hint = msgdestmerge[b'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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 bheads = list(repo.revs(b'%ln - (%ld::)', bheads, sourceset))
Pierre-Yves David
destutil: remove current head from list of candidates early...
r28138 # filters out bookmarked heads
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 nbhs = list(repo.revs(b'%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.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 nbhs = list(repo.revs(b'%ld and %ld', destspace, nbhs))
Pierre-Yves David
destutil: add the ability to specify a search space for rebase destination...
r29043
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.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg, hint = msgdestmerge[b'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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg, hint = msgdestmerge[b'bookmarkedheads'][action]
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 elif len(repo.heads()) > 1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg, hint = msgdestmerge[b'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.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg, hint = msgdestmerge[b'nootherheadsbehind'][action]
Pierre-Yves David
destutil: extract all 'mergedest' abort messages into a dictionary...
r28102 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg, hint = msgdestmerge[b'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
Augie Fackler
formatting: blacken the codebase...
r43346
def destmerge(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo, action=b'merge', sourceset=None, onheadcheck=True, destspace=None
Augie Fackler
formatting: blacken the codebase...
r43346 ):
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:
Augie Fackler
formatting: blacken the codebase...
r43346 node = _destmergebook(
repo, action=action, sourceset=sourceset, destspace=destspace
)
Pierre-Yves David
destutil: move default merge destination into a function...
r26714 else:
Augie Fackler
formatting: blacken the codebase...
r43346 node = _destmergebranch(
repo,
action=action,
sourceset=sourceset,
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
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
histedit: pick an appropriate base changeset by default (BC)...
r27262 def desthistedit(ui, repo):
"""Default base revision to edit for `hg histedit`."""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 default = ui.config(b'histedit', b'defaultrev')
Boris Feld
histedit: use the new stack definition for histedit...
r37021
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])
rdamazio@google.com
histedit: crashing with a more useful error message on empty defaultrev...
r41202 else:
Martin von Zweigbergk
destutil: raise more specific error when histedit.defaultrev is empty...
r46447 raise error.ConfigError(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"config option histedit.defaultrev can't be empty")
)
Boris Feld
histedit: use the new stack definition for histedit...
r37021
if revs:
Boris Feld
histedit: simplify desthistedit...
r37408 # Take the first revision of the revset as the root
return revs.min()
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
Augie Fackler
formatting: blacken the codebase...
r43346
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
Augie Fackler
formatting: blacken the codebase...
r43346
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)
Martin von Zweigbergk
destutil: look up bookmarks only among bookmarks...
r37470 curhead = repo._bookmarks[repo._activebookmark]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if repo.revs(b'%n and parents()', curhead):
Pierre-Yves David
update: warn about other topological heads on bare update...
r28029 # we are on the active bookmark
bmheads = [b for b in bmheads if curhead != b]
if bmheads:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg = _(b'%i other divergent bookmarks for "%s"\n')
Pierre-Yves David
update: warn about other topological heads on bare update...
r28029 ui.status(msg % (len(bmheads), repo._activebookmark))
Augie Fackler
formatting: blacken the codebase...
r43346
Pierre-Yves David
update: warn about other topological heads on bare update...
r28029 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)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if repo.revs(b'%ln and parents()', allheads):
FUJIWARA Katsunori
destutil: show message about other branch heads, even if on a closed head...
r28266 # 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
# ========= ==========
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 otherheads = repo.revs(b'%ln - parents()', heads)
if repo[b'.'].closesbranch():
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'no open descendant heads on branch "%s", '
b'updating to a closed head\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% currentbranch
)
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 if otherheads:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"(committing will reopen the head, "
b"use 'hg heads .' to see %i other heads)\n"
Augie Fackler
formatting: blacken the codebase...
r43346 )
% (len(otherheads))
)
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 else:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'(committing will reopen branch "%s")\n') % currentbranch
Augie Fackler
formatting: blacken the codebase...
r43346 )
FUJIWARA Katsunori
destutil: choose non-closed branch head at first (BC)...
r28385 elif otherheads:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 curhead = repo[b'.']
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'updated to "%s: %s"\n')
% (curhead, curhead.description().split(b'\n')[0])
Augie Fackler
formatting: blacken the codebase...
r43346 )
ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%i other heads for branch "%s"\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (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)