##// END OF EJS Templates
closehead: wrap transaction handling in a context manager
Matt Harbison -
r51767:f12d53a6 default
parent child Browse files
Show More
@@ -1,92 +1,91 b''
1 # closehead.py - Close arbitrary heads without checking them out first
1 # closehead.py - Close arbitrary heads without checking them out first
2 #
2 #
3 # This software may be used and distributed according to the terms of the
3 # This software may be used and distributed according to the terms of the
4 # GNU General Public License version 2 or any later version.
4 # GNU General Public License version 2 or any later version.
5
5
6 '''close arbitrary heads without checking them out first'''
6 '''close arbitrary heads without checking them out first'''
7
7
8
8
9 from mercurial.i18n import _
9 from mercurial.i18n import _
10 from mercurial import (
10 from mercurial import (
11 bookmarks,
11 bookmarks,
12 cmdutil,
12 cmdutil,
13 context,
13 context,
14 error,
14 error,
15 logcmdutil,
15 logcmdutil,
16 pycompat,
16 pycompat,
17 registrar,
17 registrar,
18 )
18 )
19
19
20 cmdtable = {}
20 cmdtable = {}
21 command = registrar.command(cmdtable)
21 command = registrar.command(cmdtable)
22 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
22 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
23 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
23 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
24 # be specifying the version(s) of Mercurial they are tested with, or
24 # be specifying the version(s) of Mercurial they are tested with, or
25 # leave the attribute unspecified.
25 # leave the attribute unspecified.
26 testedwith = b'ships-with-hg-core'
26 testedwith = b'ships-with-hg-core'
27
27
28 commitopts = cmdutil.commitopts
28 commitopts = cmdutil.commitopts
29 commitopts2 = cmdutil.commitopts2
29 commitopts2 = cmdutil.commitopts2
30 commitopts3 = [(b'r', b'rev', [], _(b'revision to check'), _(b'REV'))]
30 commitopts3 = [(b'r', b'rev', [], _(b'revision to check'), _(b'REV'))]
31
31
32
32
33 @command(
33 @command(
34 b'close-head|close-heads',
34 b'close-head|close-heads',
35 commitopts + commitopts2 + commitopts3,
35 commitopts + commitopts2 + commitopts3,
36 _(b'[OPTION]... [REV]...'),
36 _(b'[OPTION]... [REV]...'),
37 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
37 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
38 inferrepo=True,
38 inferrepo=True,
39 )
39 )
40 def close_branch(ui, repo, *revs, **opts):
40 def close_branch(ui, repo, *revs, **opts):
41 """close the given head revisions
41 """close the given head revisions
42
42
43 This is equivalent to checking out each revision in a clean tree and running
43 This is equivalent to checking out each revision in a clean tree and running
44 ``hg commit --close-branch``, except that it doesn't change the working
44 ``hg commit --close-branch``, except that it doesn't change the working
45 directory.
45 directory.
46
46
47 The commit message must be specified with -l or -m.
47 The commit message must be specified with -l or -m.
48 """
48 """
49
49
50 def docommit(rev):
50 def docommit(rev):
51 cctx = context.memctx(
51 cctx = context.memctx(
52 repo,
52 repo,
53 parents=[rev, None],
53 parents=[rev, None],
54 text=message,
54 text=message,
55 files=[],
55 files=[],
56 filectxfn=None,
56 filectxfn=None,
57 user=opts.get('user'),
57 user=opts.get('user'),
58 date=opts.get('date'),
58 date=opts.get('date'),
59 extra=extra,
59 extra=extra,
60 )
60 )
61 tr = repo.transaction(b'commit')
61 with repo.transaction(b'commit'):
62 ret = repo.commitctx(cctx, True)
62 ret = repo.commitctx(cctx, True)
63 bookmarks.update(repo, [rev, None], ret)
63 bookmarks.update(repo, [rev, None], ret)
64 cctx.markcommitted(ret)
64 cctx.markcommitted(ret)
65 tr.close()
66
65
67 revs += tuple(opts.get('rev', []))
66 revs += tuple(opts.get('rev', []))
68 revs = logcmdutil.revrange(repo, revs)
67 revs = logcmdutil.revrange(repo, revs)
69
68
70 if not revs:
69 if not revs:
71 raise error.Abort(_(b'no revisions specified'))
70 raise error.Abort(_(b'no revisions specified'))
72
71
73 heads = []
72 heads = []
74 for branch in repo.branchmap():
73 for branch in repo.branchmap():
75 heads.extend(repo.branchheads(branch))
74 heads.extend(repo.branchheads(branch))
76 heads = {repo[h].rev() for h in heads}
75 heads = {repo[h].rev() for h in heads}
77 for rev in revs:
76 for rev in revs:
78 if rev not in heads:
77 if rev not in heads:
79 raise error.Abort(_(b'revision is not an open head: %d') % rev)
78 raise error.Abort(_(b'revision is not an open head: %d') % rev)
80
79
81 message = cmdutil.logmessage(ui, pycompat.byteskwargs(opts))
80 message = cmdutil.logmessage(ui, pycompat.byteskwargs(opts))
82 if not message:
81 if not message:
83 raise error.Abort(_(b"no commit message specified with -l or -m"))
82 raise error.Abort(_(b"no commit message specified with -l or -m"))
84 extra = {b'close': b'1'}
83 extra = {b'close': b'1'}
85
84
86 with repo.wlock(), repo.lock():
85 with repo.wlock(), repo.lock():
87 for rev in revs:
86 for rev in revs:
88 r = repo[rev]
87 r = repo[rev]
89 branch = r.branch()
88 branch = r.branch()
90 extra[b'branch'] = branch
89 extra[b'branch'] = branch
91 docommit(r)
90 docommit(r)
92 return 0
91 return 0
General Comments 0
You need to be logged in to leave comments. Login now