##// END OF EJS Templates
destupdate: move obsolete handling first...
Pierre-Yves David -
r26722:6cd643a1 default
parent child Browse files
Show More
@@ -1,155 +1,158
1 # destutil.py - Mercurial utility function for command destination
1 # destutil.py - Mercurial utility function for command destination
2 #
2 #
3 # Copyright Matt Mackall <mpm@selenic.com> and other
3 # Copyright Matt Mackall <mpm@selenic.com> and other
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from .i18n import _
8 from .i18n import _
9 from . import (
9 from . import (
10 bookmarks,
10 bookmarks,
11 error,
11 error,
12 obsolete,
12 obsolete,
13 )
13 )
14
14
15 def _destupdatevalidate(repo, rev, clean, check):
15 def _destupdatevalidate(repo, rev, clean, check):
16 """validate that the destination comply to various rules
16 """validate that the destination comply to various rules
17
17
18 This exists as its own function to help wrapping from extensions."""
18 This exists as its own function to help wrapping from extensions."""
19 wc = repo[None]
19 wc = repo[None]
20 p1 = wc.p1()
20 p1 = wc.p1()
21 if not clean:
21 if not clean:
22 # Check that the update is linear.
22 # Check that the update is linear.
23 #
23 #
24 # Mercurial do not allow update-merge for non linear pattern
24 # Mercurial do not allow update-merge for non linear pattern
25 # (that would be technically possible but was considered too confusing
25 # (that would be technically possible but was considered too confusing
26 # for user a long time ago)
26 # for user a long time ago)
27 #
27 #
28 # See mercurial.merge.update for details
28 # See mercurial.merge.update for details
29 if p1.rev() not in repo.changelog.ancestors([rev], inclusive=True):
29 if p1.rev() not in repo.changelog.ancestors([rev], inclusive=True):
30 dirty = wc.dirty(missing=True)
30 dirty = wc.dirty(missing=True)
31 foreground = obsolete.foreground(repo, [p1.node()])
31 foreground = obsolete.foreground(repo, [p1.node()])
32 if not repo[rev].node() in foreground:
32 if not repo[rev].node() in foreground:
33 if dirty:
33 if dirty:
34 msg = _("uncommitted changes")
34 msg = _("uncommitted changes")
35 hint = _("commit and merge, or update --clean to"
35 hint = _("commit and merge, or update --clean to"
36 " discard changes")
36 " discard changes")
37 raise error.UpdateAbort(msg, hint=hint)
37 raise error.UpdateAbort(msg, hint=hint)
38 elif not check: # destination is not a descendant.
38 elif not check: # destination is not a descendant.
39 msg = _("not a linear update")
39 msg = _("not a linear update")
40 hint = _("merge or update --check to force update")
40 hint = _("merge or update --check to force update")
41 raise error.UpdateAbort(msg, hint=hint)
41 raise error.UpdateAbort(msg, hint=hint)
42
42
43 def destupdate(repo, clean=False, check=False):
43 def destupdate(repo, clean=False, check=False):
44 """destination for bare update operation
44 """destination for bare update operation
45
45
46 return (rev, movemark, activemark)
46 return (rev, movemark, activemark)
47
47
48 - rev: the revision to update to,
48 - rev: the revision to update to,
49 - movemark: node to move the active bookmark from
49 - movemark: node to move the active bookmark from
50 (cf bookmark.calculate update),
50 (cf bookmark.calculate update),
51 - activemark: a bookmark to activate at the end of the update.
51 - activemark: a bookmark to activate at the end of the update.
52 """
52 """
53 node = None
53 node = None
54 wc = repo[None]
54 wc = repo[None]
55 p1 = wc.p1()
55 p1 = wc.p1()
56 movemark, activemark = None
56 movemark = activemark = None
57
58 if node is None:
59 # we also move the active bookmark, if any
60 node, movemark = bookmarks.calculateupdate(repo.ui, repo, None)
61 if node is not None:
62 activemark = node
63
57
64 if node is None:
65 try:
66 node = repo.branchtip(wc.branch())
67 except error.RepoLookupError:
68 if wc.branch() == 'default': # no default branch!
69 node = repo.lookup('tip') # update to tip
70 else:
71 raise error.Abort(_("branch %s not found") % wc.branch())
72 if p1.obsolete() and not p1.children():
58 if p1.obsolete() and not p1.children():
73 # allow updating to successors
59 # allow updating to successors
74 successors = obsolete.successorssets(repo, p1.node())
60 successors = obsolete.successorssets(repo, p1.node())
75
61
76 # behavior of certain cases is as follows,
62 # behavior of certain cases is as follows,
77 #
63 #
78 # divergent changesets: update to highest rev, similar to what
64 # divergent changesets: update to highest rev, similar to what
79 # is currently done when there are more than one head
65 # is currently done when there are more than one head
80 # (i.e. 'tip')
66 # (i.e. 'tip')
81 #
67 #
82 # replaced changesets: same as divergent except we know there
68 # replaced changesets: same as divergent except we know there
83 # is no conflict
69 # is no conflict
84 #
70 #
85 # pruned changeset: no update is done; though, we could
71 # pruned changeset: no update is done; though, we could
86 # consider updating to the first non-obsolete parent,
72 # consider updating to the first non-obsolete parent,
87 # similar to what is current done for 'hg prune'
73 # similar to what is current done for 'hg prune'
88
74
89 if successors:
75 if successors:
90 # flatten the list here handles both divergent (len > 1)
76 # flatten the list here handles both divergent (len > 1)
91 # and the usual case (len = 1)
77 # and the usual case (len = 1)
92 successors = [n for sub in successors for n in sub]
78 successors = [n for sub in successors for n in sub]
93
79
94 # get the max revision for the given successors set,
80 # get the max revision for the given successors set,
95 # i.e. the 'tip' of a set
81 # i.e. the 'tip' of a set
96 node = repo.revs('max(%ln)', successors).first()
82 node = repo.revs('max(%ln)', successors).first()
83 if bookmarks.isactivewdirparent(repo):
84 movemark = repo['.'].node()
85
86 if node is None:
87 # we also move the active bookmark, if any
88 node, movemark = bookmarks.calculateupdate(repo.ui, repo, None)
89 if node is not None:
90 activemark = node
91
92 if node is None:
93 try:
94 node = repo.branchtip(wc.branch())
95 except error.RepoLookupError:
96 if wc.branch() == 'default': # no default branch!
97 node = repo.lookup('tip') # update to tip
98 else:
99 raise error.Abort(_("branch %s not found") % wc.branch())
97 rev = repo[node].rev()
100 rev = repo[node].rev()
98
101
99 _destupdatevalidate(repo, rev, clean, check)
102 _destupdatevalidate(repo, rev, clean, check)
100
103
101 return rev, movemark, activemark
104 return rev, movemark, activemark
102
105
103 def destmerge(repo):
106 def destmerge(repo):
104 if repo._activebookmark:
107 if repo._activebookmark:
105 bmheads = repo.bookmarkheads(repo._activebookmark)
108 bmheads = repo.bookmarkheads(repo._activebookmark)
106 curhead = repo[repo._activebookmark].node()
109 curhead = repo[repo._activebookmark].node()
107 if len(bmheads) == 2:
110 if len(bmheads) == 2:
108 if curhead == bmheads[0]:
111 if curhead == bmheads[0]:
109 node = bmheads[1]
112 node = bmheads[1]
110 else:
113 else:
111 node = bmheads[0]
114 node = bmheads[0]
112 elif len(bmheads) > 2:
115 elif len(bmheads) > 2:
113 raise error.Abort(_("multiple matching bookmarks to merge - "
116 raise error.Abort(_("multiple matching bookmarks to merge - "
114 "please merge with an explicit rev or bookmark"),
117 "please merge with an explicit rev or bookmark"),
115 hint=_("run 'hg heads' to see all heads"))
118 hint=_("run 'hg heads' to see all heads"))
116 elif len(bmheads) <= 1:
119 elif len(bmheads) <= 1:
117 raise error.Abort(_("no matching bookmark to merge - "
120 raise error.Abort(_("no matching bookmark to merge - "
118 "please merge with an explicit rev or bookmark"),
121 "please merge with an explicit rev or bookmark"),
119 hint=_("run 'hg heads' to see all heads"))
122 hint=_("run 'hg heads' to see all heads"))
120 else:
123 else:
121 branch = repo[None].branch()
124 branch = repo[None].branch()
122 bheads = repo.branchheads(branch)
125 bheads = repo.branchheads(branch)
123 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
126 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
124
127
125 if len(nbhs) > 2:
128 if len(nbhs) > 2:
126 raise error.Abort(_("branch '%s' has %d heads - "
129 raise error.Abort(_("branch '%s' has %d heads - "
127 "please merge with an explicit rev")
130 "please merge with an explicit rev")
128 % (branch, len(bheads)),
131 % (branch, len(bheads)),
129 hint=_("run 'hg heads .' to see heads"))
132 hint=_("run 'hg heads .' to see heads"))
130
133
131 parent = repo.dirstate.p1()
134 parent = repo.dirstate.p1()
132 if len(nbhs) <= 1:
135 if len(nbhs) <= 1:
133 if len(bheads) > 1:
136 if len(bheads) > 1:
134 raise error.Abort(_("heads are bookmarked - "
137 raise error.Abort(_("heads are bookmarked - "
135 "please merge with an explicit rev"),
138 "please merge with an explicit rev"),
136 hint=_("run 'hg heads' to see all heads"))
139 hint=_("run 'hg heads' to see all heads"))
137 if len(repo.heads()) > 1:
140 if len(repo.heads()) > 1:
138 raise error.Abort(_("branch '%s' has one head - "
141 raise error.Abort(_("branch '%s' has one head - "
139 "please merge with an explicit rev")
142 "please merge with an explicit rev")
140 % branch,
143 % branch,
141 hint=_("run 'hg heads' to see all heads"))
144 hint=_("run 'hg heads' to see all heads"))
142 msg, hint = _('nothing to merge'), None
145 msg, hint = _('nothing to merge'), None
143 if parent != repo.lookup(branch):
146 if parent != repo.lookup(branch):
144 hint = _("use 'hg update' instead")
147 hint = _("use 'hg update' instead")
145 raise error.Abort(msg, hint=hint)
148 raise error.Abort(msg, hint=hint)
146
149
147 if parent not in bheads:
150 if parent not in bheads:
148 raise error.Abort(_('working directory not at a head revision'),
151 raise error.Abort(_('working directory not at a head revision'),
149 hint=_("use 'hg update' or merge with an "
152 hint=_("use 'hg update' or merge with an "
150 "explicit revision"))
153 "explicit revision"))
151 if parent == nbhs[0]:
154 if parent == nbhs[0]:
152 node = nbhs[-1]
155 node = nbhs[-1]
153 else:
156 else:
154 node = nbhs[0]
157 node = nbhs[0]
155 return repo[node].rev()
158 return repo[node].rev()
General Comments 0
You need to be logged in to leave comments. Login now