Show More
@@ -0,0 +1,82 b'' | |||
|
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 |
@@ -0,0 +1,61 b'' | |||
|
1 | $ hg init test-content | |
|
2 | $ cd test-content | |
|
3 | $ hg debugbuilddag '+2*2*3*4' | |
|
4 | $ hg bookmark -r 1 @ | |
|
5 | $ hg log -G --template '{rev}:{node|short}' | |
|
6 | o 4:e7bd5218ca15 | |
|
7 | | | |
|
8 | | o 3:6100d3090acf | |
|
9 | |/ | |
|
10 | | o 2:fa942426a6fd | |
|
11 | |/ | |
|
12 | | o 1:66f7d451a68b | |
|
13 | |/ | |
|
14 | o 0:1ea73414a91b | |
|
15 | ||
|
16 | $ hg --config extensions.closehead= close-head -m 'Not a head' 0 1 | |
|
17 | abort: revision is not an open head: 0 | |
|
18 | [255] | |
|
19 | $ hg --config extensions.closehead= close-head -m 'Not a head' -r 0 1 | |
|
20 | abort: revision is not an open head: 0 | |
|
21 | [255] | |
|
22 | $ hg --config extensions.closehead= close-head -m 'Close old heads' -r 1 2 | |
|
23 | $ hg bookmark | |
|
24 | @ 1:66f7d451a68b | |
|
25 | $ hg heads | |
|
26 | changeset: 4:e7bd5218ca15 | |
|
27 | parent: 0:1ea73414a91b | |
|
28 | user: debugbuilddag | |
|
29 | date: Thu Jan 01 00:00:04 1970 +0000 | |
|
30 | summary: r4 | |
|
31 | ||
|
32 | changeset: 3:6100d3090acf | |
|
33 | parent: 0:1ea73414a91b | |
|
34 | user: debugbuilddag | |
|
35 | date: Thu Jan 01 00:00:03 1970 +0000 | |
|
36 | summary: r3 | |
|
37 | ||
|
38 | $ hg --config extensions.closehead= close-head -m 'Close more old heads' 4 | |
|
39 | $ hg heads | |
|
40 | changeset: 3:6100d3090acf | |
|
41 | parent: 0:1ea73414a91b | |
|
42 | user: debugbuilddag | |
|
43 | date: Thu Jan 01 00:00:03 1970 +0000 | |
|
44 | summary: r3 | |
|
45 | ||
|
46 | $ hg --config extensions.closehead= close-head -m 'Not a head' 0 | |
|
47 | abort: revision is not an open head: 0 | |
|
48 | [255] | |
|
49 | $ hg --config extensions.closehead= close-head -m 'Already closed head' 1 | |
|
50 | abort: revision is not an open head: 1 | |
|
51 | [255] | |
|
52 | ||
|
53 | $ hg init ../test-empty | |
|
54 | $ cd ../test-empty | |
|
55 | $ hg debugbuilddag '+1' | |
|
56 | $ hg log -G --template '{rev}:{node|short}' | |
|
57 | o 0:1ea73414a91b | |
|
58 | ||
|
59 | $ hg --config extensions.closehead= close-head -m 'Close initial revision' 0 | |
|
60 | $ hg heads | |
|
61 | [1] |
@@ -262,6 +262,7 b' Test extension help:' | |||
|
262 | 262 | censor erase file content at a given revision |
|
263 | 263 | churn command to display statistics about repository history |
|
264 | 264 | clonebundles advertise pre-generated bundles to seed clones |
|
265 | closehead close arbitrary heads without checking them out first | |
|
265 | 266 | convert import revisions from foreign VCS repositories into |
|
266 | 267 | Mercurial |
|
267 | 268 | eol automatically manage newlines in repository files |
General Comments 0
You need to be logged in to leave comments.
Login now