##// END OF EJS Templates
destupdate: indent bookmark and branch logic...
Pierre-Yves David -
r26721:3d094fbe default
parent child Browse files
Show More
@@ -1,155 +1,155 b''
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 activemark = None
56 movemark, activemark = None
57
57
58 if node is None:
58 # we also move the active bookmark, if any
59 # we also move the active bookmark, if any
59 node, movemark = bookmarks.calculateupdate(repo.ui, repo, None)
60 node, movemark = bookmarks.calculateupdate(repo.ui, repo, None)
60 if node is not None:
61 if node is not None:
61 activemark = node
62 activemark = node
62
63
63 if node is None:
64 if node is None:
64 try:
65 try:
65 node = repo.branchtip(wc.branch())
66 node = repo.branchtip(wc.branch())
66 except error.RepoLookupError:
67 except error.RepoLookupError:
67 if wc.branch() == 'default': # no default branch!
68 if wc.branch() == 'default': # no default branch!
68 node = repo.lookup('tip') # update to tip
69 node = repo.lookup('tip') # update to tip
69 else:
70 else:
70 raise error.Abort(_("branch %s not found") % wc.branch())
71 raise error.Abort(_("branch %s not found") % wc.branch())
71
72 if p1.obsolete() and not p1.children():
72 if p1.obsolete() and not p1.children():
73 # allow updating to successors
73 # allow updating to successors
74 successors = obsolete.successorssets(repo, p1.node())
74 successors = obsolete.successorssets(repo, p1.node())
75
75
76 # behavior of certain cases is as follows,
76 # behavior of certain cases is as follows,
77 #
77 #
78 # divergent changesets: update to highest rev, similar to what
78 # divergent changesets: update to highest rev, similar to what
79 # is currently done when there are more than one head
79 # is currently done when there are more than one head
80 # (i.e. 'tip')
80 # (i.e. 'tip')
81 #
81 #
82 # replaced changesets: same as divergent except we know there
82 # replaced changesets: same as divergent except we know there
83 # is no conflict
83 # is no conflict
84 #
84 #
85 # pruned changeset: no update is done; though, we could
85 # pruned changeset: no update is done; though, we could
86 # consider updating to the first non-obsolete parent,
86 # consider updating to the first non-obsolete parent,
87 # similar to what is current done for 'hg prune'
87 # similar to what is current done for 'hg prune'
88
88
89 if successors:
89 if successors:
90 # flatten the list here handles both divergent (len > 1)
90 # flatten the list here handles both divergent (len > 1)
91 # and the usual case (len = 1)
91 # and the usual case (len = 1)
92 successors = [n for sub in successors for n in sub]
92 successors = [n for sub in successors for n in sub]
93
93
94 # get the max revision for the given successors set,
94 # get the max revision for the given successors set,
95 # i.e. the 'tip' of a set
95 # i.e. the 'tip' of a set
96 node = repo.revs('max(%ln)', successors).first()
96 node = repo.revs('max(%ln)', successors).first()
97 rev = repo[node].rev()
97 rev = repo[node].rev()
98
98
99 _destupdatevalidate(repo, rev, clean, check)
99 _destupdatevalidate(repo, rev, clean, check)
100
100
101 return rev, movemark, activemark
101 return rev, movemark, activemark
102
102
103 def destmerge(repo):
103 def destmerge(repo):
104 if repo._activebookmark:
104 if repo._activebookmark:
105 bmheads = repo.bookmarkheads(repo._activebookmark)
105 bmheads = repo.bookmarkheads(repo._activebookmark)
106 curhead = repo[repo._activebookmark].node()
106 curhead = repo[repo._activebookmark].node()
107 if len(bmheads) == 2:
107 if len(bmheads) == 2:
108 if curhead == bmheads[0]:
108 if curhead == bmheads[0]:
109 node = bmheads[1]
109 node = bmheads[1]
110 else:
110 else:
111 node = bmheads[0]
111 node = bmheads[0]
112 elif len(bmheads) > 2:
112 elif len(bmheads) > 2:
113 raise error.Abort(_("multiple matching bookmarks to merge - "
113 raise error.Abort(_("multiple matching bookmarks to merge - "
114 "please merge with an explicit rev or bookmark"),
114 "please merge with an explicit rev or bookmark"),
115 hint=_("run 'hg heads' to see all heads"))
115 hint=_("run 'hg heads' to see all heads"))
116 elif len(bmheads) <= 1:
116 elif len(bmheads) <= 1:
117 raise error.Abort(_("no matching bookmark to merge - "
117 raise error.Abort(_("no matching bookmark to merge - "
118 "please merge with an explicit rev or bookmark"),
118 "please merge with an explicit rev or bookmark"),
119 hint=_("run 'hg heads' to see all heads"))
119 hint=_("run 'hg heads' to see all heads"))
120 else:
120 else:
121 branch = repo[None].branch()
121 branch = repo[None].branch()
122 bheads = repo.branchheads(branch)
122 bheads = repo.branchheads(branch)
123 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
123 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
124
124
125 if len(nbhs) > 2:
125 if len(nbhs) > 2:
126 raise error.Abort(_("branch '%s' has %d heads - "
126 raise error.Abort(_("branch '%s' has %d heads - "
127 "please merge with an explicit rev")
127 "please merge with an explicit rev")
128 % (branch, len(bheads)),
128 % (branch, len(bheads)),
129 hint=_("run 'hg heads .' to see heads"))
129 hint=_("run 'hg heads .' to see heads"))
130
130
131 parent = repo.dirstate.p1()
131 parent = repo.dirstate.p1()
132 if len(nbhs) <= 1:
132 if len(nbhs) <= 1:
133 if len(bheads) > 1:
133 if len(bheads) > 1:
134 raise error.Abort(_("heads are bookmarked - "
134 raise error.Abort(_("heads are bookmarked - "
135 "please merge with an explicit rev"),
135 "please merge with an explicit rev"),
136 hint=_("run 'hg heads' to see all heads"))
136 hint=_("run 'hg heads' to see all heads"))
137 if len(repo.heads()) > 1:
137 if len(repo.heads()) > 1:
138 raise error.Abort(_("branch '%s' has one head - "
138 raise error.Abort(_("branch '%s' has one head - "
139 "please merge with an explicit rev")
139 "please merge with an explicit rev")
140 % branch,
140 % branch,
141 hint=_("run 'hg heads' to see all heads"))
141 hint=_("run 'hg heads' to see all heads"))
142 msg, hint = _('nothing to merge'), None
142 msg, hint = _('nothing to merge'), None
143 if parent != repo.lookup(branch):
143 if parent != repo.lookup(branch):
144 hint = _("use 'hg update' instead")
144 hint = _("use 'hg update' instead")
145 raise error.Abort(msg, hint=hint)
145 raise error.Abort(msg, hint=hint)
146
146
147 if parent not in bheads:
147 if parent not in bheads:
148 raise error.Abort(_('working directory not at a head revision'),
148 raise error.Abort(_('working directory not at a head revision'),
149 hint=_("use 'hg update' or merge with an "
149 hint=_("use 'hg update' or merge with an "
150 "explicit revision"))
150 "explicit revision"))
151 if parent == nbhs[0]:
151 if parent == nbhs[0]:
152 node = nbhs[-1]
152 node = nbhs[-1]
153 else:
153 else:
154 node = nbhs[0]
154 node = nbhs[0]
155 return repo[node].rev()
155 return repo[node].rev()
General Comments 0
You need to be logged in to leave comments. Login now