Mercurial > hg-git
annotate hggit/util.py @ 1024:078c3912afce
bookmarks: compatibility with new applychanges api
Recent versions of mercuiral issue a devel-warn if the old recordchange api is
used, but we want to remain backwards-compatible, so this patch refactors things
to be forward-compatible and backwards-compatible.
author | Ryan McElroy <rmcelroy@fb.com> |
---|---|
date | Wed, 19 Jul 2017 05:51:44 -0700 |
parents | 0b957c2d151a |
children | b4d2180739bb |
rev | line source |
---|---|
779
a951b04338e1
hgrepo: move _transform_notgit into util
Siddharth Agarwal <sid0@fb.com>
parents:
686
diff
changeset
|
1 """Compatibility functions for old Mercurial versions and other utility |
a951b04338e1
hgrepo: move _transform_notgit into util
Siddharth Agarwal <sid0@fb.com>
parents:
686
diff
changeset
|
2 functions.""" |
919
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
3 import re |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
4 |
479
5c1d4311440d
submodules: only use the ordereddict backport if collections.OrderedDict is unavailable
Augie Fackler <raf@durin42.com>
parents:
476
diff
changeset
|
5 try: |
5c1d4311440d
submodules: only use the ordereddict backport if collections.OrderedDict is unavailable
Augie Fackler <raf@durin42.com>
parents:
476
diff
changeset
|
6 from collections import OrderedDict |
5c1d4311440d
submodules: only use the ordereddict backport if collections.OrderedDict is unavailable
Augie Fackler <raf@durin42.com>
parents:
476
diff
changeset
|
7 except ImportError: |
5c1d4311440d
submodules: only use the ordereddict backport if collections.OrderedDict is unavailable
Augie Fackler <raf@durin42.com>
parents:
476
diff
changeset
|
8 from ordereddict import OrderedDict |
320
6eded2e4c616
Un-break hg 1.3 by adding a compat layer for progress.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
9 |
979
a3da45923700
util: regularize mercurial imports
Sean Farley <sean@farley.io>
parents:
919
diff
changeset
|
10 from dulwich import errors |
a3da45923700
util: regularize mercurial imports
Sean Farley <sean@farley.io>
parents:
919
diff
changeset
|
11 from mercurial import ( |
980
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
12 lock as lockmod, |
979
a3da45923700
util: regularize mercurial imports
Sean Farley <sean@farley.io>
parents:
919
diff
changeset
|
13 util as hgutil, |
a3da45923700
util: regularize mercurial imports
Sean Farley <sean@farley.io>
parents:
919
diff
changeset
|
14 ) |
a3da45923700
util: regularize mercurial imports
Sean Farley <sean@farley.io>
parents:
919
diff
changeset
|
15 |
919
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
16 gitschemes = ('git', 'git+ssh', 'git+http', 'git+https') |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
17 |
476
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
18 def parse_hgsub(lines): |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
19 """Fills OrderedDict with hgsub file content passed as list of lines""" |
479
5c1d4311440d
submodules: only use the ordereddict backport if collections.OrderedDict is unavailable
Augie Fackler <raf@durin42.com>
parents:
476
diff
changeset
|
20 rv = OrderedDict() |
476
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
21 for l in lines: |
891 | 22 ls = l.strip() |
23 if not ls or ls[0] == '#': | |
24 continue | |
476
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
25 name, value = l.split('=', 1) |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
26 rv[name.strip()] = value.strip() |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
27 return rv |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
28 |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
29 def serialize_hgsub(data): |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
30 """Produces a string from OrderedDict hgsub content""" |
891 | 31 return ''.join(['%s = %s\n' % (n, v) for n, v in data.iteritems()]) |
476
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
32 |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
33 def parse_hgsubstate(lines): |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
34 """Fills OrderedDict with hgsubtate file content passed as list of lines""" |
479
5c1d4311440d
submodules: only use the ordereddict backport if collections.OrderedDict is unavailable
Augie Fackler <raf@durin42.com>
parents:
476
diff
changeset
|
35 rv = OrderedDict() |
476
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
36 for l in lines: |
891 | 37 ls = l.strip() |
38 if not ls or ls[0] == '#': | |
39 continue | |
476
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
40 value, name = l.split(' ', 1) |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
41 rv[name.strip()] = value.strip() |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
42 return rv |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
43 |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
44 def serialize_hgsubstate(data): |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
45 """Produces a string from OrderedDict hgsubstate content""" |
b9ede5f91701
Subrepos: generate .hgsubstate and .hgsub based on gitlinks and .gitmodules, preserve gitlinks on hg commit export. Tests included. Dependency from PyPI's ordereddict to use OrderedDict
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
320
diff
changeset
|
46 return ''.join(['%s %s\n' % (data[n], n) for n in sorted(data)]) |
779
a951b04338e1
hgrepo: move _transform_notgit into util
Siddharth Agarwal <sid0@fb.com>
parents:
686
diff
changeset
|
47 |
a951b04338e1
hgrepo: move _transform_notgit into util
Siddharth Agarwal <sid0@fb.com>
parents:
686
diff
changeset
|
48 def transform_notgit(f): |
891 | 49 '''use as a decorator around functions that call into dulwich''' |
779
a951b04338e1
hgrepo: move _transform_notgit into util
Siddharth Agarwal <sid0@fb.com>
parents:
686
diff
changeset
|
50 def inner(*args, **kwargs): |
a951b04338e1
hgrepo: move _transform_notgit into util
Siddharth Agarwal <sid0@fb.com>
parents:
686
diff
changeset
|
51 try: |
a951b04338e1
hgrepo: move _transform_notgit into util
Siddharth Agarwal <sid0@fb.com>
parents:
686
diff
changeset
|
52 return f(*args, **kwargs) |
a951b04338e1
hgrepo: move _transform_notgit into util
Siddharth Agarwal <sid0@fb.com>
parents:
686
diff
changeset
|
53 except errors.NotGitRepository: |
842
cf9dd81b61dc
util: add missing mercurial.util import
paul.wheeler@appature.com
parents:
779
diff
changeset
|
54 raise hgutil.Abort('not a git repository') |
779
a951b04338e1
hgrepo: move _transform_notgit into util
Siddharth Agarwal <sid0@fb.com>
parents:
686
diff
changeset
|
55 return inner |
919
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
56 |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
57 def isgitsshuri(uri): |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
58 """Method that returns True if a uri looks like git-style uri |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
59 |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
60 Tests: |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
61 |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
62 >>> print isgitsshuri('http://fqdn.com/hg') |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
63 False |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
64 >>> print isgitsshuri('http://fqdn.com/test.git') |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
65 False |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
66 >>> print isgitsshuri('git@github.com:user/repo.git') |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
67 True |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
68 >>> print isgitsshuri('github-123.com:user/repo.git') |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
69 True |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
70 >>> print isgitsshuri('git@127.0.0.1:repo.git') |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
71 True |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
72 >>> print isgitsshuri('git@[2001:db8::1]:repository.git') |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
73 True |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
74 """ |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
75 for scheme in gitschemes: |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
76 if uri.startswith('%s://' % scheme): |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
77 return False |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
78 |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
79 if uri.startswith('http:') or uri.startswith('https:'): |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
80 return False |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
81 |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
82 m = re.match(r'(?:.+@)*([\[]?[\w\d\.\:\-]+[\]]?):(.*)', uri) |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
83 if m: |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
84 # here we're being fairly conservative about what we consider to be git |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
85 # urls |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
86 giturl, repopath = m.groups() |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
87 # definitely a git repo |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
88 if repopath.endswith('.git'): |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
89 return True |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
90 # use a simple regex to check if it is a fqdn regex |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
91 fqdn_re = (r'(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}' |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
92 r'(?<!-)\.)+[a-zA-Z]{2,63}$)') |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
93 if re.match(fqdn_re, giturl): |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
94 return True |
6507d2a6be0a
util: add heuristic method to determine if a uri is git
Sean Farley <sean@farley.io>
parents:
891
diff
changeset
|
95 return False |
980
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
96 |
1024
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
97 def updatebookmarks(repo, changes, name='git_handler'): |
980
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
98 """abstract writing bookmarks for backwards compatibility""" |
1024
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
99 bms = repo._bookmarks |
980
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
100 tr = lock = wlock = None |
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
101 try: |
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
102 wlock = repo.wlock() |
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
103 lock = repo.lock() |
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
104 tr = repo.transaction(name) |
1024
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
105 if hgutil.safehasattr(bms, 'applychanges'): |
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
106 # applychanges was added in mercurial 4.3 |
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
107 bms.applychanges(repo, tr, changes) |
980
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
108 else: |
1024
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
109 for name, node in changes: |
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
110 if node is None: |
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
111 del bms[name] |
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
112 else: |
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
113 bms[name] = node |
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
114 if hgutil.safehasattr(bms, 'recordchange'): |
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
115 # recordchange was added in mercurial 3.2 |
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
116 bms.recordchange(tr) |
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
117 else: |
078c3912afce
bookmarks: compatibility with new applychanges api
Ryan McElroy <rmcelroy@fb.com>
parents:
980
diff
changeset
|
118 bms.write() |
980
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
119 tr.close() |
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
120 finally: |
0b957c2d151a
util: add method for writing bookmarks
Sean Farley <sean@farley.io>
parents:
979
diff
changeset
|
121 lockmod.release(tr, lock, wlock) |