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 | 1244 | should properly record copied files, this information is not yet |
|
1245 | 1245 | fully used by merge, nor fully reported by log. |
|
1246 | 1246 | """ |
|
1247 | try: | |
|
1248 | wlock = repo.wlock(0) | |
|
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 | |
|
1247 | wlock = repo.wlock(0) | |
|
1248 | errs, copied = docopy(ui, repo, pats, opts, wlock) | |
|
1253 | 1249 | return errs |
|
1254 | 1250 | |
|
1255 | 1251 | def debugancestor(ui, index, rev1, rev2): |
@@ -2256,18 +2252,14 b' def rename(ui, repo, *pats, **opts):' | |||
|
2256 | 2252 | should properly record rename files, this information is not yet |
|
2257 | 2253 | fully used by merge, nor fully reported by log. |
|
2258 | 2254 | """ |
|
2259 | try: | |
|
2260 | wlock = repo.wlock(0) | |
|
2261 | errs, copied = docopy(ui, repo, pats, opts, wlock) | |
|
2262 | names = [] | |
|
2263 | for abs, rel, exact in copied: | |
|
2264 | if ui.verbose or not exact: | |
|
2265 | ui.status(_('removing %s\n') % rel) | |
|
2266 | names.append(abs) | |
|
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 | |
|
2255 | wlock = repo.wlock(0) | |
|
2256 | errs, copied = docopy(ui, repo, pats, opts, wlock) | |
|
2257 | names = [] | |
|
2258 | for abs, rel, exact in copied: | |
|
2259 | if ui.verbose or not exact: | |
|
2260 | ui.status(_('removing %s\n') % rel) | |
|
2261 | names.append(abs) | |
|
2262 | repo.remove(names, True, wlock) | |
|
2271 | 2263 | return errs |
|
2272 | 2264 | |
|
2273 | 2265 | def revert(ui, repo, *pats, **opts): |
@@ -3252,6 +3244,15 b' def dispatch(args):' | |||
|
3252 | 3244 | sys.exit(1) |
|
3253 | 3245 | except hg.RepoError, inst: |
|
3254 | 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 | 3256 | except revlog.RevlogError, inst: |
|
3256 | 3257 | u.warn(_("abort: "), inst, "!\n") |
|
3257 | 3258 | except SignalInterrupt: |
@@ -31,6 +31,7 b' class localrepository(object):' | |||
|
31 | 31 | raise repo.RepoError(_("repository %s not found") % path) |
|
32 | 32 | |
|
33 | 33 | self.root = os.path.abspath(path) |
|
34 | self.origroot = path | |
|
34 | 35 | self.ui = ui.ui(parentui=parentui) |
|
35 | 36 | self.opener = util.opener(self.path) |
|
36 | 37 | self.wopener = util.opener(self.root) |
@@ -261,32 +262,31 b' class localrepository(object):' | |||
|
261 | 262 | self.tagscache = None |
|
262 | 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 | 267 | try: |
|
266 | l = lock.lock(self.join(lockname), 0, releasefn) | |
|
268 | l = lock.lock(self.join(lockname), 0, releasefn, desc=desc) | |
|
267 | 269 | except lock.LockHeld, inst: |
|
268 | 270 | if not wait: |
|
269 |
raise |
|
|
270 |
self.ui.warn(_("waiting for lock held by %s\n") % |
|
|
271 | try: | |
|
272 |
|
|
|
273 |
|
|
|
274 |
|
|
|
275 |
|
|
|
276 | except lock.LockHeld, inst: | |
|
277 | raise util.Abort(_("timeout while waiting for " | |
|
278 | "lock held by %s") % inst.args[0]) | |
|
271 | raise | |
|
272 | self.ui.warn(_("waiting for lock on %s held by %s\n") % | |
|
273 | (desc, inst.args[0])) | |
|
274 | # default to 600 seconds timeout | |
|
275 | l = lock.lock(self.join(lockname), | |
|
276 | int(self.ui.config("ui", "timeout") or 600), | |
|
277 | releasefn, desc=desc) | |
|
279 | 278 | if acquirefn: |
|
280 | 279 | acquirefn() |
|
281 | 280 | return l |
|
282 | 281 | |
|
283 | 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 | 286 | def wlock(self, wait=1): |
|
287 | return self.do_lock("wlock", wait, | |
|
288 |
self. |
|
|
289 |
self. |
|
|
287 | return self.do_lock("wlock", wait, self.dirstate.write, | |
|
288 | self.wreload, | |
|
289 | desc=_('working directory of %s') % self.origroot) | |
|
290 | 290 | |
|
291 | 291 | def checkfilemerge(self, filename, text, filelog, manifest1, manifest2): |
|
292 | 292 | "determine whether a new filenode is needed" |
@@ -8,10 +8,16 b'' | |||
|
8 | 8 | from demandload import * |
|
9 | 9 | demandload(globals(), 'errno os socket time util') |
|
10 | 10 | |
|
11 |
class LockException( |
|
|
12 | pass | |
|
11 | class LockException(IOError): | |
|
12 | def __init__(self, errno, strerror, filename, desc): | |
|
13 | IOError.__init__(self, errno, strerror, filename) | |
|
14 | self.desc = desc | |
|
15 | ||
|
13 | 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 | 21 | class LockUnavailable(LockException): |
|
16 | 22 | pass |
|
17 | 23 | |
@@ -24,7 +30,7 b' class lock(object):' | |||
|
24 | 30 | # old-style lock: symlink to pid |
|
25 | 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 | 34 | self.f = file |
|
29 | 35 | self.held = 0 |
|
30 | 36 | self.timeout = timeout |
@@ -32,6 +38,7 b' class lock(object):' | |||
|
32 | 38 | self.id = None |
|
33 | 39 | self.host = None |
|
34 | 40 | self.pid = None |
|
41 | self.desc = desc | |
|
35 | 42 | self.lock() |
|
36 | 43 | |
|
37 | 44 | def __del__(self): |
@@ -49,7 +56,8 b' class lock(object):' | |||
|
49 | 56 | if timeout > 0: |
|
50 | 57 | timeout -= 1 |
|
51 | 58 | continue |
|
52 | raise inst | |
|
59 | raise LockHeld(errno.ETIMEDOUT, inst.filename, self.desc, | |
|
60 | inst.locker) | |
|
53 | 61 | |
|
54 | 62 | def trylock(self): |
|
55 | 63 | if self.id is None: |
@@ -64,9 +72,11 b' class lock(object):' | |||
|
64 | 72 | if why.errno == errno.EEXIST: |
|
65 | 73 | locker = self.testlock() |
|
66 | 74 | if locker: |
|
67 |
raise LockHeld( |
|
|
75 | raise LockHeld(errno.EAGAIN, self.f, self.desc, | |
|
76 | locker) | |
|
68 | 77 | else: |
|
69 |
raise LockUnavailable(why |
|
|
78 | raise LockUnavailable(why.errno, why.strerror, | |
|
79 | why.filename, self.desc) | |
|
70 | 80 | |
|
71 | 81 | def testlock(self): |
|
72 | 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