|
1 # __init__.py - topic extension |
|
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 """Adds topic branches. Topic branches are lightweight branches which |
|
6 dissappear when changes are finalized. |
|
7 |
|
8 This is sort of similar to a bookmark, but it applies to a whole |
|
9 series instead of a single revision. |
|
10 """ |
|
11 import functools |
|
12 |
|
13 from mercurial import cmdutil |
|
14 from mercurial import commands |
|
15 from mercurial import extensions |
|
16 from mercurial import namespaces |
|
17 from mercurial import phases |
|
18 from mercurial import util |
|
19 |
|
20 cmdtable = {} |
|
21 command = cmdutil.command(cmdtable) |
|
22 |
|
23 def _namemap(repo, name): |
|
24 return [ctx.node() for ctx in |
|
25 repo.set('not public() and extra(topic, %s)', name)] |
|
26 |
|
27 def _nodemap(repo, node): |
|
28 ctx = repo[node] |
|
29 t = ctx.extra().get('topic', '') |
|
30 if t and ctx.phase() > phases.public: |
|
31 return [t] |
|
32 return [] |
|
33 |
|
34 def reposetup(ui, repo): |
|
35 orig = repo.__class__ |
|
36 class topicrepo(repo.__class__): |
|
37 def commitctx(self, ctx, error=None): |
|
38 current = self.currenttopic |
|
39 if current: |
|
40 ctx.extra()['topic'] = current |
|
41 return orig.commitctx(self, ctx, error=error) |
|
42 |
|
43 @property |
|
44 def topics(self): |
|
45 topics = set(['', self.currenttopic]) |
|
46 for rev in self.revs('not public()'): |
|
47 c = self.changectx(rev) |
|
48 topics.add(c.extra().get('topic', '')) |
|
49 topics.remove('') |
|
50 return topics |
|
51 |
|
52 @property |
|
53 def currenttopic(self): |
|
54 return self.vfs.tryread('topic') |
|
55 |
|
56 if util.safehasattr(repo, 'names'): |
|
57 repo.names.addnamespace(namespaces.namespace( |
|
58 'topics', 'topic', namemap=_namemap, nodemap=_nodemap)) |
|
59 repo.__class__ = topicrepo |
|
60 |
|
61 @command('topics', [ |
|
62 ('', 'clear', False, 'clear active topic if any'), |
|
63 ]) |
|
64 def topics(ui, repo, topic=None, clear=False): |
|
65 """View current topic, set current topic, or see all topics.""" |
|
66 if clear: |
|
67 if repo.vfs.exists('topic'): |
|
68 repo.vfs.unlink('topic') |
|
69 return |
|
70 if topic is not None: |
|
71 with repo.vfs.open('topic', 'w') as f: |
|
72 f.write(topic) |
|
73 return |
|
74 current = repo.currenttopic |
|
75 for t in sorted(repo.topics): |
|
76 marker = '*' if t == current else ' ' |
|
77 ui.write(' %s %s\n' % (marker, t)) |
|
78 |
|
79 |
|
80 def updatewrap(orig, ui, repo, *args, **kwargs): |
|
81 ret = orig(ui, repo, *args, **kwargs) |
|
82 pctx = repo['.'] |
|
83 if pctx.phase() == phases.public and repo.vfs.exists('topic'): |
|
84 repo.vfs.unlink('topic') |
|
85 else: |
|
86 # inherit the topic of the parent revision |
|
87 t = pctx.extra().get('topic', '') |
|
88 if t and pctx.phase() > phases.public: |
|
89 with repo.vfs.open('topic', 'w') as f: |
|
90 f.write(t) |
|
91 return ret |
|
92 |
|
93 extensions.wrapcommand(commands.table, 'update', updatewrap) |