|
1 from mercurial import error |
|
2 from mercurial import util |
|
3 from mercurial import destutil |
|
4 from mercurial import extensions |
|
5 from mercurial import bookmarks |
|
6 from mercurial.i18n import _ |
|
7 |
|
8 def _destmergebranch(orig, repo, action='merge', sourceset=None, onheadcheck=True): |
|
9 p1 = repo['.'] |
|
10 top = p1.topic() |
|
11 if top: |
|
12 heads = repo.revs('heads(topic(.)::topic(.))') |
|
13 if p1.rev() not in heads: |
|
14 raise error.Abort(_("not at topic head, update or explicit")) |
|
15 elif 1 == len(heads): |
|
16 # should look at all branch involved but... later |
|
17 bhead = ngtip(repo, p1.branch(), all=True) |
|
18 if not bhead: |
|
19 raise error.Abort(_("nothing to merge")) |
|
20 elif 1 == len(bhead): |
|
21 return bhead.first() |
|
22 else: |
|
23 raise error.Abort(_("branch '%s' has %d heads - " |
|
24 "please merge with an explicit rev") |
|
25 % (p1.branch(), len(bhead)), |
|
26 hint=_("run 'hg heads .' to see heads")) |
|
27 elif 2 == len(heads): |
|
28 heads = [r for r in heads if r != p1.rev()] |
|
29 # XXX: bla bla bla bla bla |
|
30 if 1 < len(heads): |
|
31 raise error.Abort(_('working directory not at a head revision'), |
|
32 hint=_("use 'hg update' or merge with an " |
|
33 "explicit revision")) |
|
34 return heads[0] |
|
35 elif 2 < len(heads): |
|
36 raise error.Abort(_("topic '%s' has %d heads - " |
|
37 "please merge with an explicit rev") |
|
38 % (top, len(heads))) |
|
39 else: |
|
40 assert False # that's impossible |
|
41 if orig.func_default: # version above hg-3.7 |
|
42 return orig(repo, action, sourceset, onheadcheck) |
|
43 else: |
|
44 return orig(repo) |
|
45 |
|
46 def _destupdatetopic(repo, clean, check): |
|
47 """decide on an update destination from current topic""" |
|
48 movemark = node = None |
|
49 topic = repo.currenttopic |
|
50 revs = repo.revs('.::topic("%s")' % topic) |
|
51 if not revs: |
|
52 return None, None, None |
|
53 node = revs.last() |
|
54 if bookmarks.isactivewdirparent(repo): |
|
55 movemark = repo['.'].node() |
|
56 return node, movemark, None |
|
57 |
|
58 def setupdest(): |
|
59 if util.safehasattr(destutil, '_destmergebranch'): |
|
60 extensions.wrapfunction(destutil, '_destmergebranch', _destmergebranch) |
|
61 rebase = extensions.find('rebase') |
|
62 if (util.safehasattr(rebase, '_destrebase') |
|
63 # logic not shared with merge yet < hg-3.8 |
|
64 and not util.safehasattr(rebase, '_definesets')): |
|
65 extensions.wrapfunction(rebase, '_destrebase', _destmergebranch) |
|
66 if util.safehasattr(destutil, 'destupdatesteps'): |
|
67 bridx = destutil.destupdatesteps.index('branch') |
|
68 destutil.destupdatesteps.insert(bridx, 'topic') |
|
69 destutil.destupdatestepmap['topic'] = _destupdatetopic |
|
70 |
|
71 def ngtip(repo, branch, all=False): |
|
72 """tip new generation""" |
|
73 ## search for untopiced heads of branch |
|
74 # could be heads((::branch(x) - topic())) |
|
75 # but that is expensive |
|
76 # |
|
77 # we should write plain code instead |
|
78 subquery = '''heads( |
|
79 parents( |
|
80 ancestor( |
|
81 (head() and branch(%s) |
|
82 or (topic() and branch(%s))))) |
|
83 ::(head() and branch(%s)) |
|
84 - topic())''' |
|
85 if not all: |
|
86 subquery = 'max(%s)' % subquery |
|
87 return repo.revs(subquery, branch, branch, branch) |