##// END OF EJS Templates
copies: do not initialize the dictionary with root in changeset copies...
copies: do not initialize the dictionary with root in changeset copies We don't strictly need the dict to be prefiled with `{}`. Not doing so will make the next changeset simpler. This part of a preparation to use native code for this part of copy tracing.

File last commit:

r43387:8ff1ecfa default
r44177:fb8f10c0 default
Show More
destutil.py
490 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
#
# 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 _
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
#
# 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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 node = repo.revs(b'max(%ln)', successors).first()
Pierre-Yves David
destupdate: move obsolete handling first...
r26722 if bookmarks.isactivewdirparent(repo):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(
_(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)