diff --git a/.pytype/pyi/hgext/phabricator.pyi b/.pytype/pyi/hgext/phabricator.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvaGdleHQvcGhhYnJpY2F0b3IucHlp..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvaGdleHQvcGhhYnJpY2F0b3IucHlp 100644
--- a/.pytype/pyi/hgext/phabricator.pyi
+++ b/.pytype/pyi/hgext/phabricator.pyi
@@ -25,7 +25,7 @@
 _elements: Dict[bytes, Tuple[int, Optional[bytes], Optional[Tuple[Union[bytes, int], ...]], Optional[Tuple[bytes, int]], None]]
 _knownstatusnames: Set[bytes]
 _loadhgrc: Any
-_metanamemap: util.sortdict[bytes, bytes]
+_metanamemap: util.sortdict
 cmdtable: dict
 colortable: Dict[bytes, bytes]
 command: mercurial.registrar.command
diff --git a/.pytype/pyi/mercurial/bundle2.pyi b/.pytype/pyi/mercurial/bundle2.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL2J1bmRsZTIucHlp..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL2J1bmRsZTIucHlp 100644
--- a/.pytype/pyi/mercurial/bundle2.pyi
+++ b/.pytype/pyi/mercurial/bundle2.pyi
@@ -184,7 +184,7 @@
     ui: Any
     def __init__(self, ui, fp) -> None: ...
     def _forwardchunks(self) -> Generator[Any, Any, nothing]: ...
-    def _processallparams(self, paramsblock: bytes) -> util.sortdict[bytes, bytes]: ...
+    def _processallparams(self, paramsblock) -> util.sortdict: ...
     def _processparam(self, name, value) -> None: ...
     def _readpartheader(self) -> Any: ...
     def close(self) -> Any: ...
diff --git a/.pytype/pyi/mercurial/hgweb/webutil.pyi b/.pytype/pyi/mercurial/hgweb/webutil.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL2hnd2ViL3dlYnV0aWwucHlp..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL2hnd2ViL3dlYnV0aWwucHlp 100644
--- a/.pytype/pyi/mercurial/hgweb/webutil.pyi
+++ b/.pytype/pyi/mercurial/hgweb/webutil.pyi
@@ -5,9 +5,8 @@
 import mercurial.hgweb.common
 import os
 import re
-import typing
 from mercurial import context, diffutil, error, match, mdiff, obsutil, patch, pathutil, pycompat, scmutil, templatefilters, templatekw, templateutil, ui as uimod, util
 from mercurial.utils import stringutil
 from typing import Any, Callable, Dict, Generator, List, Never, Optional, Tuple, Type, TypeVar, Union
 from typing_extensions import Buffer
 
@@ -9,10 +8,8 @@
 from mercurial import context, diffutil, error, match, mdiff, obsutil, patch, pathutil, pycompat, scmutil, templatefilters, templatekw, templateutil, ui as uimod, util
 from mercurial.utils import stringutil
 from typing import Any, Callable, Dict, Generator, List, Never, Optional, Tuple, Type, TypeVar, Union
 from typing_extensions import Buffer
 
-ArchiveSpecT = Tuple[bytes, bytes, bytes, Optional[bytes]]
-
 ErrorResponse: Type[mercurial.hgweb.common.ErrorResponse]
 HTTP_BAD_REQUEST: int
 HTTP_NOT_FOUND: int
@@ -16,7 +13,7 @@
 ErrorResponse: Type[mercurial.hgweb.common.ErrorResponse]
 HTTP_BAD_REQUEST: int
 HTTP_NOT_FOUND: int
-archivespecs: util.sortdict[bytes, Tuple[bytes, bytes, bytes, Optional[bytes]]]
+archivespecs: util.sortdict
 
 _T0 = TypeVar('_T0')
 _T1 = TypeVar('_T1')
diff --git a/.pytype/pyi/mercurial/interfaces/_basetypes.pyi b/.pytype/pyi/mercurial/interfaces/_basetypes.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL2ludGVyZmFjZXMvX2Jhc2V0eXBlcy5weWk=..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL2ludGVyZmFjZXMvX2Jhc2V0eXBlcy5weWk= 100644
--- a/.pytype/pyi/mercurial/interfaces/_basetypes.pyi
+++ b/.pytype/pyi/mercurial/interfaces/_basetypes.pyi
@@ -1,7 +1,7 @@
 # (generated with --quick)
 
-from typing import Type
+from typing import Any, Type
 
 CallbackCategoryT: Type[bytes]
 FsPathT: Type[bytes]
 HgPathT: Type[bytes]
@@ -4,6 +4,8 @@
 
 CallbackCategoryT: Type[bytes]
 FsPathT: Type[bytes]
 HgPathT: Type[bytes]
+RepoT: Any
+UiT: Any
 UserMsgT: Type[bytes]
 VfsKeyT: Type[bytes]
@@ -8,2 +10,3 @@
 UserMsgT: Type[bytes]
 VfsKeyT: Type[bytes]
+VfsT: Any
diff --git a/.pytype/pyi/mercurial/interfaces/repository.pyi b/.pytype/pyi/mercurial/interfaces/repository.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL2ludGVyZmFjZXMvcmVwb3NpdG9yeS5weWk=..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL2ludGVyZmFjZXMvcmVwb3NpdG9yeS5weWk= 100644
--- a/.pytype/pyi/mercurial/interfaces/repository.pyi
+++ b/.pytype/pyi/mercurial/interfaces/repository.pyi
@@ -3,9 +3,8 @@
 import abc
 import builtins
 import typing
-from mercurial import error, pathutil, util
-from mercurial.interfaces import dirstate as intdirstate, matcher
-from mercurial.utils import urlutil
+from mercurial import error
+from mercurial.interfaces import dirstate as intdirstate, matcher, misc
 from typing import Any, Callable, Collection, Dict, Iterable, Iterator, List, Mapping, Optional, Protocol, Set, Tuple, Type, TypeVar, Union, overload
 
 CACHES_ALL: Set[bytes]
@@ -44,7 +43,7 @@
 
 class _ipeerconnection(Protocol):
     __doc__: str
-    path: Optional[urlutil.path]
+    path: Optional[misc.IPath]
     ui: Any
     @abstractmethod
     def canpush(self) -> Any: ...
@@ -180,7 +179,7 @@
     obsstore: Any
     origroot: bytes
     path: bytes
-    prepushoutgoinghooks: util.hooks
+    prepushoutgoinghooks: misc.IHooks
     requirements: builtins.set[bytes]
     root: bytes
     sharedpath: bytes
@@ -372,7 +371,7 @@
     @abstractmethod
     def diff(self, other, match: Optional[matcher.IMatcher] = ..., clean: bool = ...) -> Dict[bytes, Optional[Tuple[Tuple[Optional[bytes], bytes], Tuple[Optional[bytes], bytes]]]]: ...
     @abstractmethod
-    def dirs(self) -> Any: ...
+    def dirs(self) -> misc.IDirs: ...
     @abstractmethod
     def fastdelta(self, base: bytes, changes: Iterable[Tuple[bytes, bool]]) -> Tuple[Union[bytearray, bytes, memoryview], Union[bytearray, bytes, memoryview]]: ...
     @abstractmethod
@@ -635,5 +634,5 @@
 class peer(_ipeerconnection, ipeercapabilities, ipeerrequests):
     __doc__: str
     limitedarguments: bool
-    path: Optional[urlutil.path]
+    path: Optional[misc.IPath]
     ui: Any
@@ -639,5 +638,5 @@
     ui: Any
-    def __init__(self, ui, path: Optional[urlutil.path] = ..., remotehidden: bool = ...) -> None: ...
+    def __init__(self, ui, path: Optional[misc.IPath] = ..., remotehidden: bool = ...) -> None: ...
     def capable(self, name: bytes) -> Union[bool, bytes]: ...
     def requirecap(self, name: bytes, purpose: bytes) -> None: ...
 
diff --git a/.pytype/pyi/mercurial/interfaces/types.pyi b/.pytype/pyi/mercurial/interfaces/types.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL2ludGVyZmFjZXMvdHlwZXMucHlp..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL2ludGVyZmFjZXMvdHlwZXMucHlp 100644
--- a/.pytype/pyi/mercurial/interfaces/types.pyi
+++ b/.pytype/pyi/mercurial/interfaces/types.pyi
@@ -1,9 +1,9 @@
 # (generated with --quick)
 
 from mercurial.interfaces import matcher, transaction
-from typing import Type
+from typing import Any, Type
 
 CallbackCategoryT: Type[bytes]
 FsPathT: Type[bytes]
 HgPathT: Type[bytes]
 MatcherT: Type[matcher.IMatcher]
@@ -5,6 +5,7 @@
 
 CallbackCategoryT: Type[bytes]
 FsPathT: Type[bytes]
 HgPathT: Type[bytes]
 MatcherT: Type[matcher.IMatcher]
+RepoT: Any
 TransactionT: Type[transaction.ITransaction]
@@ -10,3 +11,4 @@
 TransactionT: Type[transaction.ITransaction]
+UiT: Any
 UserMsgT: Type[bytes]
 VfsKeyT: Type[bytes]
@@ -11,2 +13,3 @@
 UserMsgT: Type[bytes]
 VfsKeyT: Type[bytes]
+VfsT: Any
diff --git a/.pytype/pyi/mercurial/namespaces.pyi b/.pytype/pyi/mercurial/namespaces.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL25hbWVzcGFjZXMucHlp..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL25hbWVzcGFjZXMucHlp 100644
--- a/.pytype/pyi/mercurial/namespaces.pyi
+++ b/.pytype/pyi/mercurial/namespaces.pyi
@@ -25,7 +25,7 @@
 
 class namespaces:
     __doc__: str
-    _names: util.sortdict[nothing, nothing]
+    _names: util.sortdict
     _names_version: int
     def __getitem__(self, namespace) -> Any: ...
     def __init__(self) -> None: ...
diff --git a/.pytype/pyi/mercurial/parser.pyi b/.pytype/pyi/mercurial/parser.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3BhcnNlci5weWk=..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3BhcnNlci5weWk= 100644
--- a/.pytype/pyi/mercurial/parser.pyi
+++ b/.pytype/pyi/mercurial/parser.pyi
@@ -63,7 +63,7 @@
 def _buildtree(template, placeholder, replstack) -> Any: ...
 def _matchtree(pattern, tree, placeholder, incompletenodes, matches) -> bool: ...
 def _prettyformat(tree, leafnodes, level, lines) -> None: ...
-def buildargsdict(trees, funcname, argspec, keyvaluenode, keynode) -> util.sortdict[nothing, nothing]: ...
+def buildargsdict(trees, funcname, argspec, keyvaluenode, keynode) -> util.sortdict: ...
 def buildtree(template, placeholder, *repls) -> Any: ...
 def matchtree(pattern, tree: _T1, placeholder = ..., incompletenodes = ...) -> Optional[List[_T1]]: ...
 def parseerrordetail(inst) -> Any: ...
diff --git a/.pytype/pyi/mercurial/patch.pyi b/.pytype/pyi/mercurial/patch.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3BhdGNoLnB5aQ==..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3BhdGNoLnB5aQ== 100644
--- a/.pytype/pyi/mercurial/patch.pyi
+++ b/.pytype/pyi/mercurial/patch.pyi
@@ -3,6 +3,7 @@
 import collections
 import contextlib
 import copy
+import email
 import io
 import mercurial.node
 import mercurial.ui
diff --git a/.pytype/pyi/mercurial/pathutil.pyi b/.pytype/pyi/mercurial/pathutil.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3BhdGh1dGlsLnB5aQ==..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3BhdGh1dGlsLnB5aQ== 100644
--- a/.pytype/pyi/mercurial/pathutil.pyi
+++ b/.pytype/pyi/mercurial/pathutil.pyi
@@ -6,6 +6,7 @@
 import posixpath
 import stat
 from mercurial import encoding, error, policy, pycompat, util
+from mercurial.interfaces import misc as int_misc
 from typing import Any, Callable, Dict, Iterator, Optional, Set, Union, overload
 
 dirname: Callable[[bytes], bytes]
diff --git a/.pytype/pyi/mercurial/phases.pyi b/.pytype/pyi/mercurial/phases.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3BoYXNlcy5weWk=..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3BoYXNlcy5weWk= 100644
--- a/.pytype/pyi/mercurial/phases.pyi
+++ b/.pytype/pyi/mercurial/phases.pyi
@@ -26,8 +26,8 @@
 not_public_phases: Tuple[int, int, int, int]
 nullrev: int
 phasenames: Dict[int, bytes]
-phasenumber: Dict[nothing, int]
-phasenumber2: Dict[nothing, int]
+phasenumber: Dict[bytes, int]
+phasenumber2: Dict[Union[bytes, int], int]
 public: int
 relevant_mutable_phases: Tuple[int, int]
 remotehiddenphases: Tuple[int, int, int]
diff --git a/.pytype/pyi/mercurial/pure/parsers.pyi b/.pytype/pyi/mercurial/pure/parsers.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3B1cmUvcGFyc2Vycy5weWk=..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3B1cmUvcGFyc2Vycy5weWk= 100644
--- a/.pytype/pyi/mercurial/pure/parsers.pyi
+++ b/.pytype/pyi/mercurial/pure/parsers.pyi
@@ -129,7 +129,7 @@
     _extra: List[nothing]
     _lgt: Any
     def __delitem__(self, i) -> None: ...
-    def __init__(self, data: bytes) -> None: ...
+    def __init__(self, data: bytes, uses_generaldelta = ...) -> None: ...
     def _calculate_index(self, i: int) -> int: ...
 
 class IndexObject2(IndexObject):
@@ -149,7 +149,7 @@
     _lgt: Any
     _offsets: List[int]
     def __delitem__(self, i) -> None: ...
-    def __init__(self, data, inline = ...) -> None: ...
+    def __init__(self, data, inline = ..., uses_generaldelta = ...) -> None: ...
     def _calculate_index(self, i: int) -> int: ...
     def _inline_scan(self, lgt) -> int: ...
 
@@ -172,5 +172,5 @@
 def gettype(q) -> int: ...
 def pack_dirstate(dmap, copymap, pl) -> bytes: ...
 def parse_dirstate(dmap, copymap, st) -> list: ...
-def parse_index2(data: bytes, inline, format = ...) -> Tuple[Union[IndexObject, InlinedIndexObject], Optional[Tuple[int, Union[bytearray, bytes, memoryview]]]]: ...
+def parse_index2(data: bytes, inline, uses_generaldelta, format = ...) -> Tuple[Union[IndexObject, InlinedIndexObject], Optional[Tuple[int, Union[bytearray, bytes, memoryview]]]]: ...
 def parse_index_cl_v2(data) -> Tuple[IndexChangelogV2, None]: ...
@@ -176,2 +176,2 @@
 def parse_index_cl_v2(data) -> Tuple[IndexChangelogV2, None]: ...
-def parse_index_devel_nodemap(data, inline) -> Tuple[PersistentNodeMapIndexObject, None]: ...
+def parse_index_devel_nodemap(data, inline, uses_generaldelta) -> Tuple[PersistentNodeMapIndexObject, None]: ...
diff --git a/.pytype/pyi/mercurial/revlog.pyi b/.pytype/pyi/mercurial/revlog.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3JldmxvZy5weWk=..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3JldmxvZy5weWk= 100644
--- a/.pytype/pyi/mercurial/revlog.pyi
+++ b/.pytype/pyi/mercurial/revlog.pyi
@@ -59,7 +59,7 @@
 ellipsisprocessor: Tuple[Callable[[Any, Any], Any], Callable[[Any, Any], Any], Callable[[Any, Any], Any]]
 hexdigits: bytes
 nullrev: int
-parse_index_v1_nodemap: Optional[Callable[[Any, Any], Any]]
+parse_index_v1_nodemap: Optional[Callable[[Any, Any, Any], Any]]
 parsers: Any
 rustancestor: Any
 rustdagop: Any
@@ -67,7 +67,6 @@
 sha1nodeconstants: Type[mercurial.node.sha1nodeconstants]
 wdirrev: int
 
-_T0 = TypeVar('_T0')
 _T1 = TypeVar('_T1')
 _TFeatureConfig = TypeVar('_TFeatureConfig', bound=FeatureConfig)
 _T_Config = TypeVar('_T_Config', bound=_Config)
@@ -372,8 +371,7 @@
 def ellipsisreadprocessor(rl, text: _T1) -> Tuple[_T1, bool]: ...
 def ellipsiswriteprocessor(rl, text: _T1) -> Tuple[_T1, bool]: ...
 def hex(data: Buffer, sep: Union[bytes, str] = ..., bytes_per_sep: int = ...) -> bytes: ...
-def parse_index_cl_v2(data, inline) -> Tuple[Any, Any]: ...
-def parse_index_v1(data, inline) -> Tuple[Any, Any]: ...
-def parse_index_v1_rust(data: _T0, inline, default_header) -> Tuple[Any, Optional[Tuple[int, _T0]]]: ...
-def parse_index_v2(data, inline) -> Tuple[Any, Any]: ...
+def parse_index_cl_v2(data, inline, uses_generaldelta) -> Tuple[Any, Any]: ...
+def parse_index_v1(data, inline, uses_generaldelta) -> Tuple[Any, Any]: ...
+def parse_index_v2(data, inline, uses_generaldelta) -> Tuple[Any, Any]: ...
 def short(node) -> bytes: ...
diff --git a/.pytype/pyi/mercurial/revlogutils/revlogv0.pyi b/.pytype/pyi/mercurial/revlogutils/revlogv0.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3JldmxvZ3V0aWxzL3JldmxvZ3YwLnB5aQ==..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3JldmxvZ3V0aWxzL3JldmxvZ3YwLnB5aQ== 100644
--- a/.pytype/pyi/mercurial/revlogutils/revlogv0.pyi
+++ b/.pytype/pyi/mercurial/revlogutils/revlogv0.pyi
@@ -27,4 +27,4 @@
 def _(message: bytes) -> bytes: ...
 def getoffset(q) -> int: ...
 def gettype(q) -> int: ...
-def parse_index_v0(data, inline) -> Tuple[revlogoldindex, None]: ...
+def parse_index_v0(data, inline, uses_generaldelta) -> Tuple[revlogoldindex, None]: ...
diff --git a/.pytype/pyi/mercurial/revset.pyi b/.pytype/pyi/mercurial/revset.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3JldnNldC5weWk=..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3JldnNldC5weWk= 100644
--- a/.pytype/pyi/mercurial/revset.pyi
+++ b/.pytype/pyi/mercurial/revset.pyi
@@ -156,7 +156,7 @@
 def generationsrel(repo, subset, x, rel, order) -> Any: ...
 def generationssubrel(repo, subset, x, rel, z, order) -> Any: ...
 def getargs(x: _T0, min, max, err) -> list: ...
-def getargsdict(x, funcname, keys) -> util.sortdict[nothing, nothing]: ...
+def getargsdict(x, funcname, keys) -> util.sortdict: ...
 def getboolean(x, err) -> bool: ...
 def getinteger(x, err, default: _T2 = ...) -> Union[int, _T2]: ...
 def getintrange(x, err1, err2, deffirst: _T3 = ..., deflast = ...) -> Tuple[Any, Any]: ...
diff --git a/.pytype/pyi/mercurial/revsetlang.pyi b/.pytype/pyi/mercurial/revsetlang.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3JldnNldGxhbmcucHlp..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3JldnNldGxhbmcucHlp 100644
--- a/.pytype/pyi/mercurial/revsetlang.pyi
+++ b/.pytype/pyi/mercurial/revsetlang.pyi
@@ -55,7 +55,7 @@
 def formatspec(expr, *args) -> bytes: ...
 def funcsused(tree) -> set: ...
 def getargs(x: _T0, min, max, err) -> list: ...
-def getargsdict(x, funcname, keys) -> util.sortdict[nothing, nothing]: ...
+def getargsdict(x, funcname, keys) -> util.sortdict: ...
 def getboolean(x, err) -> bool: ...
 def gethashlikesymbols(tree) -> list: ...
 def getinteger(x, err, default: _T2 = ...) -> Union[int, _T2]: ...
diff --git a/.pytype/pyi/mercurial/tagmerge.pyi b/.pytype/pyi/mercurial/tagmerge.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3RhZ21lcmdlLnB5aQ==..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3RhZ21lcmdlLnB5aQ== 100644
--- a/.pytype/pyi/mercurial/tagmerge.pyi
+++ b/.pytype/pyi/mercurial/tagmerge.pyi
@@ -6,6 +6,6 @@
 def _(message: bytes) -> bytes: ...
 def grouptagnodesbyline(tagnodes) -> List[list]: ...
 def merge(repo, fcd, fco, fca) -> Tuple[bool, int]: ...
-def readtagsformerge(ui, repo, lines, fn = ..., keeplinenums = ...) -> util.sortdict[nothing, nothing]: ...
+def readtagsformerge(ui, repo, lines, fn = ..., keeplinenums = ...) -> util.sortdict: ...
 def singletagmerge(p1nodes, p2nodes) -> Any: ...
 def writemergedtags(fcd, mergedtags) -> None: ...
diff --git a/.pytype/pyi/mercurial/tags.pyi b/.pytype/pyi/mercurial/tags.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3RhZ3MucHlp..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3RhZ3MucHlp 100644
--- a/.pytype/pyi/mercurial/tags.pyi
+++ b/.pytype/pyi/mercurial/tags.pyi
@@ -36,9 +36,9 @@
 def _filterfnodes(tagfnode, nodes) -> list: ...
 def _getfnodes(ui, repo, nodes = ..., revs = ...) -> dict: ...
 def _nulltonone(repo, value: _T1) -> Optional[_T1]: ...
-def _readtagcache(ui, repo) -> Tuple[Any, Optional[dict], Optional[Tuple[int, Any, Any]], Optional[Union[Dict[nothing, nothing], util.sortdict[nothing, nothing]]], bool]: ...
-def _readtaghist(ui, repo, lines, fn, recode = ..., calcnodelines = ...) -> Tuple[util.sortdict[nothing, nothing], util.sortdict[nothing, nothing]]: ...
-def _readtags(ui, repo, lines, fn, recode = ..., calcnodelines = ...) -> util.sortdict[nothing, nothing]: ...
+def _readtagcache(ui, repo) -> Tuple[Any, Optional[dict], Optional[Tuple[int, Any, Any]], Optional[Union[util.sortdict, Dict[nothing, nothing]]], bool]: ...
+def _readtaghist(ui, repo, lines, fn, recode = ..., calcnodelines = ...) -> Tuple[util.sortdict, util.sortdict]: ...
+def _readtags(ui, repo, lines, fn, recode = ..., calcnodelines = ...) -> util.sortdict: ...
 def _tag(repo, names, node, message, local, user, date, extra = ..., editor = ...) -> Any: ...
 def _tagsfromfnodes(ui, repo, fnodes) -> dict: ...
 def _updatetags(filetags, alltags, tagtype = ..., tagtypes = ...) -> None: ...
diff --git a/.pytype/pyi/mercurial/util.pyi b/.pytype/pyi/mercurial/util.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3V0aWwucHlp..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3V0aWwucHlp 100644
--- a/.pytype/pyi/mercurial/util.pyi
+++ b/.pytype/pyi/mercurial/util.pyi
@@ -27,7 +27,7 @@
 from hgdemandimport import tracing
 from http import client as httplib, cookiejar as cookielib
 from mercurial import encoding, error, i18n, policy, pycompat, typelib, urllibcompat
-from mercurial.interfaces import modules as intmod
+from mercurial.interfaces import misc as int_misc, modules as intmod
 from mercurial.utils import compression, hashutil, procutil, stringutil
 from typing import Annotated, Any, BinaryIO, Callable, Dict, Generator, Iterable, Iterator, List, Optional, OrderedDict, Self, Set, Tuple, Type, TypeVar, Union, overload
 from typing_extensions import Buffer
@@ -73,9 +73,8 @@
 
 AnyOrLiteralStr = TypeVar('AnyOrLiteralStr', str, bytes, str)
 AnyStr = TypeVar('AnyStr', str, bytes)
-_KT = TypeVar('_KT')
 _T0 = TypeVar('_T0')
 _Tatomictempfile = TypeVar('_Tatomictempfile', bound=atomictempfile)
 _Tcow = TypeVar('_Tcow', bound=cow)
 _Tfilestat = TypeVar('_Tfilestat', bound=filestat)
 _Tlrucachedict = TypeVar('_Tlrucachedict', bound=lrucachedict)
@@ -77,9 +76,8 @@
 _T0 = TypeVar('_T0')
 _Tatomictempfile = TypeVar('_Tatomictempfile', bound=atomictempfile)
 _Tcow = TypeVar('_Tcow', bound=cow)
 _Tfilestat = TypeVar('_Tfilestat', bound=filestat)
 _Tlrucachedict = TypeVar('_Tlrucachedict', bound=lrucachedict)
-_VT = TypeVar('_VT')
 
 class _lrucachenode:
     __slots__ = ["cost", "key", "next", "prev", "value"]
@@ -183,7 +181,7 @@
 class cowdict(cow, dict):
     __doc__: str
 
-class cowsortdict(cow, sortdict[_KT, _VT]):
+class cowsortdict(cow, sortdict):
     __doc__: str
 
 class digestchecker:
@@ -269,5 +267,5 @@
     def frompath(cls: Type[_Tfilestat], path: bytes) -> _Tfilestat: ...
     def isambig(self, old: _Tfilestat) -> bool: ...
 
-class hooks:
+class hooks(int_misc.IHooks):
     __doc__: str
@@ -273,4 +271,4 @@
     __doc__: str
-    _hooks: List[Tuple[Any, Any]]
-    def __call__(self, *args) -> List[nothing]: ...
+    _hooks: List[Tuple[bytes, Callable]]
+    def __call__(self, *args) -> list: ...
     def __init__(self) -> None: ...
@@ -276,5 +274,5 @@
     def __init__(self) -> None: ...
-    def add(self, source, hook) -> None: ...
+    def add(self, source: bytes, hook: Callable) -> None: ...
 
 class lrucachedict:
     __doc__: str
@@ -365,5 +363,5 @@
     def setsockopt(self, *args, **kwargs) -> Any: ...
     def settimeout(self, *args, **kwargs) -> Any: ...
 
-class sortdict(OrderedDict[_KT, _VT]):
+class sortdict(OrderedDict):
     __doc__: str
@@ -369,6 +367,6 @@
     __doc__: str
-    def __setitem__(self, key: _KT, value: _VT) -> None: ...
-    def insert(self, position: int, key: _KT, value: _VT) -> None: ...
+    def __setitem__(self, key, value) -> None: ...
+    def insert(self, position, key, value) -> None: ...
     def update(self, src, **f) -> None: ...
 
 @attr.s
diff --git a/.pytype/pyi/mercurial/utils/urlutil.pyi b/.pytype/pyi/mercurial/utils/urlutil.pyi
index b1e31d33601ea9718967cee472607cce239979b9_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3V0aWxzL3VybHV0aWwucHlp..d23188f6874c982e654290b4187590109ba2f0f8_LnB5dHlwZS9weWkvbWVyY3VyaWFsL3V0aWxzL3VybHV0aWwucHlp 100644
--- a/.pytype/pyi/mercurial/utils/urlutil.pyi
+++ b/.pytype/pyi/mercurial/utils/urlutil.pyi
@@ -4,6 +4,7 @@
 import re as remod
 import socket
 from mercurial import encoding, error, pycompat, urllibcompat
+from mercurial.interfaces import misc as int_misc
 from mercurial.revlogutils import constants as revlog_constants
 from mercurial.utils import stringutil
 from typing import Annotated, Any, Callable, Dict, Generator, List, Optional, Set, Tuple, Type, TypeVar, Union
@@ -21,7 +22,7 @@
 _Tpath = TypeVar('_Tpath', bound=path)
 _Turl = TypeVar('_Turl', bound=url)
 
-class path:
+class path(int_misc.IPath):
     __doc__: str
     _all_sub_opts: Any
     _own_sub_opts: Any
@@ -25,5 +26,5 @@
     __doc__: str
     _all_sub_opts: Any
     _own_sub_opts: Any
-    branch: Optional[bytes]
+    branch: Any
     is_push_variant: Annotated[bool, 'property']
@@ -29,4 +30,4 @@
     is_push_variant: Annotated[bool, 'property']
-    loc: bytes
+    loc: Any
     main_path: Optional[path]
     name: Any
@@ -31,4 +32,4 @@
     main_path: Optional[path]
     name: Any
-    raw_url: Any
+    raw_url: url
     rawloc: Any
@@ -34,8 +35,8 @@
     rawloc: Any
-    suboptions: Annotated[Dict[bytes, Any], 'property']
-    url: url
+    suboptions: Annotated[Dict[bytes, bytes], 'property']
+    url: Any
     def __init__(self, ui = ..., name = ..., rawloc = ..., suboptions = ..., validate_path = ...) -> None: ...
     def _apply_suboptions(self, ui, sub_options) -> None: ...
     def _isvalidlocalpath(self, path) -> bool: ...
     def _setup_url(self, rawloc) -> None: ...
     def _validate_path(self) -> None: ...
@@ -37,12 +38,12 @@
     def __init__(self, ui = ..., name = ..., rawloc = ..., suboptions = ..., validate_path = ...) -> None: ...
     def _apply_suboptions(self, ui, sub_options) -> None: ...
     def _isvalidlocalpath(self, path) -> bool: ...
     def _setup_url(self, rawloc) -> None: ...
     def _validate_path(self) -> None: ...
-    def copy(self: _Tpath, new_raw_location = ...) -> _Tpath: ...
+    def copy(self: _Tpath, new_raw_location: Optional[bytes] = ...) -> _Tpath: ...
     def get_push_variant(self: _Tpath) -> _Tpath: ...
 
 class paths(dict):
     __doc__: str
     def __init__(self, ui) -> None: ...
 
@@ -43,10 +44,10 @@
     def get_push_variant(self: _Tpath) -> _Tpath: ...
 
 class paths(dict):
     __doc__: str
     def __init__(self, ui) -> None: ...
 
-class url:
+class url(int_misc.IUrl):
     __doc__: str
     _hostport: bytes
     _localpath: bool
@@ -66,6 +67,6 @@
     def __init__(self, path: bytes, parsequery: bool = ..., parsefragment: bool = ...) -> None: ...
     def __repr__(self) -> str: ...
     def __str__(self) -> str: ...
-    def authinfo(self) -> Tuple[bytes, Optional[Tuple[None, Tuple[bytes, Any], Any, Any]]]: ...
+    def authinfo(self) -> Tuple[bytes, Optional[Tuple[None, Tuple[bytes, bytes], bytes, bytes]]]: ...
     def copy(self: _Turl) -> _Turl: ...
     def isabs(self) -> bool: ...
@@ -70,6 +71,6 @@
     def copy(self: _Turl) -> _Turl: ...
     def isabs(self) -> bool: ...
-    def islocal(self) -> Any: ...
+    def islocal(self) -> bool: ...
     def localpath(self) -> bytes: ...
 
 def _(message: bytes) -> bytes: ...