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