##// END OF EJS Templates
destutil: use absolute_import
Gregory Szorc -
r27333:2c60b4b2 default
parent child Browse files
Show More
@@ -1,215 +1,217 b''
1 1 # destutil.py - Mercurial utility function for command destination
2 2 #
3 3 # Copyright Matt Mackall <mpm@selenic.com> and other
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 from __future__ import absolute_import
9
8 10 from .i18n import _
9 11 from . import (
10 12 bookmarks,
11 13 error,
12 14 obsolete,
13 15 )
14 16
15 17 def _destupdatevalidate(repo, rev, clean, check):
16 18 """validate that the destination comply to various rules
17 19
18 20 This exists as its own function to help wrapping from extensions."""
19 21 wc = repo[None]
20 22 p1 = wc.p1()
21 23 if not clean:
22 24 # Check that the update is linear.
23 25 #
24 26 # Mercurial do not allow update-merge for non linear pattern
25 27 # (that would be technically possible but was considered too confusing
26 28 # for user a long time ago)
27 29 #
28 30 # See mercurial.merge.update for details
29 31 if p1.rev() not in repo.changelog.ancestors([rev], inclusive=True):
30 32 dirty = wc.dirty(missing=True)
31 33 foreground = obsolete.foreground(repo, [p1.node()])
32 34 if not repo[rev].node() in foreground:
33 35 if dirty:
34 36 msg = _("uncommitted changes")
35 37 hint = _("commit and merge, or update --clean to"
36 38 " discard changes")
37 39 raise error.UpdateAbort(msg, hint=hint)
38 40 elif not check: # destination is not a descendant.
39 41 msg = _("not a linear update")
40 42 hint = _("merge or update --check to force update")
41 43 raise error.UpdateAbort(msg, hint=hint)
42 44
43 45 def _destupdateobs(repo, clean, check):
44 46 """decide of an update destination from obsolescence markers"""
45 47 node = None
46 48 wc = repo[None]
47 49 p1 = wc.p1()
48 50 movemark = None
49 51
50 52 if p1.obsolete() and not p1.children():
51 53 # allow updating to successors
52 54 successors = obsolete.successorssets(repo, p1.node())
53 55
54 56 # behavior of certain cases is as follows,
55 57 #
56 58 # divergent changesets: update to highest rev, similar to what
57 59 # is currently done when there are more than one head
58 60 # (i.e. 'tip')
59 61 #
60 62 # replaced changesets: same as divergent except we know there
61 63 # is no conflict
62 64 #
63 65 # pruned changeset: no update is done; though, we could
64 66 # consider updating to the first non-obsolete parent,
65 67 # similar to what is current done for 'hg prune'
66 68
67 69 if successors:
68 70 # flatten the list here handles both divergent (len > 1)
69 71 # and the usual case (len = 1)
70 72 successors = [n for sub in successors for n in sub]
71 73
72 74 # get the max revision for the given successors set,
73 75 # i.e. the 'tip' of a set
74 76 node = repo.revs('max(%ln)', successors).first()
75 77 if bookmarks.isactivewdirparent(repo):
76 78 movemark = repo['.'].node()
77 79 return node, movemark, None
78 80
79 81 def _destupdatebook(repo, clean, check):
80 82 """decide on an update destination from active bookmark"""
81 83 # we also move the active bookmark, if any
82 84 activemark = None
83 85 node, movemark = bookmarks.calculateupdate(repo.ui, repo, None)
84 86 if node is not None:
85 87 activemark = node
86 88 return node, movemark, activemark
87 89
88 90 def _destupdatebranch(repo, clean, check):
89 91 """decide on an update destination from current branch"""
90 92 wc = repo[None]
91 93 movemark = node = None
92 94 try:
93 95 node = repo.branchtip(wc.branch())
94 96 if bookmarks.isactivewdirparent(repo):
95 97 movemark = repo['.'].node()
96 98 except error.RepoLookupError:
97 99 if wc.branch() == 'default': # no default branch!
98 100 node = repo.lookup('tip') # update to tip
99 101 else:
100 102 raise error.Abort(_("branch %s not found") % wc.branch())
101 103 return node, movemark, None
102 104
103 105 # order in which each step should be evalutated
104 106 # steps are run until one finds a destination
105 107 destupdatesteps = ['evolution', 'bookmark', 'branch']
106 108 # mapping to ease extension overriding steps.
107 109 destupdatestepmap = {'evolution': _destupdateobs,
108 110 'bookmark': _destupdatebook,
109 111 'branch': _destupdatebranch,
110 112 }
111 113
112 114 def destupdate(repo, clean=False, check=False):
113 115 """destination for bare update operation
114 116
115 117 return (rev, movemark, activemark)
116 118
117 119 - rev: the revision to update to,
118 120 - movemark: node to move the active bookmark from
119 121 (cf bookmark.calculate update),
120 122 - activemark: a bookmark to activate at the end of the update.
121 123 """
122 124 node = movemark = activemark = None
123 125
124 126 for step in destupdatesteps:
125 127 node, movemark, activemark = destupdatestepmap[step](repo, clean, check)
126 128 if node is not None:
127 129 break
128 130 rev = repo[node].rev()
129 131
130 132 _destupdatevalidate(repo, rev, clean, check)
131 133
132 134 return rev, movemark, activemark
133 135
134 136 def _destmergebook(repo):
135 137 """find merge destination in the active bookmark case"""
136 138 node = None
137 139 bmheads = repo.bookmarkheads(repo._activebookmark)
138 140 curhead = repo[repo._activebookmark].node()
139 141 if len(bmheads) == 2:
140 142 if curhead == bmheads[0]:
141 143 node = bmheads[1]
142 144 else:
143 145 node = bmheads[0]
144 146 elif len(bmheads) > 2:
145 147 raise error.Abort(_("multiple matching bookmarks to merge - "
146 148 "please merge with an explicit rev or bookmark"),
147 149 hint=_("run 'hg heads' to see all heads"))
148 150 elif len(bmheads) <= 1:
149 151 raise error.Abort(_("no matching bookmark to merge - "
150 152 "please merge with an explicit rev or bookmark"),
151 153 hint=_("run 'hg heads' to see all heads"))
152 154 assert node is not None
153 155 return node
154 156
155 157 def _destmergebranch(repo):
156 158 """find merge destination based on branch heads"""
157 159 node = None
158 160 branch = repo[None].branch()
159 161 bheads = repo.branchheads(branch)
160 162 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
161 163
162 164 if len(nbhs) > 2:
163 165 raise error.Abort(_("branch '%s' has %d heads - "
164 166 "please merge with an explicit rev")
165 167 % (branch, len(bheads)),
166 168 hint=_("run 'hg heads .' to see heads"))
167 169
168 170 parent = repo.dirstate.p1()
169 171 if len(nbhs) <= 1:
170 172 if len(bheads) > 1:
171 173 raise error.Abort(_("heads are bookmarked - "
172 174 "please merge with an explicit rev"),
173 175 hint=_("run 'hg heads' to see all heads"))
174 176 if len(repo.heads()) > 1:
175 177 raise error.Abort(_("branch '%s' has one head - "
176 178 "please merge with an explicit rev")
177 179 % branch,
178 180 hint=_("run 'hg heads' to see all heads"))
179 181 msg, hint = _('nothing to merge'), None
180 182 if parent != repo.lookup(branch):
181 183 hint = _("use 'hg update' instead")
182 184 raise error.Abort(msg, hint=hint)
183 185
184 186 if parent not in bheads:
185 187 raise error.Abort(_('working directory not at a head revision'),
186 188 hint=_("use 'hg update' or merge with an "
187 189 "explicit revision"))
188 190 if parent == nbhs[0]:
189 191 node = nbhs[-1]
190 192 else:
191 193 node = nbhs[0]
192 194 assert node is not None
193 195 return node
194 196
195 197 def destmerge(repo):
196 198 if repo._activebookmark:
197 199 node = _destmergebook(repo)
198 200 else:
199 201 node = _destmergebranch(repo)
200 202 return repo[node].rev()
201 203
202 204 histeditdefaultrevset = 'reverse(only(.) and not public() and not ::merge())'
203 205
204 206 def desthistedit(ui, repo):
205 207 """Default base revision to edit for `hg histedit`."""
206 208 default = ui.config('histedit', 'defaultrev', histeditdefaultrevset)
207 209 if default:
208 210 revs = repo.revs(default)
209 211 if revs:
210 212 # The revset supplied by the user may not be in ascending order nor
211 213 # take the first revision. So do this manually.
212 214 revs.sort()
213 215 return revs.first()
214 216
215 217 return None
@@ -1,220 +1,219 b''
1 1 #require test-repo
2 2
3 3 $ cd "$TESTDIR"/..
4 4
5 5 $ hg files 'set:(**.py)' | xargs python contrib/check-py3-compat.py
6 6 contrib/casesmash.py not using absolute_import
7 7 contrib/check-code.py not using absolute_import
8 8 contrib/check-code.py requires print_function
9 9 contrib/check-config.py not using absolute_import
10 10 contrib/check-config.py requires print_function
11 11 contrib/debugcmdserver.py not using absolute_import
12 12 contrib/debugcmdserver.py requires print_function
13 13 contrib/debugshell.py not using absolute_import
14 14 contrib/fixpax.py not using absolute_import
15 15 contrib/fixpax.py requires print_function
16 16 contrib/hgclient.py not using absolute_import
17 17 contrib/hgclient.py requires print_function
18 18 contrib/hgfixes/fix_bytes.py not using absolute_import
19 19 contrib/hgfixes/fix_bytesmod.py not using absolute_import
20 20 contrib/hgfixes/fix_leftover_imports.py not using absolute_import
21 21 contrib/import-checker.py not using absolute_import
22 22 contrib/import-checker.py requires print_function
23 23 contrib/memory.py not using absolute_import
24 24 contrib/perf.py not using absolute_import
25 25 contrib/python-hook-examples.py not using absolute_import
26 26 contrib/revsetbenchmarks.py not using absolute_import
27 27 contrib/revsetbenchmarks.py requires print_function
28 28 contrib/showstack.py not using absolute_import
29 29 contrib/synthrepo.py not using absolute_import
30 30 contrib/win32/hgwebdir_wsgi.py not using absolute_import
31 31 doc/check-seclevel.py not using absolute_import
32 32 doc/gendoc.py not using absolute_import
33 33 doc/hgmanpage.py not using absolute_import
34 34 hgext/__init__.py not using absolute_import
35 35 hgext/acl.py not using absolute_import
36 36 hgext/blackbox.py not using absolute_import
37 37 hgext/bugzilla.py not using absolute_import
38 38 hgext/censor.py not using absolute_import
39 39 hgext/children.py not using absolute_import
40 40 hgext/churn.py not using absolute_import
41 41 hgext/clonebundles.py not using absolute_import
42 42 hgext/color.py not using absolute_import
43 43 hgext/convert/__init__.py not using absolute_import
44 44 hgext/convert/bzr.py not using absolute_import
45 45 hgext/convert/common.py not using absolute_import
46 46 hgext/convert/convcmd.py not using absolute_import
47 47 hgext/convert/cvs.py not using absolute_import
48 48 hgext/convert/cvsps.py not using absolute_import
49 49 hgext/convert/darcs.py not using absolute_import
50 50 hgext/convert/filemap.py not using absolute_import
51 51 hgext/convert/git.py not using absolute_import
52 52 hgext/convert/gnuarch.py not using absolute_import
53 53 hgext/convert/hg.py not using absolute_import
54 54 hgext/convert/monotone.py not using absolute_import
55 55 hgext/convert/p4.py not using absolute_import
56 56 hgext/convert/subversion.py not using absolute_import
57 57 hgext/convert/transport.py not using absolute_import
58 58 hgext/eol.py not using absolute_import
59 59 hgext/extdiff.py not using absolute_import
60 60 hgext/factotum.py not using absolute_import
61 61 hgext/fetch.py not using absolute_import
62 62 hgext/gpg.py not using absolute_import
63 63 hgext/graphlog.py not using absolute_import
64 64 hgext/hgcia.py not using absolute_import
65 65 hgext/hgk.py not using absolute_import
66 66 hgext/highlight/__init__.py not using absolute_import
67 67 hgext/highlight/highlight.py not using absolute_import
68 68 hgext/histedit.py not using absolute_import
69 69 hgext/keyword.py not using absolute_import
70 70 hgext/largefiles/__init__.py not using absolute_import
71 71 hgext/largefiles/basestore.py not using absolute_import
72 72 hgext/largefiles/lfcommands.py not using absolute_import
73 73 hgext/largefiles/lfutil.py not using absolute_import
74 74 hgext/largefiles/localstore.py not using absolute_import
75 75 hgext/largefiles/overrides.py not using absolute_import
76 76 hgext/largefiles/proto.py not using absolute_import
77 77 hgext/largefiles/remotestore.py not using absolute_import
78 78 hgext/largefiles/reposetup.py not using absolute_import
79 79 hgext/largefiles/uisetup.py not using absolute_import
80 80 hgext/largefiles/wirestore.py not using absolute_import
81 81 hgext/mq.py not using absolute_import
82 82 hgext/notify.py not using absolute_import
83 83 hgext/pager.py not using absolute_import
84 84 hgext/patchbomb.py not using absolute_import
85 85 hgext/purge.py not using absolute_import
86 86 hgext/rebase.py not using absolute_import
87 87 hgext/record.py not using absolute_import
88 88 hgext/relink.py not using absolute_import
89 89 hgext/schemes.py not using absolute_import
90 90 hgext/share.py not using absolute_import
91 91 hgext/shelve.py not using absolute_import
92 92 hgext/strip.py not using absolute_import
93 93 hgext/transplant.py not using absolute_import
94 94 hgext/win32mbcs.py not using absolute_import
95 95 hgext/win32text.py not using absolute_import
96 96 hgext/zeroconf/Zeroconf.py not using absolute_import
97 97 hgext/zeroconf/Zeroconf.py requires print_function
98 98 hgext/zeroconf/__init__.py not using absolute_import
99 99 i18n/check-translation.py not using absolute_import
100 100 i18n/polib.py not using absolute_import
101 101 mercurial/byterange.py not using absolute_import
102 102 mercurial/cmdutil.py not using absolute_import
103 103 mercurial/commands.py not using absolute_import
104 104 mercurial/commandserver.py not using absolute_import
105 105 mercurial/context.py not using absolute_import
106 mercurial/destutil.py not using absolute_import
107 106 mercurial/dirstate.py not using absolute_import
108 107 mercurial/dispatch.py requires print_function
109 108 mercurial/encoding.py not using absolute_import
110 109 mercurial/exchange.py not using absolute_import
111 110 mercurial/help.py not using absolute_import
112 111 mercurial/httpclient/__init__.py not using absolute_import
113 112 mercurial/httpclient/_readers.py not using absolute_import
114 113 mercurial/httpclient/socketutil.py not using absolute_import
115 114 mercurial/httpconnection.py not using absolute_import
116 115 mercurial/keepalive.py not using absolute_import
117 116 mercurial/keepalive.py requires print_function
118 117 mercurial/localrepo.py not using absolute_import
119 118 mercurial/lsprof.py requires print_function
120 119 mercurial/lsprofcalltree.py not using absolute_import
121 120 mercurial/lsprofcalltree.py requires print_function
122 121 mercurial/mail.py requires print_function
123 122 mercurial/manifest.py not using absolute_import
124 123 mercurial/mdiff.py not using absolute_import
125 124 mercurial/patch.py not using absolute_import
126 125 mercurial/pure/base85.py not using absolute_import
127 126 mercurial/pure/bdiff.py not using absolute_import
128 127 mercurial/pure/diffhelpers.py not using absolute_import
129 128 mercurial/pure/mpatch.py not using absolute_import
130 129 mercurial/pure/osutil.py not using absolute_import
131 130 mercurial/pure/parsers.py not using absolute_import
132 131 mercurial/pvec.py not using absolute_import
133 132 mercurial/py3kcompat.py not using absolute_import
134 133 mercurial/revlog.py not using absolute_import
135 134 mercurial/scmposix.py not using absolute_import
136 135 mercurial/scmutil.py not using absolute_import
137 136 mercurial/scmwindows.py not using absolute_import
138 137 mercurial/similar.py not using absolute_import
139 138 mercurial/store.py not using absolute_import
140 139 mercurial/util.py not using absolute_import
141 140 mercurial/windows.py not using absolute_import
142 141 setup.py not using absolute_import
143 142 tests/filterpyflakes.py requires print_function
144 143 tests/generate-working-copy-states.py requires print_function
145 144 tests/get-with-headers.py requires print_function
146 145 tests/heredoctest.py requires print_function
147 146 tests/hypothesishelpers.py not using absolute_import
148 147 tests/hypothesishelpers.py requires print_function
149 148 tests/killdaemons.py not using absolute_import
150 149 tests/md5sum.py not using absolute_import
151 150 tests/mockblackbox.py not using absolute_import
152 151 tests/printenv.py not using absolute_import
153 152 tests/readlink.py not using absolute_import
154 153 tests/readlink.py requires print_function
155 154 tests/revlog-formatv0.py not using absolute_import
156 155 tests/run-tests.py not using absolute_import
157 156 tests/seq.py not using absolute_import
158 157 tests/seq.py requires print_function
159 158 tests/silenttestrunner.py not using absolute_import
160 159 tests/silenttestrunner.py requires print_function
161 160 tests/sitecustomize.py not using absolute_import
162 161 tests/svn-safe-append.py not using absolute_import
163 162 tests/svnxml.py not using absolute_import
164 163 tests/test-ancestor.py requires print_function
165 164 tests/test-atomictempfile.py not using absolute_import
166 165 tests/test-batching.py not using absolute_import
167 166 tests/test-batching.py requires print_function
168 167 tests/test-bdiff.py not using absolute_import
169 168 tests/test-bdiff.py requires print_function
170 169 tests/test-context.py not using absolute_import
171 170 tests/test-context.py requires print_function
172 171 tests/test-demandimport.py not using absolute_import
173 172 tests/test-demandimport.py requires print_function
174 173 tests/test-dispatch.py not using absolute_import
175 174 tests/test-dispatch.py requires print_function
176 175 tests/test-doctest.py not using absolute_import
177 176 tests/test-duplicateoptions.py not using absolute_import
178 177 tests/test-duplicateoptions.py requires print_function
179 178 tests/test-filecache.py not using absolute_import
180 179 tests/test-filecache.py requires print_function
181 180 tests/test-filelog.py not using absolute_import
182 181 tests/test-filelog.py requires print_function
183 182 tests/test-hg-parseurl.py not using absolute_import
184 183 tests/test-hg-parseurl.py requires print_function
185 184 tests/test-hgweb-auth.py not using absolute_import
186 185 tests/test-hgweb-auth.py requires print_function
187 186 tests/test-hgwebdir-paths.py not using absolute_import
188 187 tests/test-hybridencode.py not using absolute_import
189 188 tests/test-hybridencode.py requires print_function
190 189 tests/test-lrucachedict.py not using absolute_import
191 190 tests/test-lrucachedict.py requires print_function
192 191 tests/test-manifest.py not using absolute_import
193 192 tests/test-minirst.py not using absolute_import
194 193 tests/test-minirst.py requires print_function
195 194 tests/test-parseindex2.py not using absolute_import
196 195 tests/test-parseindex2.py requires print_function
197 196 tests/test-pathencode.py not using absolute_import
198 197 tests/test-pathencode.py requires print_function
199 198 tests/test-propertycache.py not using absolute_import
200 199 tests/test-propertycache.py requires print_function
201 200 tests/test-revlog-ancestry.py not using absolute_import
202 201 tests/test-revlog-ancestry.py requires print_function
203 202 tests/test-run-tests.py not using absolute_import
204 203 tests/test-simplemerge.py not using absolute_import
205 204 tests/test-status-inprocess.py not using absolute_import
206 205 tests/test-status-inprocess.py requires print_function
207 206 tests/test-symlink-os-yes-fs-no.py not using absolute_import
208 207 tests/test-trusted.py not using absolute_import
209 208 tests/test-trusted.py requires print_function
210 209 tests/test-ui-color.py not using absolute_import
211 210 tests/test-ui-color.py requires print_function
212 211 tests/test-ui-config.py not using absolute_import
213 212 tests/test-ui-config.py requires print_function
214 213 tests/test-ui-verbosity.py not using absolute_import
215 214 tests/test-ui-verbosity.py requires print_function
216 215 tests/test-url.py not using absolute_import
217 216 tests/test-url.py requires print_function
218 217 tests/test-walkrepo.py requires print_function
219 218 tests/test-wireproto.py requires print_function
220 219 tests/tinyproxy.py requires print_function
General Comments 0
You need to be logged in to leave comments. Login now