# HG changeset patch # User Anton Shestakov # Date 1702146395 10800 # Node ID ba7ede61f6d4bc1850d5caca4120cd6d20729866 # Parent 417f775d3eee56e566b76917eb4b512ffe14bddb topic: implement dirstate.topic() and dirstate.tns() The implementations closely follow the implementation of dirstate.branch(), including dirstate.setbranch(), from before a6e0b7d4ae9d. So far in this patch we don't write topics or topic namespaces in a transaction. But we do have `tr` argument in settopic() and settns() because it's easier to introduce it now (even though it's simply ignored). Also because of the branch implementation in core, topic and tns values on disk now have a '\n' character at the end. diff -r 417f775d3eee -r ba7ede61f6d4 hgext3rd/evolve/evolvecmd.py --- a/hgext3rd/evolve/evolvecmd.py Fri Jul 12 15:44:12 2024 +0400 +++ b/hgext3rd/evolve/evolvecmd.py Sat Dec 09 15:26:35 2023 -0300 @@ -18,7 +18,6 @@ context, encoding, error, - extensions, hg, merge, mergeutil, @@ -985,12 +984,10 @@ compat._update(repo, dest, branchmerge=False, force=True) if keepbranch: compat.setbranch(repo, orig.branch()) - if util.safehasattr(repo, 'currenttns') and repo.currenttns != orig.topic_namespace(): - topic = extensions.find(b'topic') - topic._changecurrenttns(repo, orig.topic_namespace()) - if util.safehasattr(repo, 'currenttopic') and repo.currenttopic != orig.topic(): - topic = extensions.find(b'topic') - topic._changecurrenttopic(repo, orig.topic()) + if util.safehasattr(repo, 'currenttns'): + repo.dirstate.settns(orig.topic_namespace(), repo.currenttransaction()) + if util.safehasattr(repo, 'currenttopic'): + repo.dirstate.settopic(orig.topic(), repo.currenttransaction()) stats = merge.graft(repo, orig, pctx, [b'destination', b'evolving'], True) diff -r 417f775d3eee -r ba7ede61f6d4 hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Fri Jul 12 15:44:12 2024 +0400 +++ b/hgext3rd/topic/__init__.py Sat Dec 09 15:26:35 2023 -0300 @@ -172,6 +172,7 @@ commands, configitems, context, + dirstate, encoding, error, exchange, @@ -720,8 +721,7 @@ @property def currenttns(self): - tns = self.vfs.tryread(b'topic-namespace') or b'none' - return encoding.tolocal(tns) + return self.dirstate.tns() @util.propertycache def _topiccache(self): @@ -740,8 +740,7 @@ @property def currenttopic(self): - topic = self.vfs.tryread(b'topic') - return encoding.tolocal(topic) + return self.dirstate.topic() # overwritten at the instance level by topicmap.py _autobranchmaptopic = True @@ -927,6 +926,59 @@ b'topics', b'topic', namemap=_namemap, nodemap=_nodemap, listnames=lambda repo: repo.topics)) + class topicdirstate(dirstate.dirstate): + @dirstate.repocache(b'topic') + def _topic(self): + try: + return self._opener.read(b'topic').strip() or b'' + except IOError as inst: + if inst.errno != errno.ENOENT: + raise + return b'' + + def topic(self): + return encoding.tolocal(self._topic) + + def settopic(self, topic, tr): + self.__class__._topic.set(self, encoding.fromlocal(topic)) + del topic # safeguard to not use it after adjusting encoding + vfs = self._opener + if self._topic != b'': + with vfs(b'topic', b'w', atomictemp=True, checkambig=True) as f: + f.write(self._topic + b'\n') + else: + vfs.tryunlink(b'topic') + ce = self._filecache[b'_topic'] + if ce: + ce.refresh() + + @dirstate.repocache(b'topic-namespace') + def _tns(self): + try: + return self._opener.read(b'topic-namespace').strip() or b'none' + except IOError as inst: + if inst.errno != errno.ENOENT: + raise + return b'none' + + def tns(self): + return encoding.tolocal(self._tns) + + def settns(self, tns, tr): + self.__class__._tns.set(self, encoding.fromlocal(tns)) + del tns # safeguard to not use it after adjusting encoding + vfs = self._opener + if self._tns != b'none': + with vfs(b'topic-namespace', b'w', atomictemp=True, checkambig=True) as f: + f.write(self._tns + b'\n') + else: + vfs.tryunlink(b'topic-namespace') + ce = self._filecache[b'_tns'] + if ce: + ce.refresh() + + dirstate.dirstate = topicdirstate + templatekeyword = registrar.templatekeyword() @templatekeyword(b'topic', requires={b'ctx'}) @@ -1304,12 +1356,11 @@ def _changecurrenttopic(repo, newtopic): """changes the current topic.""" - if newtopic: - with repo.wlock(): - repo.vfs.write(b'topic', newtopic) - else: - if repo.vfs.exists(b'topic'): - repo.vfs.unlink(b'topic') + # assert newtopic is not None + if not newtopic: + newtopic = b'' + with repo.wlock(): + repo.dirstate.settopic(newtopic, repo.currenttransaction()) def _changetopics(ui, repo, revs, newtopic): """ Changes topic to newtopic of all the revisions in the revset and return @@ -1568,7 +1619,7 @@ hint = _(b"see 'hg help -e topic.topic-mode' for details") if opts.get('topic'): t = opts['topic'] - repo.vfs.write(b'topic', t) + _changecurrenttopic(repo, t) elif opts.get('amend'): pass elif notopic and mayabort: @@ -1579,7 +1630,8 @@ if not ui.quiet: ui.warn((b"(%s)\n") % hint) elif notopic and mayrandom: - repo.vfs.write(b'topic', randomname.randomtopicname(ui)) + t = randomname.randomtopicname(ui) + _changecurrenttopic(repo, t) return orig(ui, repo, *args, **opts) def committextwrap(orig, repo, ctx, subs, extramsg): @@ -1795,11 +1847,8 @@ raise compat.InputError(msg, hint=hint) def _changecurrenttns(repo, tns): - if tns != b'none': - with repo.wlock(): - repo.vfs.write(b'topic-namespace', tns) - else: - repo.vfs.unlinkpath(b'topic-namespace', ignoremissing=True) + with repo.wlock(): + repo.dirstate.settns(tns, repo.currenttransaction()) @command(b'debug-topic-namespace', [ (b'', b'clear', False, b'clear active topic namespace if any'), diff -r 417f775d3eee -r ba7ede61f6d4 tests/test-namespaces.t --- a/tests/test-namespaces.t Fri Jul 12 15:44:12 2024 +0400 +++ b/tests/test-namespaces.t Sat Dec 09 15:26:35 2023 -0300 @@ -12,7 +12,7 @@ $ hg debug-topic-namespaces space-name $ cat .hg/topic-namespace - space-name (no-eol) + space-name $ hg log -r 'wdir()' -T '{topic_namespace}\n' none @@ -47,7 +47,7 @@ $ hg --encoding latin1 debug-topic-namespaces \xe6 (esc) $ cat .hg/topic-namespace - \xc3\xa6 (no-eol) (esc) + \xc3\xa6 (esc) $ hg --encoding utf-8 debug-topic-namespace © abort: invalid topic namespace name: '\xc2\xa9' (esc) @@ -130,11 +130,11 @@ $ hg debug-topic-namespace alice $ cat .hg/topic-namespace - alice (no-eol) + alice $ hg topics * feature (1 changesets) $ cat .hg/topic - feature (no-eol) + feature Updating to a topic namespace is not supported