Mercurial > hg
comparison hgext/closehead.py @ 39993:cd5f2e615262
extensions: new closehead module for closing arbitrary heads
``hg close-head`` allows closing arbitrary heads. It is equivalent to
checking out the given revisions and commit an empty change with
``hg commit --close-branch``.
Differential Revision: https://phab.mercurial-scm.org/D3557
author | Joerg Sonnenberger <joerg@bec.de> |
---|---|
date | Mon, 14 May 2018 00:43:07 +0200 |
parents | |
children | 12a72729678e |
comparison
equal
deleted
inserted
replaced
39992:ec3c06a1c554 | 39993:cd5f2e615262 |
---|---|
1 # closehead.py - Close arbitrary heads without checking them out first | |
2 # | |
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. | |
5 | |
6 '''close arbitrary heads without checking them out first''' | |
7 | |
8 from __future__ import absolute_import | |
9 | |
10 from mercurial.i18n import _ | |
11 from mercurial import ( | |
12 bookmarks, | |
13 cmdutil, | |
14 context, | |
15 error, | |
16 pycompat, | |
17 registrar, | |
18 scmutil, | |
19 ) | |
20 | |
21 cmdtable = {} | |
22 command = registrar.command(cmdtable) | |
23 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | |
24 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | |
25 # be specifying the version(s) of Mercurial they are tested with, or | |
26 # leave the attribute unspecified. | |
27 testedwith = 'ships-with-hg-core' | |
28 | |
29 commitopts = cmdutil.commitopts | |
30 commitopts2 = cmdutil.commitopts2 | |
31 commitopts3 = [('r', 'rev', '', | |
32 _('revision to check'), _('REV'))] | |
33 | |
34 @command('close-head|close-heads', commitopts + commitopts2 + commitopts3, | |
35 _('[OPTION]... [REV]...'), inferrepo=True) | |
36 def close_branch(ui, repo, *revs, **opts): | |
37 """close the given head revisions | |
38 | |
39 This is equivalent to checking out each revision in a clean tree and running | |
40 ``hg commit --close-branch``, except that it doesn't change the working | |
41 directory. | |
42 | |
43 The commit message must be specified with -l or -m. | |
44 """ | |
45 def docommit(rev): | |
46 cctx = context.memctx(repo, parents=[rev, None], text=message, | |
47 files=[], filectxfn=None, user=opts.get('user'), | |
48 date=opts.get('date'), extra=extra) | |
49 tr = repo.transaction('commit') | |
50 ret = repo.commitctx(cctx, True) | |
51 bookmarks.update(repo, [rev, None], ret) | |
52 cctx.markcommitted(ret) | |
53 tr.close() | |
54 | |
55 opts = pycompat.byteskwargs(opts) | |
56 | |
57 revs += tuple(opts.get('rev', [])) | |
58 revs = scmutil.revrange(repo, revs) | |
59 | |
60 if not revs: | |
61 raise error.Abort(_('no revisions specified')) | |
62 | |
63 heads = [] | |
64 for branch in repo.branchmap(): | |
65 heads.extend(repo.branchheads(branch)) | |
66 heads = set(repo[h].rev() for h in heads) | |
67 for rev in revs: | |
68 if rev not in heads: | |
69 raise error.Abort(_('revision is not an open head: %s') % rev) | |
70 | |
71 message = cmdutil.logmessage(ui, opts) | |
72 if not message: | |
73 raise error.Abort(_("no commit message specified with -l or -m")) | |
74 extra = { 'close': '1' } | |
75 | |
76 with repo.wlock(), repo.lock(): | |
77 for rev in revs: | |
78 r = repo[rev] | |
79 branch = r.branch() | |
80 extra['branch'] = branch | |
81 docommit(r) | |
82 return 0 |