##// END OF EJS Templates
py3: make largefiles/lfutil.py use absolute_import
liscju -
r29309:bfc10525 default
parent child Browse files
Show More
@@ -1,655 +1,664 b''
1 # Copyright 2009-2010 Gregory P. Ward
1 # Copyright 2009-2010 Gregory P. Ward
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
3 # Copyright 2010-2011 Fog Creek Software
3 # Copyright 2010-2011 Fog Creek Software
4 # Copyright 2010-2011 Unity Technologies
4 # Copyright 2010-2011 Unity Technologies
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 '''largefiles utility code: must not import other modules in this package.'''
9 '''largefiles utility code: must not import other modules in this package.'''
10 from __future__ import absolute_import
10
11
12 import copy
11 import os
13 import os
12 import platform
14 import platform
13 import stat
15 import stat
14 import copy
16
17 from mercurial.i18n import _
15
18
16 from mercurial import dirstate, httpconnection, match as match_, util, scmutil
19 from mercurial import (
17 from mercurial.i18n import _
20 dirstate,
18 from mercurial import node, error
21 error,
22 httpconnection,
23 match as match_,
24 node,
25 scmutil,
26 util,
27 )
19
28
20 shortname = '.hglf'
29 shortname = '.hglf'
21 shortnameslash = shortname + '/'
30 shortnameslash = shortname + '/'
22 longname = 'largefiles'
31 longname = 'largefiles'
23
32
24
33
25 # -- Private worker functions ------------------------------------------
34 # -- Private worker functions ------------------------------------------
26
35
27 def getminsize(ui, assumelfiles, opt, default=10):
36 def getminsize(ui, assumelfiles, opt, default=10):
28 lfsize = opt
37 lfsize = opt
29 if not lfsize and assumelfiles:
38 if not lfsize and assumelfiles:
30 lfsize = ui.config(longname, 'minsize', default=default)
39 lfsize = ui.config(longname, 'minsize', default=default)
31 if lfsize:
40 if lfsize:
32 try:
41 try:
33 lfsize = float(lfsize)
42 lfsize = float(lfsize)
34 except ValueError:
43 except ValueError:
35 raise error.Abort(_('largefiles: size must be number (not %s)\n')
44 raise error.Abort(_('largefiles: size must be number (not %s)\n')
36 % lfsize)
45 % lfsize)
37 if lfsize is None:
46 if lfsize is None:
38 raise error.Abort(_('minimum size for largefiles must be specified'))
47 raise error.Abort(_('minimum size for largefiles must be specified'))
39 return lfsize
48 return lfsize
40
49
41 def link(src, dest):
50 def link(src, dest):
42 """Try to create hardlink - if that fails, efficiently make a copy."""
51 """Try to create hardlink - if that fails, efficiently make a copy."""
43 util.makedirs(os.path.dirname(dest))
52 util.makedirs(os.path.dirname(dest))
44 try:
53 try:
45 util.oslink(src, dest)
54 util.oslink(src, dest)
46 except OSError:
55 except OSError:
47 # if hardlinks fail, fallback on atomic copy
56 # if hardlinks fail, fallback on atomic copy
48 dst = util.atomictempfile(dest)
57 dst = util.atomictempfile(dest)
49 for chunk in util.filechunkiter(open(src, 'rb')):
58 for chunk in util.filechunkiter(open(src, 'rb')):
50 dst.write(chunk)
59 dst.write(chunk)
51 dst.close()
60 dst.close()
52 os.chmod(dest, os.stat(src).st_mode)
61 os.chmod(dest, os.stat(src).st_mode)
53
62
54 def usercachepath(ui, hash):
63 def usercachepath(ui, hash):
55 '''Return the correct location in the "global" largefiles cache for a file
64 '''Return the correct location in the "global" largefiles cache for a file
56 with the given hash.
65 with the given hash.
57 This cache is used for sharing of largefiles across repositories - both
66 This cache is used for sharing of largefiles across repositories - both
58 to preserve download bandwidth and storage space.'''
67 to preserve download bandwidth and storage space.'''
59 return os.path.join(_usercachedir(ui), hash)
68 return os.path.join(_usercachedir(ui), hash)
60
69
61 def _usercachedir(ui):
70 def _usercachedir(ui):
62 '''Return the location of the "global" largefiles cache.'''
71 '''Return the location of the "global" largefiles cache.'''
63 path = ui.configpath(longname, 'usercache', None)
72 path = ui.configpath(longname, 'usercache', None)
64 if path:
73 if path:
65 return path
74 return path
66 if os.name == 'nt':
75 if os.name == 'nt':
67 appdata = os.getenv('LOCALAPPDATA', os.getenv('APPDATA'))
76 appdata = os.getenv('LOCALAPPDATA', os.getenv('APPDATA'))
68 if appdata:
77 if appdata:
69 return os.path.join(appdata, longname)
78 return os.path.join(appdata, longname)
70 elif platform.system() == 'Darwin':
79 elif platform.system() == 'Darwin':
71 home = os.getenv('HOME')
80 home = os.getenv('HOME')
72 if home:
81 if home:
73 return os.path.join(home, 'Library', 'Caches', longname)
82 return os.path.join(home, 'Library', 'Caches', longname)
74 elif os.name == 'posix':
83 elif os.name == 'posix':
75 path = os.getenv('XDG_CACHE_HOME')
84 path = os.getenv('XDG_CACHE_HOME')
76 if path:
85 if path:
77 return os.path.join(path, longname)
86 return os.path.join(path, longname)
78 home = os.getenv('HOME')
87 home = os.getenv('HOME')
79 if home:
88 if home:
80 return os.path.join(home, '.cache', longname)
89 return os.path.join(home, '.cache', longname)
81 else:
90 else:
82 raise error.Abort(_('unknown operating system: %s\n') % os.name)
91 raise error.Abort(_('unknown operating system: %s\n') % os.name)
83 raise error.Abort(_('unknown %s usercache location\n') % longname)
92 raise error.Abort(_('unknown %s usercache location\n') % longname)
84
93
85 def inusercache(ui, hash):
94 def inusercache(ui, hash):
86 path = usercachepath(ui, hash)
95 path = usercachepath(ui, hash)
87 return os.path.exists(path)
96 return os.path.exists(path)
88
97
89 def findfile(repo, hash):
98 def findfile(repo, hash):
90 '''Return store path of the largefile with the specified hash.
99 '''Return store path of the largefile with the specified hash.
91 As a side effect, the file might be linked from user cache.
100 As a side effect, the file might be linked from user cache.
92 Return None if the file can't be found locally.'''
101 Return None if the file can't be found locally.'''
93 path, exists = findstorepath(repo, hash)
102 path, exists = findstorepath(repo, hash)
94 if exists:
103 if exists:
95 repo.ui.note(_('found %s in store\n') % hash)
104 repo.ui.note(_('found %s in store\n') % hash)
96 return path
105 return path
97 elif inusercache(repo.ui, hash):
106 elif inusercache(repo.ui, hash):
98 repo.ui.note(_('found %s in system cache\n') % hash)
107 repo.ui.note(_('found %s in system cache\n') % hash)
99 path = storepath(repo, hash)
108 path = storepath(repo, hash)
100 link(usercachepath(repo.ui, hash), path)
109 link(usercachepath(repo.ui, hash), path)
101 return path
110 return path
102 return None
111 return None
103
112
104 class largefilesdirstate(dirstate.dirstate):
113 class largefilesdirstate(dirstate.dirstate):
105 def __getitem__(self, key):
114 def __getitem__(self, key):
106 return super(largefilesdirstate, self).__getitem__(unixpath(key))
115 return super(largefilesdirstate, self).__getitem__(unixpath(key))
107 def normal(self, f):
116 def normal(self, f):
108 return super(largefilesdirstate, self).normal(unixpath(f))
117 return super(largefilesdirstate, self).normal(unixpath(f))
109 def remove(self, f):
118 def remove(self, f):
110 return super(largefilesdirstate, self).remove(unixpath(f))
119 return super(largefilesdirstate, self).remove(unixpath(f))
111 def add(self, f):
120 def add(self, f):
112 return super(largefilesdirstate, self).add(unixpath(f))
121 return super(largefilesdirstate, self).add(unixpath(f))
113 def drop(self, f):
122 def drop(self, f):
114 return super(largefilesdirstate, self).drop(unixpath(f))
123 return super(largefilesdirstate, self).drop(unixpath(f))
115 def forget(self, f):
124 def forget(self, f):
116 return super(largefilesdirstate, self).forget(unixpath(f))
125 return super(largefilesdirstate, self).forget(unixpath(f))
117 def normallookup(self, f):
126 def normallookup(self, f):
118 return super(largefilesdirstate, self).normallookup(unixpath(f))
127 return super(largefilesdirstate, self).normallookup(unixpath(f))
119 def _ignore(self, f):
128 def _ignore(self, f):
120 return False
129 return False
121 def write(self, tr=False):
130 def write(self, tr=False):
122 # (1) disable PENDING mode always
131 # (1) disable PENDING mode always
123 # (lfdirstate isn't yet managed as a part of the transaction)
132 # (lfdirstate isn't yet managed as a part of the transaction)
124 # (2) avoid develwarn 'use dirstate.write with ....'
133 # (2) avoid develwarn 'use dirstate.write with ....'
125 super(largefilesdirstate, self).write(None)
134 super(largefilesdirstate, self).write(None)
126
135
127 def openlfdirstate(ui, repo, create=True):
136 def openlfdirstate(ui, repo, create=True):
128 '''
137 '''
129 Return a dirstate object that tracks largefiles: i.e. its root is
138 Return a dirstate object that tracks largefiles: i.e. its root is
130 the repo root, but it is saved in .hg/largefiles/dirstate.
139 the repo root, but it is saved in .hg/largefiles/dirstate.
131 '''
140 '''
132 vfs = repo.vfs
141 vfs = repo.vfs
133 lfstoredir = longname
142 lfstoredir = longname
134 opener = scmutil.opener(vfs.join(lfstoredir))
143 opener = scmutil.opener(vfs.join(lfstoredir))
135 lfdirstate = largefilesdirstate(opener, ui, repo.root,
144 lfdirstate = largefilesdirstate(opener, ui, repo.root,
136 repo.dirstate._validate)
145 repo.dirstate._validate)
137
146
138 # If the largefiles dirstate does not exist, populate and create
147 # If the largefiles dirstate does not exist, populate and create
139 # it. This ensures that we create it on the first meaningful
148 # it. This ensures that we create it on the first meaningful
140 # largefiles operation in a new clone.
149 # largefiles operation in a new clone.
141 if create and not vfs.exists(vfs.join(lfstoredir, 'dirstate')):
150 if create and not vfs.exists(vfs.join(lfstoredir, 'dirstate')):
142 matcher = getstandinmatcher(repo)
151 matcher = getstandinmatcher(repo)
143 standins = repo.dirstate.walk(matcher, [], False, False)
152 standins = repo.dirstate.walk(matcher, [], False, False)
144
153
145 if len(standins) > 0:
154 if len(standins) > 0:
146 vfs.makedirs(lfstoredir)
155 vfs.makedirs(lfstoredir)
147
156
148 for standin in standins:
157 for standin in standins:
149 lfile = splitstandin(standin)
158 lfile = splitstandin(standin)
150 lfdirstate.normallookup(lfile)
159 lfdirstate.normallookup(lfile)
151 return lfdirstate
160 return lfdirstate
152
161
153 def lfdirstatestatus(lfdirstate, repo):
162 def lfdirstatestatus(lfdirstate, repo):
154 wctx = repo['.']
163 wctx = repo['.']
155 match = match_.always(repo.root, repo.getcwd())
164 match = match_.always(repo.root, repo.getcwd())
156 unsure, s = lfdirstate.status(match, [], False, False, False)
165 unsure, s = lfdirstate.status(match, [], False, False, False)
157 modified, clean = s.modified, s.clean
166 modified, clean = s.modified, s.clean
158 for lfile in unsure:
167 for lfile in unsure:
159 try:
168 try:
160 fctx = wctx[standin(lfile)]
169 fctx = wctx[standin(lfile)]
161 except LookupError:
170 except LookupError:
162 fctx = None
171 fctx = None
163 if not fctx or fctx.data().strip() != hashfile(repo.wjoin(lfile)):
172 if not fctx or fctx.data().strip() != hashfile(repo.wjoin(lfile)):
164 modified.append(lfile)
173 modified.append(lfile)
165 else:
174 else:
166 clean.append(lfile)
175 clean.append(lfile)
167 lfdirstate.normal(lfile)
176 lfdirstate.normal(lfile)
168 return s
177 return s
169
178
170 def listlfiles(repo, rev=None, matcher=None):
179 def listlfiles(repo, rev=None, matcher=None):
171 '''return a list of largefiles in the working copy or the
180 '''return a list of largefiles in the working copy or the
172 specified changeset'''
181 specified changeset'''
173
182
174 if matcher is None:
183 if matcher is None:
175 matcher = getstandinmatcher(repo)
184 matcher = getstandinmatcher(repo)
176
185
177 # ignore unknown files in working directory
186 # ignore unknown files in working directory
178 return [splitstandin(f)
187 return [splitstandin(f)
179 for f in repo[rev].walk(matcher)
188 for f in repo[rev].walk(matcher)
180 if rev is not None or repo.dirstate[f] != '?']
189 if rev is not None or repo.dirstate[f] != '?']
181
190
182 def instore(repo, hash, forcelocal=False):
191 def instore(repo, hash, forcelocal=False):
183 '''Return true if a largefile with the given hash exists in the user
192 '''Return true if a largefile with the given hash exists in the user
184 cache.'''
193 cache.'''
185 return os.path.exists(storepath(repo, hash, forcelocal))
194 return os.path.exists(storepath(repo, hash, forcelocal))
186
195
187 def storepath(repo, hash, forcelocal=False):
196 def storepath(repo, hash, forcelocal=False):
188 '''Return the correct location in the repository largefiles cache for a
197 '''Return the correct location in the repository largefiles cache for a
189 file with the given hash.'''
198 file with the given hash.'''
190 if not forcelocal and repo.shared():
199 if not forcelocal and repo.shared():
191 return repo.vfs.reljoin(repo.sharedpath, longname, hash)
200 return repo.vfs.reljoin(repo.sharedpath, longname, hash)
192 return repo.join(longname, hash)
201 return repo.join(longname, hash)
193
202
194 def findstorepath(repo, hash):
203 def findstorepath(repo, hash):
195 '''Search through the local store path(s) to find the file for the given
204 '''Search through the local store path(s) to find the file for the given
196 hash. If the file is not found, its path in the primary store is returned.
205 hash. If the file is not found, its path in the primary store is returned.
197 The return value is a tuple of (path, exists(path)).
206 The return value is a tuple of (path, exists(path)).
198 '''
207 '''
199 # For shared repos, the primary store is in the share source. But for
208 # For shared repos, the primary store is in the share source. But for
200 # backward compatibility, force a lookup in the local store if it wasn't
209 # backward compatibility, force a lookup in the local store if it wasn't
201 # found in the share source.
210 # found in the share source.
202 path = storepath(repo, hash, False)
211 path = storepath(repo, hash, False)
203
212
204 if instore(repo, hash):
213 if instore(repo, hash):
205 return (path, True)
214 return (path, True)
206 elif repo.shared() and instore(repo, hash, True):
215 elif repo.shared() and instore(repo, hash, True):
207 return storepath(repo, hash, True)
216 return storepath(repo, hash, True)
208
217
209 return (path, False)
218 return (path, False)
210
219
211 def copyfromcache(repo, hash, filename):
220 def copyfromcache(repo, hash, filename):
212 '''Copy the specified largefile from the repo or system cache to
221 '''Copy the specified largefile from the repo or system cache to
213 filename in the repository. Return true on success or false if the
222 filename in the repository. Return true on success or false if the
214 file was not found in either cache (which should not happened:
223 file was not found in either cache (which should not happened:
215 this is meant to be called only after ensuring that the needed
224 this is meant to be called only after ensuring that the needed
216 largefile exists in the cache).'''
225 largefile exists in the cache).'''
217 wvfs = repo.wvfs
226 wvfs = repo.wvfs
218 path = findfile(repo, hash)
227 path = findfile(repo, hash)
219 if path is None:
228 if path is None:
220 return False
229 return False
221 wvfs.makedirs(wvfs.dirname(wvfs.join(filename)))
230 wvfs.makedirs(wvfs.dirname(wvfs.join(filename)))
222 # The write may fail before the file is fully written, but we
231 # The write may fail before the file is fully written, but we
223 # don't use atomic writes in the working copy.
232 # don't use atomic writes in the working copy.
224 with open(path, 'rb') as srcfd:
233 with open(path, 'rb') as srcfd:
225 with wvfs(filename, 'wb') as destfd:
234 with wvfs(filename, 'wb') as destfd:
226 gothash = copyandhash(srcfd, destfd)
235 gothash = copyandhash(srcfd, destfd)
227 if gothash != hash:
236 if gothash != hash:
228 repo.ui.warn(_('%s: data corruption in %s with hash %s\n')
237 repo.ui.warn(_('%s: data corruption in %s with hash %s\n')
229 % (filename, path, gothash))
238 % (filename, path, gothash))
230 wvfs.unlink(filename)
239 wvfs.unlink(filename)
231 return False
240 return False
232 return True
241 return True
233
242
234 def copytostore(repo, rev, file, uploaded=False):
243 def copytostore(repo, rev, file, uploaded=False):
235 wvfs = repo.wvfs
244 wvfs = repo.wvfs
236 hash = readstandin(repo, file, rev)
245 hash = readstandin(repo, file, rev)
237 if instore(repo, hash):
246 if instore(repo, hash):
238 return
247 return
239 if wvfs.exists(file):
248 if wvfs.exists(file):
240 copytostoreabsolute(repo, wvfs.join(file), hash)
249 copytostoreabsolute(repo, wvfs.join(file), hash)
241 else:
250 else:
242 repo.ui.warn(_("%s: largefile %s not available from local store\n") %
251 repo.ui.warn(_("%s: largefile %s not available from local store\n") %
243 (file, hash))
252 (file, hash))
244
253
245 def copyalltostore(repo, node):
254 def copyalltostore(repo, node):
246 '''Copy all largefiles in a given revision to the store'''
255 '''Copy all largefiles in a given revision to the store'''
247
256
248 ctx = repo[node]
257 ctx = repo[node]
249 for filename in ctx.files():
258 for filename in ctx.files():
250 if isstandin(filename) and filename in ctx.manifest():
259 if isstandin(filename) and filename in ctx.manifest():
251 realfile = splitstandin(filename)
260 realfile = splitstandin(filename)
252 copytostore(repo, ctx.node(), realfile)
261 copytostore(repo, ctx.node(), realfile)
253
262
254
263
255 def copytostoreabsolute(repo, file, hash):
264 def copytostoreabsolute(repo, file, hash):
256 if inusercache(repo.ui, hash):
265 if inusercache(repo.ui, hash):
257 link(usercachepath(repo.ui, hash), storepath(repo, hash))
266 link(usercachepath(repo.ui, hash), storepath(repo, hash))
258 else:
267 else:
259 util.makedirs(os.path.dirname(storepath(repo, hash)))
268 util.makedirs(os.path.dirname(storepath(repo, hash)))
260 dst = util.atomictempfile(storepath(repo, hash),
269 dst = util.atomictempfile(storepath(repo, hash),
261 createmode=repo.store.createmode)
270 createmode=repo.store.createmode)
262 for chunk in util.filechunkiter(open(file, 'rb')):
271 for chunk in util.filechunkiter(open(file, 'rb')):
263 dst.write(chunk)
272 dst.write(chunk)
264 dst.close()
273 dst.close()
265 linktousercache(repo, hash)
274 linktousercache(repo, hash)
266
275
267 def linktousercache(repo, hash):
276 def linktousercache(repo, hash):
268 '''Link / copy the largefile with the specified hash from the store
277 '''Link / copy the largefile with the specified hash from the store
269 to the cache.'''
278 to the cache.'''
270 path = usercachepath(repo.ui, hash)
279 path = usercachepath(repo.ui, hash)
271 link(storepath(repo, hash), path)
280 link(storepath(repo, hash), path)
272
281
273 def getstandinmatcher(repo, rmatcher=None):
282 def getstandinmatcher(repo, rmatcher=None):
274 '''Return a match object that applies rmatcher to the standin directory'''
283 '''Return a match object that applies rmatcher to the standin directory'''
275 wvfs = repo.wvfs
284 wvfs = repo.wvfs
276 standindir = shortname
285 standindir = shortname
277
286
278 # no warnings about missing files or directories
287 # no warnings about missing files or directories
279 badfn = lambda f, msg: None
288 badfn = lambda f, msg: None
280
289
281 if rmatcher and not rmatcher.always():
290 if rmatcher and not rmatcher.always():
282 pats = [wvfs.join(standindir, pat) for pat in rmatcher.files()]
291 pats = [wvfs.join(standindir, pat) for pat in rmatcher.files()]
283 if not pats:
292 if not pats:
284 pats = [wvfs.join(standindir)]
293 pats = [wvfs.join(standindir)]
285 match = scmutil.match(repo[None], pats, badfn=badfn)
294 match = scmutil.match(repo[None], pats, badfn=badfn)
286 # if pats is empty, it would incorrectly always match, so clear _always
295 # if pats is empty, it would incorrectly always match, so clear _always
287 match._always = False
296 match._always = False
288 else:
297 else:
289 # no patterns: relative to repo root
298 # no patterns: relative to repo root
290 match = scmutil.match(repo[None], [wvfs.join(standindir)], badfn=badfn)
299 match = scmutil.match(repo[None], [wvfs.join(standindir)], badfn=badfn)
291 return match
300 return match
292
301
293 def composestandinmatcher(repo, rmatcher):
302 def composestandinmatcher(repo, rmatcher):
294 '''Return a matcher that accepts standins corresponding to the
303 '''Return a matcher that accepts standins corresponding to the
295 files accepted by rmatcher. Pass the list of files in the matcher
304 files accepted by rmatcher. Pass the list of files in the matcher
296 as the paths specified by the user.'''
305 as the paths specified by the user.'''
297 smatcher = getstandinmatcher(repo, rmatcher)
306 smatcher = getstandinmatcher(repo, rmatcher)
298 isstandin = smatcher.matchfn
307 isstandin = smatcher.matchfn
299 def composedmatchfn(f):
308 def composedmatchfn(f):
300 return isstandin(f) and rmatcher.matchfn(splitstandin(f))
309 return isstandin(f) and rmatcher.matchfn(splitstandin(f))
301 smatcher.matchfn = composedmatchfn
310 smatcher.matchfn = composedmatchfn
302
311
303 return smatcher
312 return smatcher
304
313
305 def standin(filename):
314 def standin(filename):
306 '''Return the repo-relative path to the standin for the specified big
315 '''Return the repo-relative path to the standin for the specified big
307 file.'''
316 file.'''
308 # Notes:
317 # Notes:
309 # 1) Some callers want an absolute path, but for instance addlargefiles
318 # 1) Some callers want an absolute path, but for instance addlargefiles
310 # needs it repo-relative so it can be passed to repo[None].add(). So
319 # needs it repo-relative so it can be passed to repo[None].add(). So
311 # leave it up to the caller to use repo.wjoin() to get an absolute path.
320 # leave it up to the caller to use repo.wjoin() to get an absolute path.
312 # 2) Join with '/' because that's what dirstate always uses, even on
321 # 2) Join with '/' because that's what dirstate always uses, even on
313 # Windows. Change existing separator to '/' first in case we are
322 # Windows. Change existing separator to '/' first in case we are
314 # passed filenames from an external source (like the command line).
323 # passed filenames from an external source (like the command line).
315 return shortnameslash + util.pconvert(filename)
324 return shortnameslash + util.pconvert(filename)
316
325
317 def isstandin(filename):
326 def isstandin(filename):
318 '''Return true if filename is a big file standin. filename must be
327 '''Return true if filename is a big file standin. filename must be
319 in Mercurial's internal form (slash-separated).'''
328 in Mercurial's internal form (slash-separated).'''
320 return filename.startswith(shortnameslash)
329 return filename.startswith(shortnameslash)
321
330
322 def splitstandin(filename):
331 def splitstandin(filename):
323 # Split on / because that's what dirstate always uses, even on Windows.
332 # Split on / because that's what dirstate always uses, even on Windows.
324 # Change local separator to / first just in case we are passed filenames
333 # Change local separator to / first just in case we are passed filenames
325 # from an external source (like the command line).
334 # from an external source (like the command line).
326 bits = util.pconvert(filename).split('/', 1)
335 bits = util.pconvert(filename).split('/', 1)
327 if len(bits) == 2 and bits[0] == shortname:
336 if len(bits) == 2 and bits[0] == shortname:
328 return bits[1]
337 return bits[1]
329 else:
338 else:
330 return None
339 return None
331
340
332 def updatestandin(repo, standin):
341 def updatestandin(repo, standin):
333 file = repo.wjoin(splitstandin(standin))
342 file = repo.wjoin(splitstandin(standin))
334 if repo.wvfs.exists(splitstandin(standin)):
343 if repo.wvfs.exists(splitstandin(standin)):
335 hash = hashfile(file)
344 hash = hashfile(file)
336 executable = getexecutable(file)
345 executable = getexecutable(file)
337 writestandin(repo, standin, hash, executable)
346 writestandin(repo, standin, hash, executable)
338 else:
347 else:
339 raise error.Abort(_('%s: file not found!') % splitstandin(standin))
348 raise error.Abort(_('%s: file not found!') % splitstandin(standin))
340
349
341 def readstandin(repo, filename, node=None):
350 def readstandin(repo, filename, node=None):
342 '''read hex hash from standin for filename at given node, or working
351 '''read hex hash from standin for filename at given node, or working
343 directory if no node is given'''
352 directory if no node is given'''
344 return repo[node][standin(filename)].data().strip()
353 return repo[node][standin(filename)].data().strip()
345
354
346 def writestandin(repo, standin, hash, executable):
355 def writestandin(repo, standin, hash, executable):
347 '''write hash to <repo.root>/<standin>'''
356 '''write hash to <repo.root>/<standin>'''
348 repo.wwrite(standin, hash + '\n', executable and 'x' or '')
357 repo.wwrite(standin, hash + '\n', executable and 'x' or '')
349
358
350 def copyandhash(instream, outfile):
359 def copyandhash(instream, outfile):
351 '''Read bytes from instream (iterable) and write them to outfile,
360 '''Read bytes from instream (iterable) and write them to outfile,
352 computing the SHA-1 hash of the data along the way. Return the hash.'''
361 computing the SHA-1 hash of the data along the way. Return the hash.'''
353 hasher = util.sha1('')
362 hasher = util.sha1('')
354 for data in instream:
363 for data in instream:
355 hasher.update(data)
364 hasher.update(data)
356 outfile.write(data)
365 outfile.write(data)
357 return hasher.hexdigest()
366 return hasher.hexdigest()
358
367
359 def hashrepofile(repo, file):
368 def hashrepofile(repo, file):
360 return hashfile(repo.wjoin(file))
369 return hashfile(repo.wjoin(file))
361
370
362 def hashfile(file):
371 def hashfile(file):
363 if not os.path.exists(file):
372 if not os.path.exists(file):
364 return ''
373 return ''
365 hasher = util.sha1('')
374 hasher = util.sha1('')
366 fd = open(file, 'rb')
375 fd = open(file, 'rb')
367 for data in util.filechunkiter(fd, 128 * 1024):
376 for data in util.filechunkiter(fd, 128 * 1024):
368 hasher.update(data)
377 hasher.update(data)
369 fd.close()
378 fd.close()
370 return hasher.hexdigest()
379 return hasher.hexdigest()
371
380
372 def getexecutable(filename):
381 def getexecutable(filename):
373 mode = os.stat(filename).st_mode
382 mode = os.stat(filename).st_mode
374 return ((mode & stat.S_IXUSR) and
383 return ((mode & stat.S_IXUSR) and
375 (mode & stat.S_IXGRP) and
384 (mode & stat.S_IXGRP) and
376 (mode & stat.S_IXOTH))
385 (mode & stat.S_IXOTH))
377
386
378 def urljoin(first, second, *arg):
387 def urljoin(first, second, *arg):
379 def join(left, right):
388 def join(left, right):
380 if not left.endswith('/'):
389 if not left.endswith('/'):
381 left += '/'
390 left += '/'
382 if right.startswith('/'):
391 if right.startswith('/'):
383 right = right[1:]
392 right = right[1:]
384 return left + right
393 return left + right
385
394
386 url = join(first, second)
395 url = join(first, second)
387 for a in arg:
396 for a in arg:
388 url = join(url, a)
397 url = join(url, a)
389 return url
398 return url
390
399
391 def hexsha1(data):
400 def hexsha1(data):
392 """hexsha1 returns the hex-encoded sha1 sum of the data in the file-like
401 """hexsha1 returns the hex-encoded sha1 sum of the data in the file-like
393 object data"""
402 object data"""
394 h = util.sha1()
403 h = util.sha1()
395 for chunk in util.filechunkiter(data):
404 for chunk in util.filechunkiter(data):
396 h.update(chunk)
405 h.update(chunk)
397 return h.hexdigest()
406 return h.hexdigest()
398
407
399 def httpsendfile(ui, filename):
408 def httpsendfile(ui, filename):
400 return httpconnection.httpsendfile(ui, filename, 'rb')
409 return httpconnection.httpsendfile(ui, filename, 'rb')
401
410
402 def unixpath(path):
411 def unixpath(path):
403 '''Return a version of path normalized for use with the lfdirstate.'''
412 '''Return a version of path normalized for use with the lfdirstate.'''
404 return util.pconvert(os.path.normpath(path))
413 return util.pconvert(os.path.normpath(path))
405
414
406 def islfilesrepo(repo):
415 def islfilesrepo(repo):
407 '''Return true if the repo is a largefile repo.'''
416 '''Return true if the repo is a largefile repo.'''
408 if ('largefiles' in repo.requirements and
417 if ('largefiles' in repo.requirements and
409 any(shortnameslash in f[0] for f in repo.store.datafiles())):
418 any(shortnameslash in f[0] for f in repo.store.datafiles())):
410 return True
419 return True
411
420
412 return any(openlfdirstate(repo.ui, repo, False))
421 return any(openlfdirstate(repo.ui, repo, False))
413
422
414 class storeprotonotcapable(Exception):
423 class storeprotonotcapable(Exception):
415 def __init__(self, storetypes):
424 def __init__(self, storetypes):
416 self.storetypes = storetypes
425 self.storetypes = storetypes
417
426
418 def getstandinsstate(repo):
427 def getstandinsstate(repo):
419 standins = []
428 standins = []
420 matcher = getstandinmatcher(repo)
429 matcher = getstandinmatcher(repo)
421 for standin in repo.dirstate.walk(matcher, [], False, False):
430 for standin in repo.dirstate.walk(matcher, [], False, False):
422 lfile = splitstandin(standin)
431 lfile = splitstandin(standin)
423 try:
432 try:
424 hash = readstandin(repo, lfile)
433 hash = readstandin(repo, lfile)
425 except IOError:
434 except IOError:
426 hash = None
435 hash = None
427 standins.append((lfile, hash))
436 standins.append((lfile, hash))
428 return standins
437 return standins
429
438
430 def synclfdirstate(repo, lfdirstate, lfile, normallookup):
439 def synclfdirstate(repo, lfdirstate, lfile, normallookup):
431 lfstandin = standin(lfile)
440 lfstandin = standin(lfile)
432 if lfstandin in repo.dirstate:
441 if lfstandin in repo.dirstate:
433 stat = repo.dirstate._map[lfstandin]
442 stat = repo.dirstate._map[lfstandin]
434 state, mtime = stat[0], stat[3]
443 state, mtime = stat[0], stat[3]
435 else:
444 else:
436 state, mtime = '?', -1
445 state, mtime = '?', -1
437 if state == 'n':
446 if state == 'n':
438 if (normallookup or mtime < 0 or
447 if (normallookup or mtime < 0 or
439 not repo.wvfs.exists(lfile)):
448 not repo.wvfs.exists(lfile)):
440 # state 'n' doesn't ensure 'clean' in this case
449 # state 'n' doesn't ensure 'clean' in this case
441 lfdirstate.normallookup(lfile)
450 lfdirstate.normallookup(lfile)
442 else:
451 else:
443 lfdirstate.normal(lfile)
452 lfdirstate.normal(lfile)
444 elif state == 'm':
453 elif state == 'm':
445 lfdirstate.normallookup(lfile)
454 lfdirstate.normallookup(lfile)
446 elif state == 'r':
455 elif state == 'r':
447 lfdirstate.remove(lfile)
456 lfdirstate.remove(lfile)
448 elif state == 'a':
457 elif state == 'a':
449 lfdirstate.add(lfile)
458 lfdirstate.add(lfile)
450 elif state == '?':
459 elif state == '?':
451 lfdirstate.drop(lfile)
460 lfdirstate.drop(lfile)
452
461
453 def markcommitted(orig, ctx, node):
462 def markcommitted(orig, ctx, node):
454 repo = ctx.repo()
463 repo = ctx.repo()
455
464
456 orig(node)
465 orig(node)
457
466
458 # ATTENTION: "ctx.files()" may differ from "repo[node].files()"
467 # ATTENTION: "ctx.files()" may differ from "repo[node].files()"
459 # because files coming from the 2nd parent are omitted in the latter.
468 # because files coming from the 2nd parent are omitted in the latter.
460 #
469 #
461 # The former should be used to get targets of "synclfdirstate",
470 # The former should be used to get targets of "synclfdirstate",
462 # because such files:
471 # because such files:
463 # - are marked as "a" by "patch.patch()" (e.g. via transplant), and
472 # - are marked as "a" by "patch.patch()" (e.g. via transplant), and
464 # - have to be marked as "n" after commit, but
473 # - have to be marked as "n" after commit, but
465 # - aren't listed in "repo[node].files()"
474 # - aren't listed in "repo[node].files()"
466
475
467 lfdirstate = openlfdirstate(repo.ui, repo)
476 lfdirstate = openlfdirstate(repo.ui, repo)
468 for f in ctx.files():
477 for f in ctx.files():
469 if isstandin(f):
478 if isstandin(f):
470 lfile = splitstandin(f)
479 lfile = splitstandin(f)
471 synclfdirstate(repo, lfdirstate, lfile, False)
480 synclfdirstate(repo, lfdirstate, lfile, False)
472 lfdirstate.write()
481 lfdirstate.write()
473
482
474 # As part of committing, copy all of the largefiles into the cache.
483 # As part of committing, copy all of the largefiles into the cache.
475 copyalltostore(repo, node)
484 copyalltostore(repo, node)
476
485
477 def getlfilestoupdate(oldstandins, newstandins):
486 def getlfilestoupdate(oldstandins, newstandins):
478 changedstandins = set(oldstandins).symmetric_difference(set(newstandins))
487 changedstandins = set(oldstandins).symmetric_difference(set(newstandins))
479 filelist = []
488 filelist = []
480 for f in changedstandins:
489 for f in changedstandins:
481 if f[0] not in filelist:
490 if f[0] not in filelist:
482 filelist.append(f[0])
491 filelist.append(f[0])
483 return filelist
492 return filelist
484
493
485 def getlfilestoupload(repo, missing, addfunc):
494 def getlfilestoupload(repo, missing, addfunc):
486 for i, n in enumerate(missing):
495 for i, n in enumerate(missing):
487 repo.ui.progress(_('finding outgoing largefiles'), i,
496 repo.ui.progress(_('finding outgoing largefiles'), i,
488 unit=_('revisions'), total=len(missing))
497 unit=_('revisions'), total=len(missing))
489 parents = [p for p in repo[n].parents() if p != node.nullid]
498 parents = [p for p in repo[n].parents() if p != node.nullid]
490
499
491 oldlfstatus = repo.lfstatus
500 oldlfstatus = repo.lfstatus
492 repo.lfstatus = False
501 repo.lfstatus = False
493 try:
502 try:
494 ctx = repo[n]
503 ctx = repo[n]
495 finally:
504 finally:
496 repo.lfstatus = oldlfstatus
505 repo.lfstatus = oldlfstatus
497
506
498 files = set(ctx.files())
507 files = set(ctx.files())
499 if len(parents) == 2:
508 if len(parents) == 2:
500 mc = ctx.manifest()
509 mc = ctx.manifest()
501 mp1 = ctx.parents()[0].manifest()
510 mp1 = ctx.parents()[0].manifest()
502 mp2 = ctx.parents()[1].manifest()
511 mp2 = ctx.parents()[1].manifest()
503 for f in mp1:
512 for f in mp1:
504 if f not in mc:
513 if f not in mc:
505 files.add(f)
514 files.add(f)
506 for f in mp2:
515 for f in mp2:
507 if f not in mc:
516 if f not in mc:
508 files.add(f)
517 files.add(f)
509 for f in mc:
518 for f in mc:
510 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
519 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
511 files.add(f)
520 files.add(f)
512 for fn in files:
521 for fn in files:
513 if isstandin(fn) and fn in ctx:
522 if isstandin(fn) and fn in ctx:
514 addfunc(fn, ctx[fn].data().strip())
523 addfunc(fn, ctx[fn].data().strip())
515 repo.ui.progress(_('finding outgoing largefiles'), None)
524 repo.ui.progress(_('finding outgoing largefiles'), None)
516
525
517 def updatestandinsbymatch(repo, match):
526 def updatestandinsbymatch(repo, match):
518 '''Update standins in the working directory according to specified match
527 '''Update standins in the working directory according to specified match
519
528
520 This returns (possibly modified) ``match`` object to be used for
529 This returns (possibly modified) ``match`` object to be used for
521 subsequent commit process.
530 subsequent commit process.
522 '''
531 '''
523
532
524 ui = repo.ui
533 ui = repo.ui
525
534
526 # Case 1: user calls commit with no specific files or
535 # Case 1: user calls commit with no specific files or
527 # include/exclude patterns: refresh and commit all files that
536 # include/exclude patterns: refresh and commit all files that
528 # are "dirty".
537 # are "dirty".
529 if match is None or match.always():
538 if match is None or match.always():
530 # Spend a bit of time here to get a list of files we know
539 # Spend a bit of time here to get a list of files we know
531 # are modified so we can compare only against those.
540 # are modified so we can compare only against those.
532 # It can cost a lot of time (several seconds)
541 # It can cost a lot of time (several seconds)
533 # otherwise to update all standins if the largefiles are
542 # otherwise to update all standins if the largefiles are
534 # large.
543 # large.
535 lfdirstate = openlfdirstate(ui, repo)
544 lfdirstate = openlfdirstate(ui, repo)
536 dirtymatch = match_.always(repo.root, repo.getcwd())
545 dirtymatch = match_.always(repo.root, repo.getcwd())
537 unsure, s = lfdirstate.status(dirtymatch, [], False, False,
546 unsure, s = lfdirstate.status(dirtymatch, [], False, False,
538 False)
547 False)
539 modifiedfiles = unsure + s.modified + s.added + s.removed
548 modifiedfiles = unsure + s.modified + s.added + s.removed
540 lfiles = listlfiles(repo)
549 lfiles = listlfiles(repo)
541 # this only loops through largefiles that exist (not
550 # this only loops through largefiles that exist (not
542 # removed/renamed)
551 # removed/renamed)
543 for lfile in lfiles:
552 for lfile in lfiles:
544 if lfile in modifiedfiles:
553 if lfile in modifiedfiles:
545 if repo.wvfs.exists(standin(lfile)):
554 if repo.wvfs.exists(standin(lfile)):
546 # this handles the case where a rebase is being
555 # this handles the case where a rebase is being
547 # performed and the working copy is not updated
556 # performed and the working copy is not updated
548 # yet.
557 # yet.
549 if repo.wvfs.exists(lfile):
558 if repo.wvfs.exists(lfile):
550 updatestandin(repo,
559 updatestandin(repo,
551 standin(lfile))
560 standin(lfile))
552
561
553 return match
562 return match
554
563
555 lfiles = listlfiles(repo)
564 lfiles = listlfiles(repo)
556 match._files = repo._subdirlfs(match.files(), lfiles)
565 match._files = repo._subdirlfs(match.files(), lfiles)
557
566
558 # Case 2: user calls commit with specified patterns: refresh
567 # Case 2: user calls commit with specified patterns: refresh
559 # any matching big files.
568 # any matching big files.
560 smatcher = composestandinmatcher(repo, match)
569 smatcher = composestandinmatcher(repo, match)
561 standins = repo.dirstate.walk(smatcher, [], False, False)
570 standins = repo.dirstate.walk(smatcher, [], False, False)
562
571
563 # No matching big files: get out of the way and pass control to
572 # No matching big files: get out of the way and pass control to
564 # the usual commit() method.
573 # the usual commit() method.
565 if not standins:
574 if not standins:
566 return match
575 return match
567
576
568 # Refresh all matching big files. It's possible that the
577 # Refresh all matching big files. It's possible that the
569 # commit will end up failing, in which case the big files will
578 # commit will end up failing, in which case the big files will
570 # stay refreshed. No harm done: the user modified them and
579 # stay refreshed. No harm done: the user modified them and
571 # asked to commit them, so sooner or later we're going to
580 # asked to commit them, so sooner or later we're going to
572 # refresh the standins. Might as well leave them refreshed.
581 # refresh the standins. Might as well leave them refreshed.
573 lfdirstate = openlfdirstate(ui, repo)
582 lfdirstate = openlfdirstate(ui, repo)
574 for fstandin in standins:
583 for fstandin in standins:
575 lfile = splitstandin(fstandin)
584 lfile = splitstandin(fstandin)
576 if lfdirstate[lfile] != 'r':
585 if lfdirstate[lfile] != 'r':
577 updatestandin(repo, fstandin)
586 updatestandin(repo, fstandin)
578
587
579 # Cook up a new matcher that only matches regular files or
588 # Cook up a new matcher that only matches regular files or
580 # standins corresponding to the big files requested by the
589 # standins corresponding to the big files requested by the
581 # user. Have to modify _files to prevent commit() from
590 # user. Have to modify _files to prevent commit() from
582 # complaining "not tracked" for big files.
591 # complaining "not tracked" for big files.
583 match = copy.copy(match)
592 match = copy.copy(match)
584 origmatchfn = match.matchfn
593 origmatchfn = match.matchfn
585
594
586 # Check both the list of largefiles and the list of
595 # Check both the list of largefiles and the list of
587 # standins because if a largefile was removed, it
596 # standins because if a largefile was removed, it
588 # won't be in the list of largefiles at this point
597 # won't be in the list of largefiles at this point
589 match._files += sorted(standins)
598 match._files += sorted(standins)
590
599
591 actualfiles = []
600 actualfiles = []
592 for f in match._files:
601 for f in match._files:
593 fstandin = standin(f)
602 fstandin = standin(f)
594
603
595 # For largefiles, only one of the normal and standin should be
604 # For largefiles, only one of the normal and standin should be
596 # committed (except if one of them is a remove). In the case of a
605 # committed (except if one of them is a remove). In the case of a
597 # standin removal, drop the normal file if it is unknown to dirstate.
606 # standin removal, drop the normal file if it is unknown to dirstate.
598 # Thus, skip plain largefile names but keep the standin.
607 # Thus, skip plain largefile names but keep the standin.
599 if f in lfiles or fstandin in standins:
608 if f in lfiles or fstandin in standins:
600 if repo.dirstate[fstandin] != 'r':
609 if repo.dirstate[fstandin] != 'r':
601 if repo.dirstate[f] != 'r':
610 if repo.dirstate[f] != 'r':
602 continue
611 continue
603 elif repo.dirstate[f] == '?':
612 elif repo.dirstate[f] == '?':
604 continue
613 continue
605
614
606 actualfiles.append(f)
615 actualfiles.append(f)
607 match._files = actualfiles
616 match._files = actualfiles
608
617
609 def matchfn(f):
618 def matchfn(f):
610 if origmatchfn(f):
619 if origmatchfn(f):
611 return f not in lfiles
620 return f not in lfiles
612 else:
621 else:
613 return f in standins
622 return f in standins
614
623
615 match.matchfn = matchfn
624 match.matchfn = matchfn
616
625
617 return match
626 return match
618
627
619 class automatedcommithook(object):
628 class automatedcommithook(object):
620 '''Stateful hook to update standins at the 1st commit of resuming
629 '''Stateful hook to update standins at the 1st commit of resuming
621
630
622 For efficiency, updating standins in the working directory should
631 For efficiency, updating standins in the working directory should
623 be avoided while automated committing (like rebase, transplant and
632 be avoided while automated committing (like rebase, transplant and
624 so on), because they should be updated before committing.
633 so on), because they should be updated before committing.
625
634
626 But the 1st commit of resuming automated committing (e.g. ``rebase
635 But the 1st commit of resuming automated committing (e.g. ``rebase
627 --continue``) should update them, because largefiles may be
636 --continue``) should update them, because largefiles may be
628 modified manually.
637 modified manually.
629 '''
638 '''
630 def __init__(self, resuming):
639 def __init__(self, resuming):
631 self.resuming = resuming
640 self.resuming = resuming
632
641
633 def __call__(self, repo, match):
642 def __call__(self, repo, match):
634 if self.resuming:
643 if self.resuming:
635 self.resuming = False # avoids updating at subsequent commits
644 self.resuming = False # avoids updating at subsequent commits
636 return updatestandinsbymatch(repo, match)
645 return updatestandinsbymatch(repo, match)
637 else:
646 else:
638 return match
647 return match
639
648
640 def getstatuswriter(ui, repo, forcibly=None):
649 def getstatuswriter(ui, repo, forcibly=None):
641 '''Return the function to write largefiles specific status out
650 '''Return the function to write largefiles specific status out
642
651
643 If ``forcibly`` is ``None``, this returns the last element of
652 If ``forcibly`` is ``None``, this returns the last element of
644 ``repo._lfstatuswriters`` as "default" writer function.
653 ``repo._lfstatuswriters`` as "default" writer function.
645
654
646 Otherwise, this returns the function to always write out (or
655 Otherwise, this returns the function to always write out (or
647 ignore if ``not forcibly``) status.
656 ignore if ``not forcibly``) status.
648 '''
657 '''
649 if forcibly is None and util.safehasattr(repo, '_largefilesenabled'):
658 if forcibly is None and util.safehasattr(repo, '_largefilesenabled'):
650 return repo._lfstatuswriters[-1]
659 return repo._lfstatuswriters[-1]
651 else:
660 else:
652 if forcibly:
661 if forcibly:
653 return ui.status # forcibly WRITE OUT
662 return ui.status # forcibly WRITE OUT
654 else:
663 else:
655 return lambda *msg, **opts: None # forcibly IGNORE
664 return lambda *msg, **opts: None # forcibly IGNORE
@@ -1,159 +1,158 b''
1 #require test-repo
1 #require test-repo
2
2
3 $ . "$TESTDIR/helpers-testrepo.sh"
3 $ . "$TESTDIR/helpers-testrepo.sh"
4 $ cd "$TESTDIR"/..
4 $ cd "$TESTDIR"/..
5
5
6 $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs python contrib/check-py3-compat.py
6 $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs python contrib/check-py3-compat.py
7 hgext/fsmonitor/pywatchman/__init__.py not using absolute_import
7 hgext/fsmonitor/pywatchman/__init__.py not using absolute_import
8 hgext/fsmonitor/pywatchman/__init__.py requires print_function
8 hgext/fsmonitor/pywatchman/__init__.py requires print_function
9 hgext/fsmonitor/pywatchman/capabilities.py not using absolute_import
9 hgext/fsmonitor/pywatchman/capabilities.py not using absolute_import
10 hgext/fsmonitor/pywatchman/pybser.py not using absolute_import
10 hgext/fsmonitor/pywatchman/pybser.py not using absolute_import
11 hgext/highlight/__init__.py not using absolute_import
11 hgext/highlight/__init__.py not using absolute_import
12 hgext/highlight/highlight.py not using absolute_import
12 hgext/highlight/highlight.py not using absolute_import
13 hgext/largefiles/lfutil.py not using absolute_import
14 hgext/largefiles/localstore.py not using absolute_import
13 hgext/largefiles/localstore.py not using absolute_import
15 hgext/largefiles/overrides.py not using absolute_import
14 hgext/largefiles/overrides.py not using absolute_import
16 hgext/largefiles/proto.py not using absolute_import
15 hgext/largefiles/proto.py not using absolute_import
17 hgext/largefiles/remotestore.py not using absolute_import
16 hgext/largefiles/remotestore.py not using absolute_import
18 hgext/largefiles/reposetup.py not using absolute_import
17 hgext/largefiles/reposetup.py not using absolute_import
19 hgext/largefiles/uisetup.py not using absolute_import
18 hgext/largefiles/uisetup.py not using absolute_import
20 hgext/largefiles/wirestore.py not using absolute_import
19 hgext/largefiles/wirestore.py not using absolute_import
21 hgext/share.py not using absolute_import
20 hgext/share.py not using absolute_import
22 hgext/win32text.py not using absolute_import
21 hgext/win32text.py not using absolute_import
23 i18n/check-translation.py not using absolute_import
22 i18n/check-translation.py not using absolute_import
24 i18n/polib.py not using absolute_import
23 i18n/polib.py not using absolute_import
25 setup.py not using absolute_import
24 setup.py not using absolute_import
26 tests/heredoctest.py requires print_function
25 tests/heredoctest.py requires print_function
27 tests/md5sum.py not using absolute_import
26 tests/md5sum.py not using absolute_import
28 tests/readlink.py not using absolute_import
27 tests/readlink.py not using absolute_import
29 tests/run-tests.py not using absolute_import
28 tests/run-tests.py not using absolute_import
30 tests/test-demandimport.py not using absolute_import
29 tests/test-demandimport.py not using absolute_import
31
30
32 #if py3exe
31 #if py3exe
33 $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs $PYTHON3 contrib/check-py3-compat.py
32 $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs $PYTHON3 contrib/check-py3-compat.py
34 doc/hgmanpage.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
33 doc/hgmanpage.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
35 hgext/automv.py: error importing module: <SyntaxError> invalid syntax (commands.py, line *) (line *) (glob)
34 hgext/automv.py: error importing module: <SyntaxError> invalid syntax (commands.py, line *) (line *) (glob)
36 hgext/blackbox.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
35 hgext/blackbox.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
37 hgext/bugzilla.py: error importing module: <ImportError> No module named 'urlparse' (line *) (glob)
36 hgext/bugzilla.py: error importing module: <ImportError> No module named 'urlparse' (line *) (glob)
38 hgext/censor.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
37 hgext/censor.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
39 hgext/chgserver.py: error importing module: <ImportError> No module named 'SocketServer' (line *) (glob)
38 hgext/chgserver.py: error importing module: <ImportError> No module named 'SocketServer' (line *) (glob)
40 hgext/children.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
39 hgext/children.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
41 hgext/churn.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
40 hgext/churn.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
42 hgext/clonebundles.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
41 hgext/clonebundles.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
43 hgext/color.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
42 hgext/color.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
44 hgext/convert/bzr.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
43 hgext/convert/bzr.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
45 hgext/convert/common.py: error importing module: <ImportError> No module named 'cPickle' (line *) (glob)
44 hgext/convert/common.py: error importing module: <ImportError> No module named 'cPickle' (line *) (glob)
46 hgext/convert/convcmd.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
45 hgext/convert/convcmd.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
47 hgext/convert/cvs.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
46 hgext/convert/cvs.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
48 hgext/convert/cvsps.py: error importing module: <ImportError> No module named 'cPickle' (line *) (glob)
47 hgext/convert/cvsps.py: error importing module: <ImportError> No module named 'cPickle' (line *) (glob)
49 hgext/convert/darcs.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
48 hgext/convert/darcs.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
50 hgext/convert/filemap.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
49 hgext/convert/filemap.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
51 hgext/convert/git.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
50 hgext/convert/git.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
52 hgext/convert/gnuarch.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
51 hgext/convert/gnuarch.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
53 hgext/convert/hg.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
52 hgext/convert/hg.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
54 hgext/convert/monotone.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
53 hgext/convert/monotone.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
55 hgext/convert/p*.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
54 hgext/convert/p*.py: error importing module: <SystemError> Parent module 'hgext.convert' not loaded, cannot perform relative import (line *) (glob)
56 hgext/convert/subversion.py: error importing module: <ImportError> No module named 'cPickle' (line *) (glob)
55 hgext/convert/subversion.py: error importing module: <ImportError> No module named 'cPickle' (line *) (glob)
57 hgext/convert/transport.py: error importing module: <ImportError> No module named 'svn.client' (line *) (glob)
56 hgext/convert/transport.py: error importing module: <ImportError> No module named 'svn.client' (line *) (glob)
58 hgext/eol.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
57 hgext/eol.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
59 hgext/extdiff.py: error importing module: <SyntaxError> invalid syntax (archival.py, line *) (line *) (glob)
58 hgext/extdiff.py: error importing module: <SyntaxError> invalid syntax (archival.py, line *) (line *) (glob)
60 hgext/factotum.py: error importing: <ImportError> No module named 'rfc822' (error at __init__.py:*) (glob)
59 hgext/factotum.py: error importing: <ImportError> No module named 'rfc822' (error at __init__.py:*) (glob)
61 hgext/fetch.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
60 hgext/fetch.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
62 hgext/fsmonitor/watchmanclient.py: error importing module: <SystemError> Parent module 'hgext.fsmonitor' not loaded, cannot perform relative import (line *) (glob)
61 hgext/fsmonitor/watchmanclient.py: error importing module: <SystemError> Parent module 'hgext.fsmonitor' not loaded, cannot perform relative import (line *) (glob)
63 hgext/gpg.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
62 hgext/gpg.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
64 hgext/graphlog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
63 hgext/graphlog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
65 hgext/hgk.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
64 hgext/hgk.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
66 hgext/histedit.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
65 hgext/histedit.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
67 hgext/keyword.py: error importing: <ImportError> No module named 'BaseHTTPServer' (error at common.py:*) (glob)
66 hgext/keyword.py: error importing: <ImportError> No module named 'BaseHTTPServer' (error at common.py:*) (glob)
68 hgext/largefiles/basestore.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
67 hgext/largefiles/basestore.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
69 hgext/largefiles/lfcommands.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
68 hgext/largefiles/lfcommands.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
70 hgext/largefiles/lfutil.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
69 hgext/largefiles/lfutil.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
71 hgext/largefiles/localstore.py: error importing module: <ImportError> No module named 'lfutil' (line *) (glob)
70 hgext/largefiles/localstore.py: error importing module: <ImportError> No module named 'lfutil' (line *) (glob)
72 hgext/largefiles/overrides.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
71 hgext/largefiles/overrides.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
73 hgext/largefiles/proto.py: error importing: <ImportError> No module named 'httplib' (error at httppeer.py:*) (glob)
72 hgext/largefiles/proto.py: error importing: <ImportError> No module named 'httplib' (error at httppeer.py:*) (glob)
74 hgext/largefiles/remotestore.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at wireproto.py:*) (glob)
73 hgext/largefiles/remotestore.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at wireproto.py:*) (glob)
75 hgext/largefiles/reposetup.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
74 hgext/largefiles/reposetup.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
76 hgext/largefiles/uisetup.py: error importing module: <SyntaxError> invalid syntax (archival.py, line *) (line *) (glob)
75 hgext/largefiles/uisetup.py: error importing module: <SyntaxError> invalid syntax (archival.py, line *) (line *) (glob)
77 hgext/largefiles/wirestore.py: error importing module: <ImportError> No module named 'lfutil' (line *) (glob)
76 hgext/largefiles/wirestore.py: error importing module: <ImportError> No module named 'lfutil' (line *) (glob)
78 hgext/mq.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
77 hgext/mq.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
79 hgext/notify.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
78 hgext/notify.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
80 hgext/pager.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
79 hgext/pager.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
81 hgext/patchbomb.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
80 hgext/patchbomb.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
82 hgext/purge.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
81 hgext/purge.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
83 hgext/rebase.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
82 hgext/rebase.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
84 hgext/record.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
83 hgext/record.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
85 hgext/relink.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
84 hgext/relink.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
86 hgext/schemes.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
85 hgext/schemes.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
87 hgext/share.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
86 hgext/share.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
88 hgext/shelve.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
87 hgext/shelve.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
89 hgext/strip.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
88 hgext/strip.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
90 hgext/transplant.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
89 hgext/transplant.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
91 mercurial/archival.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
90 mercurial/archival.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
92 mercurial/branchmap.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
91 mercurial/branchmap.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
93 mercurial/bundle*.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
92 mercurial/bundle*.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
94 mercurial/bundlerepo.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
93 mercurial/bundlerepo.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
95 mercurial/changegroup.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
94 mercurial/changegroup.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
96 mercurial/changelog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
95 mercurial/changelog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
97 mercurial/cmdutil.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
96 mercurial/cmdutil.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
98 mercurial/commands.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
97 mercurial/commands.py: invalid syntax: invalid syntax (<unknown>, line *) (glob)
99 mercurial/commandserver.py: error importing module: <ImportError> No module named 'SocketServer' (line *) (glob)
98 mercurial/commandserver.py: error importing module: <ImportError> No module named 'SocketServer' (line *) (glob)
100 mercurial/context.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
99 mercurial/context.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
101 mercurial/copies.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
100 mercurial/copies.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
102 mercurial/crecord.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
101 mercurial/crecord.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
103 mercurial/dirstate.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
102 mercurial/dirstate.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
104 mercurial/discovery.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
103 mercurial/discovery.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
105 mercurial/dispatch.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
104 mercurial/dispatch.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
106 mercurial/exchange.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
105 mercurial/exchange.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
107 mercurial/extensions.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
106 mercurial/extensions.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
108 mercurial/filelog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
107 mercurial/filelog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
109 mercurial/filemerge.py: error importing: <ImportError> No module named 'cPickle' (error at formatter.py:*) (glob)
108 mercurial/filemerge.py: error importing: <ImportError> No module named 'cPickle' (error at formatter.py:*) (glob)
110 mercurial/fileset.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
109 mercurial/fileset.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
111 mercurial/formatter.py: error importing module: <ImportError> No module named 'cPickle' (line *) (glob)
110 mercurial/formatter.py: error importing module: <ImportError> No module named 'cPickle' (line *) (glob)
112 mercurial/graphmod.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
111 mercurial/graphmod.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
113 mercurial/help.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
112 mercurial/help.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
114 mercurial/hg.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
113 mercurial/hg.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at bundlerepo.py:*) (glob)
115 mercurial/hgweb/common.py: error importing module: <ImportError> No module named 'BaseHTTPServer' (line *) (glob)
114 mercurial/hgweb/common.py: error importing module: <ImportError> No module named 'BaseHTTPServer' (line *) (glob)
116 mercurial/hgweb/hgweb_mod.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
115 mercurial/hgweb/hgweb_mod.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
117 mercurial/hgweb/hgwebdir_mod.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
116 mercurial/hgweb/hgwebdir_mod.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
118 mercurial/hgweb/protocol.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
117 mercurial/hgweb/protocol.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
119 mercurial/hgweb/request.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
118 mercurial/hgweb/request.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
120 mercurial/hgweb/server.py: error importing module: <ImportError> No module named 'BaseHTTPServer' (line *) (glob)
119 mercurial/hgweb/server.py: error importing module: <ImportError> No module named 'BaseHTTPServer' (line *) (glob)
121 mercurial/hgweb/webcommands.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
120 mercurial/hgweb/webcommands.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
122 mercurial/hgweb/webutil.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
121 mercurial/hgweb/webutil.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
123 mercurial/hgweb/wsgicgi.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
122 mercurial/hgweb/wsgicgi.py: error importing module: <SystemError> Parent module 'mercurial.hgweb' not loaded, cannot perform relative import (line *) (glob)
124 mercurial/hook.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
123 mercurial/hook.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
125 mercurial/httpconnection.py: error importing: <ImportError> No module named 'rfc822' (error at __init__.py:*) (glob)
124 mercurial/httpconnection.py: error importing: <ImportError> No module named 'rfc822' (error at __init__.py:*) (glob)
126 mercurial/httppeer.py: error importing module: <ImportError> No module named 'httplib' (line *) (glob)
125 mercurial/httppeer.py: error importing module: <ImportError> No module named 'httplib' (line *) (glob)
127 mercurial/keepalive.py: error importing module: <ImportError> No module named 'httplib' (line *) (glob)
126 mercurial/keepalive.py: error importing module: <ImportError> No module named 'httplib' (line *) (glob)
128 mercurial/localrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
127 mercurial/localrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
129 mercurial/mail.py: error importing module: <AttributeError> module 'email' has no attribute 'Header' (line *) (glob)
128 mercurial/mail.py: error importing module: <AttributeError> module 'email' has no attribute 'Header' (line *) (glob)
130 mercurial/manifest.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
129 mercurial/manifest.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
131 mercurial/merge.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
130 mercurial/merge.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
132 mercurial/namespaces.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
131 mercurial/namespaces.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
133 mercurial/patch.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
132 mercurial/patch.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
134 mercurial/pure/mpatch.py: error importing module: <ImportError> cannot import name 'pycompat' (line *) (glob)
133 mercurial/pure/mpatch.py: error importing module: <ImportError> cannot import name 'pycompat' (line *) (glob)
135 mercurial/pure/parsers.py: error importing module: <ImportError> No module named 'mercurial.pure.node' (line *) (glob)
134 mercurial/pure/parsers.py: error importing module: <ImportError> No module named 'mercurial.pure.node' (line *) (glob)
136 mercurial/repair.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
135 mercurial/repair.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
137 mercurial/revlog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
136 mercurial/revlog.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
138 mercurial/revset.py: error importing module: <AttributeError> 'dict' object has no attribute 'iteritems' (line *) (glob)
137 mercurial/revset.py: error importing module: <AttributeError> 'dict' object has no attribute 'iteritems' (line *) (glob)
139 mercurial/scmutil.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
138 mercurial/scmutil.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
140 mercurial/scmwindows.py: error importing module: <ImportError> No module named '_winreg' (line *) (glob)
139 mercurial/scmwindows.py: error importing module: <ImportError> No module named '_winreg' (line *) (glob)
141 mercurial/simplemerge.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
140 mercurial/simplemerge.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
142 mercurial/sshpeer.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at wireproto.py:*) (glob)
141 mercurial/sshpeer.py: error importing: <SyntaxError> invalid syntax (bundle*.py, line *) (error at wireproto.py:*) (glob)
143 mercurial/sshserver.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
142 mercurial/sshserver.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
144 mercurial/statichttprepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
143 mercurial/statichttprepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
145 mercurial/store.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
144 mercurial/store.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
146 mercurial/streamclone.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
145 mercurial/streamclone.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
147 mercurial/subrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
146 mercurial/subrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
148 mercurial/templatefilters.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
147 mercurial/templatefilters.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
149 mercurial/templatekw.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
148 mercurial/templatekw.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
150 mercurial/templater.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
149 mercurial/templater.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
151 mercurial/ui.py: error importing: <ImportError> No module named 'cPickle' (error at formatter.py:*) (glob)
150 mercurial/ui.py: error importing: <ImportError> No module named 'cPickle' (error at formatter.py:*) (glob)
152 mercurial/unionrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
151 mercurial/unionrepo.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
153 mercurial/url.py: error importing module: <ImportError> No module named 'httplib' (line *) (glob)
152 mercurial/url.py: error importing module: <ImportError> No module named 'httplib' (line *) (glob)
154 mercurial/verify.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
153 mercurial/verify.py: error importing: <AttributeError> 'dict' object has no attribute 'iteritems' (error at revset.py:*) (glob)
155 mercurial/win*.py: error importing module: <ImportError> No module named 'msvcrt' (line *) (glob)
154 mercurial/win*.py: error importing module: <ImportError> No module named 'msvcrt' (line *) (glob)
156 mercurial/windows.py: error importing module: <ImportError> No module named '_winreg' (line *) (glob)
155 mercurial/windows.py: error importing module: <ImportError> No module named '_winreg' (line *) (glob)
157 mercurial/wireproto.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
156 mercurial/wireproto.py: error importing module: <SyntaxError> invalid syntax (bundle*.py, line *) (line *) (glob)
158
157
159 #endif
158 #endif
General Comments 0
You need to be logged in to leave comments. Login now