diff hgext3rd/topic/topicmap.py @ 6336:453861da6922

topic: use fully qualified branch name during exchange For the entire duration of exchange process, we now use branch//namespace/topic format for branchmap, head checking, etc. Sometimes we still need to disable this feature (e.g. when pushing to a repo that doesn't have topic extension enabled), but every other case should be handled using the new fqbn format. This applies both to internal API, such as having fqbn as branchmap keys and even making ctx.branch() return fqbn, and to UI, such as users seeing fqbn in hg branches output and messages from hg push. Things to note: now we're wrapping revbranchcache.branchinfo() during the extension setup, instead of doing it only in one place in _headssummary(). We're also using override_context_branch context manager that makes ctx.branch() return fqbn also in cases when we call the original _headssummary(). There are still places in the UI where branch names are not in fqbn format, because they don't take part in the exchange process.
author Anton Shestakov <av6@dwimlabs.net>
date Sat, 12 Nov 2022 16:24:55 +0400
parents f4ffe1e67a9b
children 3271ec128328
line wrap: on
line diff
--- a/hgext3rd/topic/topicmap.py	Thu Oct 20 17:58:08 2022 +0400
+++ b/hgext3rd/topic/topicmap.py	Sat Nov 12 16:24:55 2022 +0400
@@ -178,6 +178,18 @@
         new.phaseshash = self.phaseshash
         return new
 
+    def load(self, repo, lineiter):
+        """call branchmap.load(), and then transform branch names to be in the
+        new "//" format
+        """
+        super(_topiccache, self).load(repo, lineiter)
+        entries = compat.bcentries(self)
+
+        for branch in tuple(entries):
+            formatted = common.formatfqbn(branch=branch)
+            if branch != formatted:
+                entries[formatted] = entries.pop(branch)
+
     def validfor(self, repo):
         """Is the cache content valid regarding a repo
 
@@ -198,10 +210,21 @@
                 return False
 
     def write(self, repo):
+        """write cache to disk if it's not topic-only, but first transform
+        cache keys from branches in "//" format into bare branch names
+        """
         # we expect mutable set to be small enough to be that computing it all
         # the time will be fast enough
         if not istopicfilter(repo.filtername):
-            super(_topiccache, self).write(repo)
+            cache = self.copy()
+            entries = compat.bcentries(cache)
+
+            for formatted in tuple(entries):
+                branch, tns, topic = common.parsefqbn(formatted)
+                if branch != formatted:
+                    entries[branch] = entries.pop(formatted)
+
+            super(_topiccache, cache).write(repo)
 
     def update(self, repo, revgen):
         """Given a branchhead cache, self, that may have extra nodes or be
@@ -210,19 +233,14 @@
         """
         if not istopicfilter(repo.filtername):
             return super(_topiccache, self).update(repo, revgen)
-        unfi = repo.unfiltered()
-        oldgetbranchinfo = unfi.revbranchcache().branchinfo
 
-        def branchinfo(r, changelog=None):
-            info = oldgetbranchinfo(r)
-            ctx = unfi[r]
-            branch = info[0]
-            if ctx.mutable():
-                branch = ctx.fqbn()
-            return (branch, info[1])
-        try:
-            unfi.revbranchcache().branchinfo = branchinfo
-            super(_topiccache, self).update(repo, revgen)
-            self.phaseshash = _phaseshash(repo, self.tiprev)
-        finally:
-            unfi.revbranchcache().branchinfo = oldgetbranchinfo
+        # See topic.discovery._headssummary(), where repo.unfiltered gets
+        # overridden to return .filtered('unfiltered-topic'). revbranchcache
+        # only can be created for unfiltered repo (filtername is None), so we
+        # do that here, and this revbranchcache will be cached inside repo.
+        # When we get rid of *-topic filters, then this workaround can be
+        # removed too.
+        repo.unfiltered().revbranchcache()
+
+        super(_topiccache, self).update(repo, revgen)
+        self.phaseshash = _phaseshash(repo, self.tiprev)