changeset 27379:2278870bb997

help: support loading sub-topics If a sub-topic/section is requested and the main topic corresponds to a topic with sub-topics, we now look for and return content for a sub-topic if found. With this patch, `hg help internals.X` now works. hgweb does not yet render sub-topics, however.
author Gregory Szorc <gregory.szorc@gmail.com>
date Sun, 13 Dec 2015 11:19:55 -0800
parents c709b515218e
children c7129ed280b8
files mercurial/help.py tests/test-help.t
diffstat 2 files changed, 163 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/help.py	Sun Dec 13 11:29:01 2015 -0800
+++ b/mercurial/help.py	Sun Dec 13 11:19:55 2015 -0800
@@ -206,6 +206,11 @@
      internalshelp),
 ])
 
+# Maps topics with sub-topics to a list of their sub-topics.
+subtopics = {
+    'internals': internalstable,
+}
+
 # Map topics to lists of callable taking the current topic help and
 # returning the updated version
 helphooks = {}
@@ -433,11 +438,19 @@
         return rst
 
     def helptopic(name, subtopic=None):
-        for names, header, doc in helptable:
-            if name in names:
-                break
-        else:
-            raise error.UnknownCommand(name)
+        # Look for sub-topic entry first.
+        header, doc = None, None
+        if subtopic and name in subtopics:
+            for names, header, doc in subtopics[name]:
+                if subtopic in names:
+                    break
+
+        if not header:
+            for names, header, doc in helptable:
+                if name in names:
+                    break
+            else:
+                raise error.UnknownCommand(name)
 
         rst = [minirst.section(header)]
 
--- a/tests/test-help.t	Sun Dec 13 11:29:01 2015 -0800
+++ b/tests/test-help.t	Sun Dec 13 11:19:55 2015 -0800
@@ -874,6 +874,151 @@
        bundles       container for exchange of repository data
        changegroups  representation of revlog data
 
+sub-topics can be accessed
+
+  $ hg help internals.changegroups
+      Changegroups
+      ============
+  
+      Changegroups are representations of repository revlog data, specifically
+      the changelog, manifest, and filelogs.
+  
+      There are 2 versions of changegroups: "1" and "2". From a high-level, they
+      are almost exactly the same, with the only difference being a header on
+      entries in the changeset segment.
+  
+      Changegroups consists of 3 logical segments:
+  
+        +---------------------------------+
+        |           |          |          |
+        | changeset | manifest | filelogs |
+        |           |          |          |
+        +---------------------------------+
+  
+      The principle building block of each segment is a *chunk*. A *chunk* is a
+      framed piece of data:
+  
+        +---------------------------------------+
+        |           |                           |
+        |  length   |           data            |
+        | (32 bits) |       <length> bytes      |
+        |           |                           |
+        +---------------------------------------+
+  
+      Each chunk starts with a 32-bit big-endian signed integer indicating the
+      length of the raw data that follows.
+  
+      There is a special case chunk that has 0 length ("0x00000000"). We call
+      this an *empty chunk*.
+  
+      Delta Groups
+      ------------
+  
+      A *delta group* expresses the content of a revlog as a series of deltas,
+      or patches against previous revisions.
+  
+      Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
+      to signal the end of the delta group:
+  
+        +------------------------------------------------------------------------+
+        |                |             |               |             |           |
+        | chunk0 length  | chunk0 data | chunk1 length | chunk1 data |    0x0    |
+        |   (32 bits)    |  (various)  |   (32 bits)   |  (various)  | (32 bits) |
+        |                |             |               |             |           |
+        +------------------------------------------------------------+-----------+
+  
+      Each *chunk*'s data consists of the following:
+  
+        +-----------------------------------------+
+        |              |              |           |
+        | delta header | mdiff header |   delta   |
+        |  (various)   |  (12 bytes)  | (various) |
+        |              |              |           |
+        +-----------------------------------------+
+  
+      The *length* field is the byte length of the remaining 3 logical pieces of
+      data. The *delta* is a diff from an existing entry in the changelog.
+  
+      The *delta header* is different between versions "1" and "2" of the
+      changegroup format.
+  
+      Version 1:
+  
+        +------------------------------------------------------+
+        |            |             |             |             |
+        |    node    |   p1 node   |   p2 node   |  link node  |
+        | (20 bytes) |  (20 bytes) |  (20 bytes) |  (20 bytes) |
+        |            |             |             |             |
+        +------------------------------------------------------+
+  
+      Version 2:
+  
+        +------------------------------------------------------------------+
+        |            |             |             |            |            |
+        |    node    |   p1 node   |   p2 node   | base node  | link node  |
+        | (20 bytes) |  (20 bytes) |  (20 bytes) | (20 bytes) | (20 bytes) |
+        |            |             |             |            |            |
+        +------------------------------------------------------------------+
+  
+      The *mdiff header* consists of 3 32-bit big-endian signed integers
+      describing offsets at which to apply the following delta content:
+  
+        +-------------------------------------+
+        |           |            |            |
+        |  offset   | old length | new length |
+        | (32 bits) |  (32 bits) |  (32 bits) |
+        |           |            |            |
+        +-------------------------------------+
+  
+      In version 1, the delta is always applied against the previous node from
+      the changegroup or the first parent if this is the first entry in the
+      changegroup.
+  
+      In version 2, the delta base node is encoded in the entry in the
+      changegroup. This allows the delta to be expressed against any parent,
+      which can result in smaller deltas and more efficient encoding of data.
+  
+      Changeset Segment
+      -----------------
+  
+      The *changeset segment* consists of a single *delta group* holding
+      changelog data. It is followed by an *empty chunk* to denote the boundary
+      to the *manifests segment*.
+  
+      Manifest Segment
+      ----------------
+  
+      The *manifest segment* consists of a single *delta group* holding manifest
+      data. It is followed by an *empty chunk* to denote the boundary to the
+      *filelogs segment*.
+  
+      Filelogs Segment
+      ----------------
+  
+      The *filelogs* segment consists of multiple sub-segments, each
+      corresponding to an individual file whose data is being described:
+  
+        +--------------------------------------+
+        |          |          |          |     |
+        | filelog0 | filelog1 | filelog2 | ... |
+        |          |          |          |     |
+        +--------------------------------------+
+  
+      The final filelog sub-segment is followed by an *empty chunk* to denote
+      the end of the segment and the overall changegroup.
+  
+      Each filelog sub-segment consists of the following:
+  
+        +------------------------------------------+
+        |               |            |             |
+        | filename size |  filename  | delta group |
+        |   (32 bits)   |  (various) |  (various)  |
+        |               |            |             |
+        +------------------------------------------+
+  
+      That is, a *chunk* consisting of the filename (not terminated or padded)
+      followed by N chunks constituting the *delta group* for this file.
+
 Test list of commands with command with no help text
 
   $ hg help helpext