##// END OF EJS Templates
fix backtrace printed when cannot get lock....
Vadim Gelfer -
r2016:ff5c9a92 default
parent child Browse files
Show More
@@ -0,0 +1,11 b''
1 #!/bin/sh
2
3 hg init a
4 echo a > a/a
5 hg --cwd a ci -A -m a
6 hg clone a b
7 echo b > b/b
8 hg --cwd b ci -A -m b
9 chmod 100 a/.hg
10 hg --cwd b push ../a
11 chmod 700 a/.hg
@@ -0,0 +1,4 b''
1 adding a
2 adding b
3 pushing to ../a
4 abort: could not lock repository ../a: Permission denied
@@ -1244,12 +1244,8 b' def copy(ui, repo, *pats, **opts):'
1244 should properly record copied files, this information is not yet
1244 should properly record copied files, this information is not yet
1245 fully used by merge, nor fully reported by log.
1245 fully used by merge, nor fully reported by log.
1246 """
1246 """
1247 try:
1247 wlock = repo.wlock(0)
1248 wlock = repo.wlock(0)
1248 errs, copied = docopy(ui, repo, pats, opts, wlock)
1249 errs, copied = docopy(ui, repo, pats, opts, wlock)
1250 except lock.LockHeld, inst:
1251 ui.warn(_("repository lock held by %s\n") % inst.args[0])
1252 errs = 1
1253 return errs
1249 return errs
1254
1250
1255 def debugancestor(ui, index, rev1, rev2):
1251 def debugancestor(ui, index, rev1, rev2):
@@ -2256,18 +2252,14 b' def rename(ui, repo, *pats, **opts):'
2256 should properly record rename files, this information is not yet
2252 should properly record rename files, this information is not yet
2257 fully used by merge, nor fully reported by log.
2253 fully used by merge, nor fully reported by log.
2258 """
2254 """
2259 try:
2255 wlock = repo.wlock(0)
2260 wlock = repo.wlock(0)
2256 errs, copied = docopy(ui, repo, pats, opts, wlock)
2261 errs, copied = docopy(ui, repo, pats, opts, wlock)
2257 names = []
2262 names = []
2258 for abs, rel, exact in copied:
2263 for abs, rel, exact in copied:
2259 if ui.verbose or not exact:
2264 if ui.verbose or not exact:
2260 ui.status(_('removing %s\n') % rel)
2265 ui.status(_('removing %s\n') % rel)
2261 names.append(abs)
2266 names.append(abs)
2262 repo.remove(names, True, wlock)
2267 repo.remove(names, True, wlock)
2268 except lock.LockHeld, inst:
2269 ui.warn(_("repository lock held by %s\n") % inst.args[0])
2270 errs = 1
2271 return errs
2263 return errs
2272
2264
2273 def revert(ui, repo, *pats, **opts):
2265 def revert(ui, repo, *pats, **opts):
@@ -3252,6 +3244,15 b' def dispatch(args):'
3252 sys.exit(1)
3244 sys.exit(1)
3253 except hg.RepoError, inst:
3245 except hg.RepoError, inst:
3254 u.warn(_("abort: "), inst, "!\n")
3246 u.warn(_("abort: "), inst, "!\n")
3247 except lock.LockHeld, inst:
3248 if inst.errno == errno.ETIMEDOUT:
3249 reason = _('timed out waiting for lock held by %s') % inst.locker
3250 else:
3251 reason = _('lock held by %s') % inst.locker
3252 u.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
3253 except lock.LockUnavailable, inst:
3254 u.warn(_("abort: could not lock %s: %s\n") %
3255 (inst.desc or inst.filename, inst.strerror))
3255 except revlog.RevlogError, inst:
3256 except revlog.RevlogError, inst:
3256 u.warn(_("abort: "), inst, "!\n")
3257 u.warn(_("abort: "), inst, "!\n")
3257 except SignalInterrupt:
3258 except SignalInterrupt:
@@ -31,6 +31,7 b' class localrepository(object):'
31 raise repo.RepoError(_("repository %s not found") % path)
31 raise repo.RepoError(_("repository %s not found") % path)
32
32
33 self.root = os.path.abspath(path)
33 self.root = os.path.abspath(path)
34 self.origroot = path
34 self.ui = ui.ui(parentui=parentui)
35 self.ui = ui.ui(parentui=parentui)
35 self.opener = util.opener(self.path)
36 self.opener = util.opener(self.path)
36 self.wopener = util.opener(self.root)
37 self.wopener = util.opener(self.root)
@@ -261,32 +262,31 b' class localrepository(object):'
261 self.tagscache = None
262 self.tagscache = None
262 self.nodetagscache = None
263 self.nodetagscache = None
263
264
264 def do_lock(self, lockname, wait, releasefn=None, acquirefn=None):
265 def do_lock(self, lockname, wait, releasefn=None, acquirefn=None,
266 desc=None):
265 try:
267 try:
266 l = lock.lock(self.join(lockname), 0, releasefn)
268 l = lock.lock(self.join(lockname), 0, releasefn, desc=desc)
267 except lock.LockHeld, inst:
269 except lock.LockHeld, inst:
268 if not wait:
270 if not wait:
269 raise inst
271 raise
270 self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0])
272 self.ui.warn(_("waiting for lock on %s held by %s\n") %
271 try:
273 (desc, inst.args[0]))
272 # default to 600 seconds timeout
274 # default to 600 seconds timeout
273 l = lock.lock(self.join(lockname),
275 l = lock.lock(self.join(lockname),
274 int(self.ui.config("ui", "timeout") or 600),
276 int(self.ui.config("ui", "timeout") or 600),
275 releasefn)
277 releasefn, desc=desc)
276 except lock.LockHeld, inst:
277 raise util.Abort(_("timeout while waiting for "
278 "lock held by %s") % inst.args[0])
279 if acquirefn:
278 if acquirefn:
280 acquirefn()
279 acquirefn()
281 return l
280 return l
282
281
283 def lock(self, wait=1):
282 def lock(self, wait=1):
284 return self.do_lock("lock", wait, acquirefn=self.reload)
283 return self.do_lock("lock", wait, acquirefn=self.reload,
284 desc=_('repository %s') % self.origroot)
285
285
286 def wlock(self, wait=1):
286 def wlock(self, wait=1):
287 return self.do_lock("wlock", wait,
287 return self.do_lock("wlock", wait, self.dirstate.write,
288 self.dirstate.write,
288 self.wreload,
289 self.wreload)
289 desc=_('working directory of %s') % self.origroot)
290
290
291 def checkfilemerge(self, filename, text, filelog, manifest1, manifest2):
291 def checkfilemerge(self, filename, text, filelog, manifest1, manifest2):
292 "determine whether a new filenode is needed"
292 "determine whether a new filenode is needed"
@@ -8,10 +8,16 b''
8 from demandload import *
8 from demandload import *
9 demandload(globals(), 'errno os socket time util')
9 demandload(globals(), 'errno os socket time util')
10
10
11 class LockException(Exception):
11 class LockException(IOError):
12 pass
12 def __init__(self, errno, strerror, filename, desc):
13 IOError.__init__(self, errno, strerror, filename)
14 self.desc = desc
15
13 class LockHeld(LockException):
16 class LockHeld(LockException):
14 pass
17 def __init__(self, errno, filename, desc, locker):
18 LockException.__init__(self, errno, 'Lock held', filename, desc)
19 self.locker = locker
20
15 class LockUnavailable(LockException):
21 class LockUnavailable(LockException):
16 pass
22 pass
17
23
@@ -24,7 +30,7 b' class lock(object):'
24 # old-style lock: symlink to pid
30 # old-style lock: symlink to pid
25 # new-style lock: symlink to hostname:pid
31 # new-style lock: symlink to hostname:pid
26
32
27 def __init__(self, file, timeout=-1, releasefn=None):
33 def __init__(self, file, timeout=-1, releasefn=None, desc=None):
28 self.f = file
34 self.f = file
29 self.held = 0
35 self.held = 0
30 self.timeout = timeout
36 self.timeout = timeout
@@ -32,6 +38,7 b' class lock(object):'
32 self.id = None
38 self.id = None
33 self.host = None
39 self.host = None
34 self.pid = None
40 self.pid = None
41 self.desc = desc
35 self.lock()
42 self.lock()
36
43
37 def __del__(self):
44 def __del__(self):
@@ -49,7 +56,8 b' class lock(object):'
49 if timeout > 0:
56 if timeout > 0:
50 timeout -= 1
57 timeout -= 1
51 continue
58 continue
52 raise inst
59 raise LockHeld(errno.ETIMEDOUT, inst.filename, self.desc,
60 inst.locker)
53
61
54 def trylock(self):
62 def trylock(self):
55 if self.id is None:
63 if self.id is None:
@@ -64,9 +72,11 b' class lock(object):'
64 if why.errno == errno.EEXIST:
72 if why.errno == errno.EEXIST:
65 locker = self.testlock()
73 locker = self.testlock()
66 if locker:
74 if locker:
67 raise LockHeld(locker)
75 raise LockHeld(errno.EAGAIN, self.f, self.desc,
76 locker)
68 else:
77 else:
69 raise LockUnavailable(why)
78 raise LockUnavailable(why.errno, why.strerror,
79 why.filename, self.desc)
70
80
71 def testlock(self):
81 def testlock(self):
72 '''return id of locker if lock is valid, else None.'''
82 '''return id of locker if lock is valid, else None.'''
General Comments 0
You need to be logged in to leave comments. Login now