Patchwork D9603: branchmap: refactor revbranchmap and use it as topicmap [PoC]

login
register
mail settings
Submitter phabricator
Date Dec. 14, 2020, 9:41 p.m.
Message ID <differential-rev-PHID-DREV-owg4n67ipduhp4txuteu-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47901/
State New
Headers show

Comments

phabricator - Dec. 14, 2020, 9:41 p.m.
joerg.sonnenberger created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9603

AFFECTED FILES
  mercurial/branchmap.py
  mercurial/cacheutil.py
  mercurial/changegroup.py
  mercurial/changelog.py
  mercurial/commit.py
  mercurial/exchangev2.py
  mercurial/interfaces/repository.py
  mercurial/localrepo.py
  tests/test-acl.t
  tests/test-clone-uncompressed.t
  tests/test-clone.t
  tests/test-clonebundles.t
  tests/test-debugcommands.t
  tests/test-fncache.t
  tests/test-hardlinks.t
  tests/test-http-proxy.t
  tests/test-http.t
  tests/test-inherit-mode.t
  tests/test-keyword.t
  tests/test-mq-symlinks.t
  tests/test-push-http.t
  tests/test-rebase-conflicts.t
  tests/test-remote-hidden.t
  tests/test-server-view.t
  tests/test-share.t
  tests/test-ssh.t
  tests/test-stream-bundle-v2.t
  tests/test-tags.t
  tests/test-treemanifest.t

CHANGE DETAILS




To: joerg.sonnenberger, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/tests/test-treemanifest.t b/tests/test-treemanifest.t
--- a/tests/test-treemanifest.t
+++ b/tests/test-treemanifest.t
@@ -792,7 +792,7 @@ 
   $ hg clone --config experimental.changegroup3=True --stream -U \
   >   http://localhost:$HGPORT1 stream-clone-basicstore
   streaming all changes
-  21 files to transfer, * of data (glob)
+  23 files to transfer, * of data (glob)
   transferred * in * seconds (*) (glob)
   $ hg -R stream-clone-basicstore verify
   checking changesets
@@ -806,7 +806,7 @@ 
   $ hg clone --config experimental.changegroup3=True --stream -U \
   >   http://localhost:$HGPORT2 stream-clone-encodedstore
   streaming all changes
-  21 files to transfer, * of data (glob)
+  23 files to transfer, * of data (glob)
   transferred * in * seconds (*) (glob)
   $ hg -R stream-clone-encodedstore verify
   checking changesets
@@ -820,7 +820,7 @@ 
   $ hg clone --config experimental.changegroup3=True --stream -U \
   >   http://localhost:$HGPORT stream-clone-fncachestore
   streaming all changes
-  22 files to transfer, * of data (glob)
+  24 files to transfer, * of data (glob)
   transferred * in * seconds (*) (glob)
   $ hg -R stream-clone-fncachestore verify
   checking changesets
diff --git a/tests/test-tags.t b/tests/test-tags.t
--- a/tests/test-tags.t
+++ b/tests/test-tags.t
@@ -724,6 +724,8 @@ 
   hgtagsfnodes1
   rbc-names-v1
   rbc-revs-v1
+  topic-names-v1
+  topic-revs-v1
 
 Cache should contain the head only, even though other nodes have tags data
 
@@ -749,6 +751,8 @@ 
   rbc-names-v1
   rbc-revs-v1
   tags2-visible
+  topic-names-v1
+  topic-revs-v1
 
   $ f --size --hexdump tagsclient/.hg/cache/hgtagsfnodes1
   tagsclient/.hg/cache/hgtagsfnodes1: size=96
diff --git a/tests/test-stream-bundle-v2.t b/tests/test-stream-bundle-v2.t
--- a/tests/test-stream-bundle-v2.t
+++ b/tests/test-stream-bundle-v2.t
@@ -46,7 +46,7 @@ 
   $ hg bundle -a --type="none-v2;stream=v2" bundle.hg
   $ hg debugbundle bundle.hg
   Stream params: {}
-  stream2 -- {bytecount: 1693, filecount: 11, requirements: dotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Csparserevlog%2Cstore} (mandatory: True)
+  stream2 -- {bytecount: 1740, filecount: 13, requirements: dotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Csparserevlog%2Cstore} (mandatory: True)
   $ hg debugbundle --spec bundle.hg
   none-v2;stream=v2;requirements%3Ddotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Csparserevlog%2Cstore
 
@@ -71,7 +71,7 @@ 
   bundle2-input-bundle: with-transaction
   bundle2-input-part: "stream2" (params: 3 mandatory) supported
   applying stream bundle
-  11 files to transfer, 1.65 KB of data
+  13 files to transfer, 1.70 KB of data
   starting 4 threads for background file closing (?)
   starting 4 threads for background file closing (?)
   adding [s] data/A.i (66 bytes)
@@ -85,8 +85,10 @@ 
   adding [c] branch2-served (94 bytes)
   adding [c] rbc-names-v1 (7 bytes)
   adding [c] rbc-revs-v1 (40 bytes)
-  transferred 1.65 KB in \d\.\d seconds \(.*/sec\) (re)
-  bundle2-input-part: total payload size 1840
+  adding [c] topic-names-v1 (7 bytes)
+  adding [c] topic-revs-v1 (40 bytes)
+  transferred 1.70 KB in \d\.\d seconds \(.*/sec\) (re)
+  bundle2-input-part: total payload size 1920
   bundle2-input-bundle: 1 parts total
   updating the branch cache
   finished applying clone bundle
@@ -127,7 +129,7 @@ 
   bundle2-input-bundle: with-transaction
   bundle2-input-part: "stream2" (params: 3 mandatory) supported
   applying stream bundle
-  11 files to transfer, 1.65 KB of data
+  13 files to transfer, 1.70 KB of data
   starting 4 threads for background file closing (?)
   starting 4 threads for background file closing (?)
   adding [s] data/A.i (66 bytes)
@@ -141,8 +143,10 @@ 
   adding [c] branch2-served (94 bytes)
   adding [c] rbc-names-v1 (7 bytes)
   adding [c] rbc-revs-v1 (40 bytes)
-  transferred 1.65 KB in *.* seconds (*/sec) (glob)
-  bundle2-input-part: total payload size 1840
+  adding [c] topic-names-v1 (7 bytes)
+  adding [c] topic-revs-v1 (40 bytes)
+  transferred 1.70 KB in *.* seconds (*/sec) (glob)
+  bundle2-input-part: total payload size 1920
   bundle2-input-bundle: 1 parts total
   updating the branch cache
   finished applying clone bundle
diff --git a/tests/test-ssh.t b/tests/test-ssh.t
--- a/tests/test-ssh.t
+++ b/tests/test-ssh.t
@@ -64,8 +64,8 @@ 
 
   $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --stream ssh://user@dummy/remote local-stream
   streaming all changes
-  8 files to transfer, 827 bytes of data
-  transferred 827 bytes in * seconds (*) (glob)
+  10 files to transfer, 865 bytes of data
+  transferred 865 bytes in * seconds (*) (glob)
   updating to branch default
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd local-stream
@@ -84,8 +84,8 @@ 
   $ hg -R local-stream book mybook
   $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --stream ssh://user@dummy/local-stream stream2
   streaming all changes
-  9 files to transfer, 870 bytes of data
-  transferred 870 bytes in * seconds (*) (glob)
+  11 files to transfer, 908 bytes of data
+  transferred 908 bytes in * seconds (*) (glob)
   updating to branch default
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ cd stream2
diff --git a/tests/test-share.t b/tests/test-share.t
--- a/tests/test-share.t
+++ b/tests/test-share.t
@@ -55,6 +55,8 @@ 
   rbc-names-v1
   rbc-revs-v1
   tags2-visible
+  topic-names-v1
+  topic-revs-v1
 
 Cloning a shared repo should pick up the full cache dir on the other hand.
 
@@ -66,6 +68,8 @@ 
   rbc-names-v1
   rbc-revs-v1
   tags2-visible
+  topic-names-v1
+  topic-revs-v1
 
 Some sed versions appends newline, some don't, and some just fails
 
diff --git a/tests/test-server-view.t b/tests/test-server-view.t
--- a/tests/test-server-view.t
+++ b/tests/test-server-view.t
@@ -61,6 +61,8 @@ 
   rbc-revs-v1
   tags2
   tags2-served%89c45d2fa07e
+  topic-names-v1
+  topic-revs-v1
 
 cleanup
 
diff --git a/tests/test-remote-hidden.t b/tests/test-remote-hidden.t
--- a/tests/test-remote-hidden.t
+++ b/tests/test-remote-hidden.t
@@ -87,6 +87,8 @@ 
   rbc-revs-v1
   tags2
   tags2-visible
+  topic-names-v1
+  topic-revs-v1
 
 Check that the `served.hidden` repoview
 ---------------------------------------
diff --git a/tests/test-rebase-conflicts.t b/tests/test-rebase-conflicts.t
--- a/tests/test-rebase-conflicts.t
+++ b/tests/test-rebase-conflicts.t
@@ -322,6 +322,7 @@ 
   bundle2-input-part: total payload size 24
   bundle2-input-bundle: 3 parts total
   truncating cache/rbc-revs-v1 to 72
+  truncating cache/topic-revs-v1 to 72
   added 2 changesets with 2 changes to 1 files
   updating the branch cache
   invalid branch cache (served): tip differs
diff --git a/tests/test-push-http.t b/tests/test-push-http.t
--- a/tests/test-push-http.t
+++ b/tests/test-push-http.t
@@ -117,6 +117,7 @@ 
   remote: adding manifests
   remote: adding file changes
   remote: adding a revisions
+  remote: truncating cache/topic-revs-v1 to 8
   remote: updating the branch cache
   remote: added 1 changesets with 1 changes to 1 files
   remote: running hook txnclose-phase.test: sh $TESTTMP/hook.sh
diff --git a/tests/test-mq-symlinks.t b/tests/test-mq-symlinks.t
--- a/tests/test-mq-symlinks.t
+++ b/tests/test-mq-symlinks.t
@@ -51,6 +51,7 @@ 
   a
   committing manifest
   committing changelog
+  truncating cache/topic-revs-v1 to 16
   updating the branch cache
   now at: updatelink
   $ readlink.py a
diff --git a/tests/test-keyword.t b/tests/test-keyword.t
--- a/tests/test-keyword.t
+++ b/tests/test-keyword.t
@@ -656,6 +656,7 @@ 
   committing manifest
   committing changelog
   overwriting c expanding keywords
+  truncating cache/topic-revs-v1 to 16
   updating the branch cache
   committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
   $ cat a c
@@ -830,6 +831,7 @@ 
   committing manifest
   committing changelog
   overwriting a expanding keywords
+  truncating cache/topic-revs-v1 to 16
   updating the branch cache
   committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
   $ rm log
@@ -996,6 +998,7 @@ 
   committing manifest
   committing changelog
   overwriting x/a expanding keywords
+  truncating cache/topic-revs-v1 to 24
   updating the branch cache
   committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
   $ cat a
diff --git a/tests/test-inherit-mode.t b/tests/test-inherit-mode.t
--- a/tests/test-inherit-mode.t
+++ b/tests/test-inherit-mode.t
@@ -73,6 +73,8 @@ 
   00660 ./.hg/cache/branch2-served
   00660 ./.hg/cache/rbc-names-v1
   00660 ./.hg/cache/rbc-revs-v1
+  00660 ./.hg/cache/topic-names-v1
+  00660 ./.hg/cache/topic-revs-v1
   00660 ./.hg/dirstate
   00660 ./.hg/fsmonitor.state (fsmonitor !)
   00660 ./.hg/last-message.txt
@@ -136,6 +138,8 @@ 
   00660 ../push/.hg/cache/branch2-base
   00660 ../push/.hg/cache/rbc-names-v1
   00660 ../push/.hg/cache/rbc-revs-v1
+  00660 ../push/.hg/cache/topic-names-v1
+  00660 ../push/.hg/cache/topic-revs-v1
   00660 ../push/.hg/dirstate
   00660 ../push/.hg/requires
   00770 ../push/.hg/store/
diff --git a/tests/test-http.t b/tests/test-http.t
--- a/tests/test-http.t
+++ b/tests/test-http.t
@@ -29,7 +29,7 @@ 
 #if no-reposimplestore
   $ hg clone --stream http://localhost:$HGPORT/ copy 2>&1
   streaming all changes
-  9 files to transfer, 715 bytes of data
+  11 files to transfer, 730 bytes of data
   transferred * bytes in * seconds (*/sec) (glob)
   updating to branch default
   4 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -261,7 +261,7 @@ 
 #if no-reposimplestore
   $ hg clone http://user:pass@localhost:$HGPORT2/ dest 2>&1
   streaming all changes
-  10 files to transfer, 1.01 KB of data
+  12 files to transfer, 1.03 KB of data
   transferred * KB in * seconds (*/sec) (glob)
   updating to branch default
   5 files updated, 0 files merged, 0 files removed, 0 files unresolved
diff --git a/tests/test-http-proxy.t b/tests/test-http-proxy.t
--- a/tests/test-http-proxy.t
+++ b/tests/test-http-proxy.t
@@ -16,7 +16,7 @@ 
 
   $ http_proxy=http://localhost:$HGPORT1/ hg --config http_proxy.always=True clone --stream http://localhost:$HGPORT/ b
   streaming all changes
-  6 files to transfer, 412 bytes of data (reporevlogstore !)
+  8 files to transfer, 427 bytes of data (reporevlogstore !)
   4 files to transfer, 330 bytes of data (reposimplestore !)
   transferred * bytes in * seconds (*/sec) (glob)
   updating to branch default
diff --git a/tests/test-hardlinks.t b/tests/test-hardlinks.t
--- a/tests/test-hardlinks.t
+++ b/tests/test-hardlinks.t
@@ -241,6 +241,8 @@ 
   2 r4/.hg/cache/branch2-served
   2 r4/.hg/cache/rbc-names-v1
   2 r4/.hg/cache/rbc-revs-v1
+  2 r4/.hg/cache/topic-names-v1
+  2 r4/.hg/cache/topic-revs-v1
   2 r4/.hg/dirstate
   2 r4/.hg/fsmonitor.state (fsmonitor !)
   2 r4/.hg/hgrc
@@ -292,6 +294,8 @@ 
   2 r4/.hg/cache/branch2-served
   2 r4/.hg/cache/rbc-names-v1
   2 r4/.hg/cache/rbc-revs-v1
+  2 r4/.hg/cache/topic-names-v1
+  2 r4/.hg/cache/topic-revs-v1
   1 r4/.hg/dirstate
   1 r4/.hg/fsmonitor.state (fsmonitor !)
   2 r4/.hg/hgrc
diff --git a/tests/test-fncache.t b/tests/test-fncache.t
--- a/tests/test-fncache.t
+++ b/tests/test-fncache.t
@@ -104,6 +104,8 @@ 
   .hg/cache/branch2-served
   .hg/cache/rbc-names-v1
   .hg/cache/rbc-revs-v1
+  .hg/cache/topic-names-v1
+  .hg/cache/topic-revs-v1
   .hg/data
   .hg/data/tst.d.hg
   .hg/data/tst.d.hg/foo.i
@@ -142,6 +144,8 @@ 
   .hg/cache/branch2-served
   .hg/cache/rbc-names-v1
   .hg/cache/rbc-revs-v1
+  .hg/cache/topic-names-v1
+  .hg/cache/topic-revs-v1
   .hg/dirstate
   .hg/fsmonitor.state (fsmonitor !)
   .hg/last-message.txt
diff --git a/tests/test-debugcommands.t b/tests/test-debugcommands.t
--- a/tests/test-debugcommands.t
+++ b/tests/test-debugcommands.t
@@ -541,6 +541,8 @@ 
   $ hg debugupdatecaches --debug
   updating the branch cache
   $ ls -r .hg/cache/*
+  .hg/cache/topic-revs-v1
+  .hg/cache/topic-names-v1
   .hg/cache/tags2-served
   .hg/cache/tags2
   .hg/cache/rbc-revs-v1
diff --git a/tests/test-clonebundles.t b/tests/test-clonebundles.t
--- a/tests/test-clonebundles.t
+++ b/tests/test-clonebundles.t
@@ -464,8 +464,8 @@ 
   no compatible clone bundles available on server; falling back to regular clone
   (you may want to report this to the server operator)
   streaming all changes
-  9 files to transfer, 816 bytes of data
-  transferred 816 bytes in * seconds (*) (glob)
+  11 files to transfer, 839 bytes of data
+  transferred 839 bytes in * seconds (* */sec) (glob)
 
 A manifest with a stream clone but no BUNDLESPEC
 
@@ -477,8 +477,8 @@ 
   no compatible clone bundles available on server; falling back to regular clone
   (you may want to report this to the server operator)
   streaming all changes
-  9 files to transfer, 816 bytes of data
-  transferred 816 bytes in * seconds (*) (glob)
+  11 files to transfer, 839 bytes of data
+  transferred 839 bytes in * seconds (* */sec) (glob)
 
 A manifest with a gzip bundle and a stream clone
 
@@ -521,8 +521,8 @@ 
   no compatible clone bundles available on server; falling back to regular clone
   (you may want to report this to the server operator)
   streaming all changes
-  9 files to transfer, 816 bytes of data
-  transferred 816 bytes in * seconds (*) (glob)
+  11 files to transfer, 839 bytes of data
+  transferred 839 bytes in * seconds (* */sec) (glob)
 
 Test clone bundle retrieved through bundle2
 
diff --git a/tests/test-clone.t b/tests/test-clone.t
--- a/tests/test-clone.t
+++ b/tests/test-clone.t
@@ -45,6 +45,8 @@ 
   branch2-served
   rbc-names-v1
   rbc-revs-v1
+  topic-names-v1
+  topic-revs-v1
 
 Default operation:
 
@@ -59,6 +61,8 @@ 
   branch2-served
   rbc-names-v1
   rbc-revs-v1
+  topic-names-v1
+  topic-revs-v1
 
   $ cat a
   a
@@ -130,6 +134,8 @@ 
   branch2-served
   rbc-names-v1
   rbc-revs-v1
+  topic-names-v1
+  topic-revs-v1
 
   $ cat a 2>/dev/null || echo "a not present"
   a not present
diff --git a/tests/test-clone-uncompressed.t b/tests/test-clone-uncompressed.t
--- a/tests/test-clone-uncompressed.t
+++ b/tests/test-clone-uncompressed.t
@@ -188,13 +188,15 @@ 
 #if stream-bundle2
   $ hg clone --stream -U http://localhost:$HGPORT clone1
   streaming all changes
-  1030 files to transfer, 96.5 KB of data
+  1032 files to transfer, 96.5 KB of data
   transferred 96.5 KB in * seconds (* */sec) (glob)
 
   $ ls -1 clone1/.hg/cache
   branch2-served
   rbc-names-v1
   rbc-revs-v1
+  topic-names-v1
+  topic-revs-v1
 #endif
 
 getbundle requests with stream=1 are uncompressed
@@ -205,11 +207,11 @@ 
   
 
   $ f --size --hex --bytes 256 body
-  body: size=112262
+  body: size=112318
   0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
   0010: 7f 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......|
   0020: 05 09 04 0c 44 62 79 74 65 63 6f 75 6e 74 39 38 |....Dbytecount98|
-  0030: 37 37 35 66 69 6c 65 63 6f 75 6e 74 31 30 33 30 |775filecount1030|
+  0030: 37 39 38 66 69 6c 65 63 6f 75 6e 74 31 30 33 32 |798filecount1032|
   0040: 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 65 |requirementsdote|
   0050: 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 25 |ncode%2Cfncache%|
   0060: 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 32 |2Cgeneraldelta%2|
@@ -236,7 +238,7 @@ 
 #if stream-bundle2
   $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
   streaming all changes
-  1030 files to transfer, 96.5 KB of data
+  1032 files to transfer, 96.5 KB of data
   transferred 96.5 KB in * seconds (* */sec) (glob)
 #endif
 
@@ -278,12 +280,12 @@ 
   bundle2-input-bundle: with-transaction
   bundle2-input-part: "stream2" (params: 3 mandatory) supported
   applying stream bundle
-  1030 files to transfer, 96.5 KB of data
+  1032 files to transfer, 96.5 KB of data
   starting 4 threads for background file closing
   starting 4 threads for background file closing
   updating the branch cache
   transferred 96.5 KB in * seconds (* */sec) (glob)
-  bundle2-input-part: total payload size 112094
+  bundle2-input-part: total payload size 112150
   bundle2-input-part: "listkeys" (params: 1 mandatory) supported
   bundle2-input-bundle: 2 parts total
   checking for updated bookmarks
@@ -322,7 +324,7 @@ 
 #if stream-bundle2
   $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
   streaming all changes
-  1030 files to transfer, 96.5 KB of data
+  1032 files to transfer, 96.5 KB of data
   transferred 96.5 KB in * seconds (* */sec) (glob)
 #endif
 
@@ -439,8 +441,8 @@ 
 #if stream-bundle2
   $ hg clone --stream http://localhost:$HGPORT with-bookmarks
   streaming all changes
-  1033 files to transfer, 96.6 KB of data
-  transferred 96.6 KB in * seconds (* */sec) (glob)
+  1035 files to transfer, 96.7 KB of data
+  transferred 96.7 KB in * seconds (* */sec) (glob)
   updating to branch default
   1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
 #endif
@@ -469,8 +471,8 @@ 
 #if stream-bundle2
   $ hg clone --stream http://localhost:$HGPORT phase-publish
   streaming all changes
-  1033 files to transfer, 96.6 KB of data
-  transferred 96.6 KB in * seconds (* */sec) (glob)
+  1035 files to transfer, 96.7 KB of data
+  transferred 96.7 KB in * seconds (* */sec) (glob)
   updating to branch default
   1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
 #endif
@@ -508,7 +510,7 @@ 
 #if stream-bundle2
   $ hg clone --stream http://localhost:$HGPORT phase-no-publish
   streaming all changes
-  1034 files to transfer, 96.7 KB of data
+  1036 files to transfer, 96.7 KB of data
   transferred 96.7 KB in * seconds (* */sec) (glob)
   updating to branch default
   1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -553,7 +555,7 @@ 
 
   $ hg clone -U --stream http://localhost:$HGPORT with-obsolescence
   streaming all changes
-  1035 files to transfer, 97.1 KB of data
+  1037 files to transfer, 97.1 KB of data
   transferred 97.1 KB in * seconds (* */sec) (glob)
   $ hg -R with-obsolescence log -T '{rev}: {phase}\n'
   1: draft
diff --git a/tests/test-acl.t b/tests/test-acl.t
--- a/tests/test-acl.t
+++ b/tests/test-acl.t
@@ -205,6 +205,7 @@ 
   bundle2-input-part: total payload size 24
   bundle2-input-bundle: 5 parts total
   truncating cache/rbc-revs-v1 to 8
+  truncating cache/topic-revs-v1 to 8
   updating the branch cache
   added 3 changesets with 3 changes to 3 files
   bundle2-output-bundle: "HG20", 1 parts total
@@ -285,6 +286,7 @@ 
   bundle2-input-part: total payload size 24
   bundle2-input-bundle: 5 parts total
   truncating cache/rbc-revs-v1 to 8
+  truncating cache/topic-revs-v1 to 8
   updating the branch cache
   added 3 changesets with 3 changes to 3 files
   bundle2-output-bundle: "HG20", 1 parts total
@@ -809,6 +811,7 @@ 
   acl: bookmark access granted: "ef1ea85a6374b77d6da9dcda9541f498f2d17df7" on bookmark "moving-bookmark"
   bundle2-input-bundle: 7 parts total
   truncating cache/rbc-revs-v1 to 8
+  truncating cache/topic-revs-v1 to 8
   updating the branch cache
   added 1 changesets with 1 changes to 1 files
   bundle2-output-bundle: "HG20", 1 parts total
@@ -985,6 +988,7 @@ 
   bundle2-input-part: total payload size 24
   bundle2-input-bundle: 5 parts total
   truncating cache/rbc-revs-v1 to 8
+  truncating cache/topic-revs-v1 to 8
   updating the branch cache
   added 3 changesets with 3 changes to 3 files
   bundle2-output-bundle: "HG20", 1 parts total
@@ -1322,6 +1326,7 @@ 
   bundle2-input-part: total payload size 24
   bundle2-input-bundle: 5 parts total
   truncating cache/rbc-revs-v1 to 8
+  truncating cache/topic-revs-v1 to 8
   updating the branch cache
   added 3 changesets with 3 changes to 3 files
   bundle2-output-bundle: "HG20", 1 parts total
@@ -1413,6 +1418,7 @@ 
   bundle2-input-part: total payload size 24
   bundle2-input-bundle: 5 parts total
   truncating cache/rbc-revs-v1 to 8
+  truncating cache/topic-revs-v1 to 8
   updating the branch cache
   added 3 changesets with 3 changes to 3 files
   bundle2-output-bundle: "HG20", 1 parts total
@@ -1583,6 +1589,7 @@ 
   bundle2-input-part: total payload size 24
   bundle2-input-bundle: 5 parts total
   truncating cache/rbc-revs-v1 to 8
+  truncating cache/topic-revs-v1 to 8
   updating the branch cache
   added 3 changesets with 3 changes to 3 files
   bundle2-output-bundle: "HG20", 1 parts total
@@ -2100,6 +2107,7 @@ 
   bundle2-input-part: "phase-heads" supported
   bundle2-input-part: total payload size 48
   bundle2-input-bundle: 5 parts total
+  truncating cache/topic-revs-v1 to 24
   updating the branch cache
   added 4 changesets with 4 changes to 4 files (+1 heads)
   bundle2-output-bundle: "HG20", 1 parts total
@@ -2191,6 +2199,7 @@ 
   bundle2-input-part: "phase-heads" supported
   bundle2-input-part: total payload size 48
   bundle2-input-bundle: 5 parts total
+  truncating cache/topic-revs-v1 to 24
   updating the branch cache
   added 4 changesets with 4 changes to 4 files (+1 heads)
   bundle2-output-bundle: "HG20", 1 parts total
@@ -2354,6 +2363,7 @@ 
   bundle2-input-part: "phase-heads" supported
   bundle2-input-part: total payload size 48
   bundle2-input-bundle: 5 parts total
+  truncating cache/topic-revs-v1 to 24
   updating the branch cache
   added 4 changesets with 4 changes to 4 files (+1 heads)
   bundle2-output-bundle: "HG20", 1 parts total
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1229,6 +1229,7 @@ 
 
         self._branchcaches = branchmap.BranchMapCache()
         self._revbranchcache = None
+        self._topicbranchcache = None
         self._filterpats = {}
         self._datafilters = {}
         self._transref = self._lockref = self._wlockref = None
@@ -1344,6 +1345,8 @@ 
     def _writecaches(self):
         if self._revbranchcache:
             self._revbranchcache.write()
+        if self._topicbranchcache:
+            self._topicbranchcache.write()
 
     def _restrictcapabilities(self, caps):
         if self.ui.configbool(b'experimental', b'bundle2-advertise'):
@@ -1942,6 +1945,12 @@ 
             self._revbranchcache = branchmap.revbranchcache(self.unfiltered())
         return self._revbranchcache
 
+    @unfilteredmethod
+    def topicbranchcache(self):
+        if not self._topicbranchcache:
+            self._topicbranchcache = branchmap.topicbranchcache(self.unfiltered())
+        return self._topicbranchcache
+
     def branchtip(self, branch, ignoremissing=False):
         """return the tip node for a given branch
 
@@ -2583,9 +2592,12 @@ 
             self.manifestlog.update_caches(transaction=tr)
 
             rbc = unfi.revbranchcache()
+            tbc = unfi.topicbranchcache()
             for r in unfi.changelog:
                 rbc.branchinfo(r)
+                tbc.branchinfo(r)
             rbc.write()
+            tbc.write()
 
             # ensure the working copy parents are in the manifestfulltextcache
             for ctx in self[b'.'].parents():
diff --git a/mercurial/interfaces/repository.py b/mercurial/interfaces/repository.py
--- a/mercurial/interfaces/repository.py
+++ b/mercurial/interfaces/repository.py
@@ -1641,6 +1641,9 @@ 
     def revbranchcache():
         pass
 
+    def topicbranchcache():
+        pass
+
     def branchtip(branchtip, ignoremissing=False):
         """Return the tip node for a given branch."""
 
diff --git a/mercurial/exchangev2.py b/mercurial/exchangev2.py
--- a/mercurial/exchangev2.py
+++ b/mercurial/exchangev2.py
@@ -372,6 +372,7 @@ 
         manifestnodes[cl.rev(node)] = revision.manifest
 
         repo.revbranchcache().setdata(node, revision.extra)
+        repo.topicbranchcache().setdata(node, revision.extra)
 
     nodesbyphase = {phase: set() for phase in phases.phasenames.values()}
     remotebookmarks = {}
diff --git a/mercurial/commit.py b/mercurial/commit.py
--- a/mercurial/commit.py
+++ b/mercurial/commit.py
@@ -97,6 +97,7 @@ 
             extra,
         )
         repo.revbranchcache().setdata(n, extra)
+        repo.topicbranchcache().setdata(n, extra)
 
         xp1, xp2 = p1.hex(), p2 and p2.hex() or b''
         repo.hook(
diff --git a/mercurial/changelog.py b/mercurial/changelog.py
--- a/mercurial/changelog.py
+++ b/mercurial/changelog.py
@@ -596,14 +596,6 @@ 
             text, transaction, len(self), p1, p2, sidedata=sidedata, flags=flags
         )
 
-    def branchinfo(self, rev):
-        """return the branch name and open/close state of a revision
-
-        This function exists because creating a changectx object
-        just to access this is costly."""
-        extra = self.read(rev)[5]
-        return encoding.tolocal(extra.get(b"branch")), b'close' in extra
-
     def _nodeduplicatecallback(self, transaction, node):
         # keep track of revisions that got "re-added", eg: unbunde of know rev.
         #
diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -326,6 +326,7 @@ 
                 ctx = cl.changelogrevision(node)
                 efilesset.update(ctx.files)
                 repo.revbranchcache().setdata(node, ctx.extra)
+                repo.topicbranchcache().setdata(node, ctx.extra)
 
             self.changelogheader()
             deltas = self.deltaiter()
diff --git a/mercurial/cacheutil.py b/mercurial/cacheutil.py
--- a/mercurial/cacheutil.py
+++ b/mercurial/cacheutil.py
@@ -18,5 +18,6 @@ 
     cachefiles += [b'rbc-names-v1', b'rbc-revs-v1']
     cachefiles += [b'tags2']
     cachefiles += [b'tags2-%s' % f for f in repoview.filtertable]
+    cachefiles += [b'topic-names-v1', b'topic-revs-v1']
     cachefiles += [b'hgtagsfnodes1']
     return cachefiles
diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -115,7 +115,7 @@ 
         """
         cl = repo.changelog
         clrev = cl.rev
-        clbranchinfo = cl.branchinfo
+        clbranchinfo = repo.revbranchcache().branchinfo
         rbheads = []
         closed = set()
         for bheads in pycompat.itervalues(remotebranchmap):
@@ -512,8 +512,6 @@ 
 # Revision branch info cache
 
 _rbcversion = b'-v1'
-_rbcnames = b'rbc-names' + _rbcversion
-_rbcrevs = b'rbc-revs' + _rbcversion
 # [4 byte hash prefix][4 byte branch name number with sign bit indicating open]
 _rbcrecfmt = b'>4sI'
 _rbcrecsize = calcsize(_rbcrecfmt)
@@ -546,6 +544,10 @@ 
     and will grow with it but be 1/8th of its size.
     """
 
+    names_cache = b'rbc-names' + _rbcversion
+    revisions_cache = b'rbc-revs' + _rbcversion
+    phase_name = b'write-revbranchcache'
+
     def __init__(self, repo, readonly=True):
         assert repo.filtername is None
         self._repo = repo
@@ -553,7 +555,7 @@ 
         self._rbcrevs = bytearray()
         self._rbcsnameslen = 0  # length of names read at _rbcsnameslen
         try:
-            bndata = repo.cachevfs.read(_rbcnames)
+            bndata = repo.cachevfs.read(self.names_cache)
             self._rbcsnameslen = len(bndata)  # for verification before writing
             if bndata:
                 self._names = [
@@ -566,7 +568,7 @@ 
 
         if self._names:
             try:
-                data = repo.cachevfs.read(_rbcrevs)
+                data = repo.cachevfs.read(self.revisions_cache)
                 self._rbcrevs[:] = data
             except (IOError, OSError) as inst:
                 repo.ui.debug(
@@ -594,6 +596,11 @@ 
     def _namesreverse(self):
         return {b: r for r, b in enumerate(self._names)}
 
+    def getbranchinfo(self, extra=None):
+        if extra is None:
+            extra = {}
+        return encoding.tolocal(extra.get(b"branch", b"default")), b'close' in extra
+
     def branchinfo(self, rev):
         """Return branch name and close flag for rev, using and updating
         persistent cache."""
@@ -602,7 +609,7 @@ 
 
         # avoid negative index, changelog.read(nullrev) is fast without cache
         if rev == nullrev:
-            return changelog.branchinfo(rev)
+            return self.getbranchinfo()
 
         # if requested rev isn't allocated, grow and cache the rev info
         if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
@@ -644,7 +651,7 @@ 
     def _branchinfo(self, rev):
         """Retrieve branch info from changelog and update _rbcrevs"""
         changelog = self._repo.changelog
-        b, close = changelog.branchinfo(rev)
+        b, close = self.getbranchinfo(changelog.read(rev)[5])
         if b in self._namesreverse:
             branchidx = self._namesreverse[b]
         else:
@@ -694,7 +701,7 @@ 
 
         tr = self._repo.currenttransaction()
         if tr:
-            tr.addfinalize(b'write-revbranchcache', self.write)
+            tr.addfinalize(self.phase_name, self.write)
 
     def write(self, tr=None):
         """Save branch cache if it is dirty."""
@@ -728,18 +735,18 @@ 
     def _writenames(self, repo):
         """ write the new branch names to revbranchcache """
         if self._rbcnamescount != 0:
-            f = repo.cachevfs.open(_rbcnames, b'ab')
+            f = repo.cachevfs.open(self.names_cache, b'ab')
             if f.tell() == self._rbcsnameslen:
                 f.write(b'\0')
             else:
                 f.close()
-                repo.ui.debug(b"%s changed - rewriting it\n" % _rbcnames)
+                repo.ui.debug(b"%s changed - rewriting it\n" % self.names_cache)
                 self._rbcnamescount = 0
                 self._rbcrevslen = 0
         if self._rbcnamescount == 0:
             # before rewriting names, make sure references are removed
-            repo.cachevfs.unlinkpath(_rbcrevs, ignoremissing=True)
-            f = repo.cachevfs.open(_rbcnames, b'wb')
+            repo.cachevfs.unlinkpath(self.revisions_cache, ignoremissing=True)
+            f = repo.cachevfs.open(self.names_cache, b'wb')
         f.write(
             b'\0'.join(
                 encoding.fromlocal(b)
@@ -753,10 +760,10 @@ 
     def _writerevs(self, repo, start):
         """ write the new revs to revbranchcache """
         revs = min(len(repo.changelog), len(self._rbcrevs) // _rbcrecsize)
-        with repo.cachevfs.open(_rbcrevs, b'ab') as f:
+        with repo.cachevfs.open(self.revisions_cache, b'ab') as f:
             if f.tell() != start:
                 repo.ui.debug(
-                    b"truncating cache/%s to %d\n" % (_rbcrevs, start)
+                    b"truncating cache/%s to %d\n" % (self.revisions_cache, start)
                 )
                 f.seek(start)
                 if f.tell() != start:
@@ -766,3 +773,13 @@ 
             end = revs * _rbcrecsize
             f.write(self._rbcrevs[start:end])
         self._rbcrevslen = revs
+
+class topicbranchcache(revbranchcache):
+    names_cache = b'topic-names' + _rbcversion
+    revisions_cache = b'topic-revs' + _rbcversion
+    phase_name = b'write-topicbranchcache'
+
+    def getbranchinfo(self, extra=None):
+        if extra is None:
+            extra = {}
+        return encoding.tolocal(extra.get(b"topic", b"")), False