Merge with mpm.
authorBryan O'Sullivan <bos@serpentine.com>
Tue, 09 Aug 2005 17:24:38 -0800
changeset 871 c2e77581bc84
parent 870 a82eae840447 (current diff)
parent 859 6390c377a9e6 (diff)
child 874 d4cb383e7de7
child 875 d3f836bf6cc1
child 879 953ccddd57bd
child 882 bc9ca4d51d23
Merge with mpm.
.hgignore
CONTRIBUTORS
TODO
doc/hg.1.txt
mercurial/commands.py
mercurial/hg.py
mercurial/hgweb.py
mercurial/revlog.py
mercurial/util.py
templates/map
tests/test-help
tests/test-help.out
--- a/.hgignore
+++ b/.hgignore
@@ -4,10 +4,11 @@
 \.so$
 \.pyc$
 \.swp$
+\.prof$
 ^tests/.*\.err$
 ^build/
 ^dist/
-^doc/.*\.[0-9]$
+^doc/.*\.[0-9](\.(x|ht)ml)?$
 ^MANIFEST$
 ^\.pc/
 ^patches/
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -19,10 +19,12 @@ Nguyen Anh Quynh <aquynh at gmail.com>
 Arun Sharma <arun at sharma-home.net>
 Kevin Smith <yarcs at qualitycode.com>
 Radoslaw Szkodzinski <astralstorm at gorzow.mm.pl>
+Samuel Tardieu <sam at rfc1149.net>
 K Thananchayan <thananck at yahoo.com>
 Andrew Thompson <andrewkt at aktzero.com>
 Michael S. Tsirkin <mst at mellanox.co.il>
 Rafael Villar Burke <pachi at mmn-arquitectos.com>
+Tristan Wibberley <tristan at wibberley.org>
 Mark Williamson <mark.williamson at cl.cam.ac.uk>
 
 If you are a contributor and don't see your name here, please let me know.
--- a/TODO
+++ b/TODO
@@ -26,17 +26,18 @@ Commands:
 - commands.py: number of args too much magic (e.g. in import_())
 - optionally only show merges (two parents)
 - automatic pull fallback to old-http://
-- hg pull http://foo tries hostname
-  'foo?cmd=changegroup&roots=0000000000000000000000000000000000000000'
 - pass options to ssh (debug/verbose/remote hg command etc.)
 - create a commented .hg/hgrc on init/clone
 - hg pull default in a subdir doesn't work, if it is a relative path
 - hg clone should store corrected relative paths, so moving a directory
   containing related repositories works again
-- mention synonyms (co, ci, ...) in help
-- show global options in help
 - if everyone knows 'hg clone': hg init [DIR]
 - if everyone knows 'hg update -m': remove -t
+- hg revert does not forget added files, it probably should.
+- hg pull should state if there are more heads than before.
+- hg clone: locking the repository while hardlinking.
+- hg clone: fall back to pull if hardlink not possible.
+- "hg diff not_existing" should yield an error message.
 
 Web:
 - optionally only show merges (two parents)
@@ -51,3 +52,5 @@ Web:
 - link children in hgweb
 - allow verbose mode
 - hide trivial parent (like in show_changeset)
+- default port for hg serve configurable in hgrc
+- download tarball via web interface
--- a/doc/hg.1.txt
+++ b/doc/hg.1.txt
@@ -346,6 +346,10 @@ status [options] [files]::
 
     options:
 
+    -m, --modified       show only modified files
+    -a, --added          show only added files
+    -r, --removed        show only removed files
+    -u, --unknown        show only unknown (not tracked) files
     -I, --include <pat>  include names matching the given patterns
     -X, --exclude <pat>  exclude names matching the given patterns
 
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -273,7 +273,8 @@ def show_changeset(ui, repo, rev=0, chan
 
 def show_version(ui):
     """output version and copyright information"""
-    ui.write("Mercurial version %s\n" % version.get_version())
+    ui.write("Mercurial Distributed SCM (version %s)\n"
+             % version.get_version())
     ui.status(
         "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
         "This is free software; see the source for copying conditions. "
@@ -283,56 +284,95 @@ def show_version(ui):
 
 def help_(ui, cmd=None):
     """show help for a given command or all commands"""
-    if cmd:
-        try:
-            i = find(cmd)
-            ui.write("%s\n\n" % i[2])
+    if cmd and cmd != 'shortlist':
+        key, i = find(cmd)
+        # synopsis
+        ui.write("%s\n\n" % i[2])
+
+        # description
+        doc = i[0].__doc__
+        if ui.quiet:
+            doc = doc.splitlines(0)[0]
+        ui.write("%s\n" % doc.rstrip())
+
+        # aliases
+        if not ui.quiet:
+            aliases = ', '.join(key.split('|')[1:])
+            if aliases:
+                ui.write("\naliases: %s\n" % aliases)
 
-            if i[1]:
-                for s, l, d, c in i[1]:
-                    opt = ' '
-                    if s:
-                        opt = opt + '-' + s + ' '
-                    if l:
-                        opt = opt + '--' + l + ' '
-                    if d:
-                        opt = opt + '(' + str(d) + ')'
-                    ui.write(opt, "\n")
-                    if c:
-                        ui.write('   %s\n' % c)
-                ui.write("\n")
+        # options
+        if not ui.quiet and i[1]:
+            ui.write("\noptions:\n\n")
+            for s, l, d, c in i[1]:
+                opt = ' '
+                if s:
+                    opt = opt + '-' + s + ' '
+                if l:
+                    opt = opt + '--' + l + ' '
+                if d:
+                    opt = opt + '(' + str(d) + ')'
+                ui.write(opt, "\n")
+                if c:
+                    ui.write('   %s\n' % c)
 
-            ui.write(i[0].__doc__, "\n")
-        except UnknownCommand:
-            ui.warn("hg: unknown command %s\n" % cmd)
-        sys.exit(0)
     else:
+        # program name
         if ui.verbose:
             show_version(ui)
-            ui.write('\n')
-        if ui.verbose:
-            ui.write('hg commands:\n\n')
         else:
-            ui.write('basic hg commands (use "hg help -v" for more):\n\n')
+            ui.status("Mercurial Distributed SCM\n")
+        ui.status('\n')
+
+        # list of commands
+        if cmd == "shortlist":
+            ui.status('basic commands (use "hg help" '
+                      'for the full list or option "-v" for details):\n\n')
+        elif ui.verbose:
+            ui.status('list of commands:\n\n')
+        else:
+            ui.status('list of commands (use "hg help -v" '
+                      'to show aliases and global options):\n\n')
 
         h = {}
+        cmds = {}
         for c, e in table.items():
             f = c.split("|")[0]
-            if not ui.verbose and not f.startswith("^"):
+            if cmd == "shortlist" and not f.startswith("^"):
                 continue
+            f = f.lstrip("^")
             if not ui.debugflag and f.startswith("debug"):
                 continue
-            f = f.lstrip("^")
             d = ""
             if e[0].__doc__:
                 d = e[0].__doc__.splitlines(0)[0].rstrip()
             h[f] = d
+            cmds[f]=c.lstrip("^")
 
         fns = h.keys()
         fns.sort()
         m = max(map(len, fns))
         for f in fns:
-            ui.write(' %-*s   %s\n' % (m, f, h[f]))
+            if ui.verbose:
+                commands = cmds[f].replace("|",", ")
+                ui.write(" %s:\n      %s\n"%(commands,h[f]))
+            else:
+                ui.write(' %-*s   %s\n' % (m, f, h[f]))
+
+    # global options
+    if ui.verbose:
+        ui.write("\nglobal options:\n\n")
+        for s, l, d, c in globalopts:
+            opt = ' '
+            if s:
+                opt = opt + '-' + s + ' '
+            if l:
+                opt = opt + '--' + l + ' '
+            if d:
+                opt = opt + '(' + str(d) + ')'
+            ui.write(opt, "\n")
+            if c:
+                ui.write('    %s\n' % c)
 
 # Commands start here, listed alphabetically
 
@@ -698,6 +738,7 @@ def import_(ui, repo, patch1, *patches, 
                     hgpatch = False
             elif line == '# HG changeset patch':
                 hgpatch = True
+                message = []       # We may have collected garbage
             else:
                 message.append(line)
 
@@ -1031,21 +1072,23 @@ def status(ui, repo, *pats, **opts):
     M = modified
     A = added
     R = removed
-    ? = not tracked'''
+    ? = not tracked
+    '''
 
     cwd = repo.getcwd()
     files, matchfn = matchpats(repo, cwd, pats, opts)
     (c, a, d, u) = [[pathto(cwd, x) for x in n]
                     for n in repo.changes(files=files, match=matchfn)]
 
-    for f in c:
-        ui.write("M ", f, "\n")
-    for f in a:
-        ui.write("A ", f, "\n")
-    for f in d:
-        ui.write("R ", f, "\n")
-    for f in u:
-        ui.write("? ", f, "\n")
+    changetypes = [('modified', 'M', c),
+                   ('added', 'A', a),
+                   ('removed', 'R', d),
+                   ('unknown', '?', u)]
+
+    for opt, char, changes in ([ct for ct in changetypes if opts[ct[0]]]
+                               or changetypes):
+        for f in changes:
+            ui.write("%s %s\n" % (char, f))
 
 def tag(ui, repo, name, rev=None, **opts):
     """add a tag for the current tip or a given revision"""
@@ -1138,14 +1181,16 @@ def verify(ui, repo):
 # Command options and aliases are listed here, alphabetically
 
 table = {
-    "^add": (add,
-             [('I', 'include', [], 'include path in search'),
-              ('X', 'exclude', [], 'exclude path from search')],
-             "hg add [FILE]..."),
-    "addremove": (addremove,
-                  [('I', 'include', [], 'include path in search'),
-                   ('X', 'exclude', [], 'exclude path from search')],
-                  "hg addremove [OPTION]... [FILE]..."),
+    "^add":
+        (add,
+         [('I', 'include', [], 'include path in search'),
+          ('X', 'exclude', [], 'exclude path from search')],
+         "hg add [FILE]..."),
+    "addremove":
+        (addremove,
+         [('I', 'include', [], 'include path in search'),
+          ('X', 'exclude', [], 'exclude path from search')],
+         "hg addremove [OPTION]... [FILE]..."),
     "^annotate":
         (annotate,
          [('r', 'rev', '', 'revision'),
@@ -1179,10 +1224,11 @@ table = {
     "debugstate": (debugstate, [], 'debugstate'),
     "debugindex": (debugindex, [], 'debugindex FILE'),
     "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'),
-    "debugwalk": (debugwalk,
-                  [('I', 'include', [], 'include path in search'),
-                   ('X', 'exclude', [], 'exclude path from search')],
-                  'debugwalk [OPTIONS]... [FILE]...'),
+    "debugwalk":
+        (debugwalk,
+         [('I', 'include', [], 'include path in search'),
+          ('X', 'exclude', [], 'exclude path from search')],
+         'debugwalk [OPTIONS]... [FILE]...'),
     "^diff":
         (diff,
          [('r', 'rev', [], 'revision'),
@@ -1193,10 +1239,11 @@ table = {
         (export,
          [('o', 'output', "", 'output to file')],
          "hg export [-o OUTFILE] REV..."),
-    "forget": (forget,
-               [('I', 'include', [], 'include path in search'),
-                ('X', 'exclude', [], 'exclude path from search')],
-               "hg forget FILE..."),
+    "forget":
+        (forget,
+         [('I', 'include', [], 'include path in search'),
+          ('X', 'exclude', [], 'exclude path from search')],
+         "hg forget FILE..."),
     "heads": (heads, [], 'hg heads'),
     "help": (help_, [], 'hg help [COMMAND]'),
     "identify|id": (identify, [], 'hg identify'),
@@ -1259,10 +1306,15 @@ table = {
           ('t', 'templates', "", 'template map'),
           ('6', 'ipv6', None, 'use IPv6 in addition to IPv4')],
          "hg serve [OPTION]..."),
-    "^status": (status,
-                [('I', 'include', [], 'include path in search'),
-                 ('X', 'exclude', [], 'exclude path from search')],
-                'hg status [FILE]...'),
+    "^status":
+        (status,
+         [('m', 'modified', None, 'show only modified files'),
+          ('a', 'added', None, 'show only added files'),
+          ('r', 'removed', None, 'show only removed files'),
+          ('u', 'unknown', None, 'show only unknown (not tracked) files'),
+          ('I', 'include', [], 'include path in search'),
+          ('X', 'exclude', [], 'exclude path from search')],
+         "hg status [FILE]..."),
     "tag":
         (tag,
          [('l', 'local', None, 'make the tag local'),
@@ -1283,9 +1335,9 @@ table = {
     "version": (show_version, [], 'hg version'),
     }
 
-globalopts = [('v', 'verbose', None, 'verbose'),
-              ('', 'debug', None, 'debug'),
-              ('q', 'quiet', None, 'quiet'),
+globalopts = [('v', 'verbose', None, 'verbose mode'),
+              ('', 'debug', None, 'debug mode'),
+              ('q', 'quiet', None, 'quiet mode'),
               ('', 'profile', None, 'profile'),
               ('R', 'repository', "", 'repository root directory'),
               ('', 'traceback', None, 'print traceback on exception'),
@@ -1299,7 +1351,7 @@ norepo = "clone init version help debugi
 def find(cmd):
     for e in table.keys():
         if re.match("(%s)$" % e, cmd):
-            return table[e]
+            return e, table[e]
 
     raise UnknownCommand(cmd)
 
@@ -1327,11 +1379,11 @@ def parse(args):
     if options["version"]:
         return ("version", show_version, [], options, cmdoptions)
     elif not args:
-        return ("help", help_, [], options, cmdoptions)
+        return ("help", help_, ["shortlist"], options, cmdoptions)
     else:
         cmd, args = args[0], args[1:]
 
-    i = find(cmd)
+    i = find(cmd)[1]
 
     # combine global options into local
     c = list(i[1])
@@ -1367,12 +1419,12 @@ def dispatch(args):
             help_(u, inst.args[0])
         else:
             u.warn("hg: %s\n" % inst.args[1])
-            help_(u)
+            help_(u, 'shortlist')
         sys.exit(-1)
     except UnknownCommand, inst:
         u = ui.ui()
         u.warn("hg: unknown command '%s'\n" % inst.args[0])
-        help_(u)
+        help_(u, 'shortlist')
         sys.exit(1)
 
     if options["time"]:
@@ -1455,5 +1507,8 @@ def dispatch(args):
         u.debug(inst, "\n")
         u.warn("%s: invalid arguments\n" % cmd)
         help_(u, cmd)
+    except UnknownCommand, inst:
+        u.warn("hg: unknown command '%s'\n" % inst.args[0])
+        help_(u, 'shortlist')
 
     sys.exit(-1)
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -22,16 +22,16 @@ class filelog(revlog):
     # This avoids a collision between a file named foo and a dir named
     # foo.i or foo.d
     def encodedir(self, path):
-        path.replace(".hg/", ".hg.hg/")
-        path.replace(".i/", ".i.hg/")
-        path.replace(".d/", ".i.hg/")
-        return path
+        return (path
+                .replace(".hg/", ".hg.hg/")
+                .replace(".i/", ".i.hg/")
+                .replace(".d/", ".d.hg/"))
 
     def decodedir(self, path):
-        path.replace(".d.hg/", ".d/")
-        path.replace(".i.hg/", ".i/")
-        path.replace(".hg.hg/", ".hg/")
-        return path
+        return (path
+                .replace(".d.hg/", ".d/")
+                .replace(".i.hg/", ".i/")
+                .replace(".hg.hg/", ".hg/"))
 
     def read(self, node):
         t = self.revision(node)
@@ -1784,8 +1784,11 @@ class httprepository:
         # Note: urllib2 takes proxy values from the environment and those will
         # take precedence
         for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]:
-            if os.environ.has_key(env):
-                del os.environ[env]
+            try:
+                if os.environ.has_key(env):
+                    del os.environ[env]
+            except OSError:
+                pass
 
         proxy_handler = urllib2.BaseHandler()
         if host and not no_proxy:
--- a/mercurial/hgweb.py
+++ b/mercurial/hgweb.py
@@ -70,7 +70,7 @@ def template(tmpl, filters = {}, **map):
         if m:
             yield tmpl[:m.start(0)]
             v = map.get(m.group(1), "")
-            v = callable(v) and v() or v
+            v = callable(v) and v(**map) or v
 
             fl = m.group(2)
             if fl:
@@ -224,14 +224,8 @@ class hgweb:
             tn = None
             yield diffblock(mdiff.unidiff(to, date1, tn, date2, f), f, tn)
 
-    def header(self):
-        yield self.t("header")
-
-    def footer(self):
-        yield self.t("footer")
-
     def changelog(self, pos):
-        def changenav():
+        def changenav(**map):
             def seq(factor = 1):
                 yield 1 * factor
                 yield 3 * factor
@@ -254,7 +248,7 @@ class hgweb:
 
             yield self.t("naventry", label="tip")
 
-        def changelist():
+        def changelist(**map):
             parity = (start - end) & 1
             cl = self.repo.changelog
             l = [] # build a list in forward order for efficiency
@@ -295,7 +289,7 @@ class hgweb:
 
     def search(self, query):
 
-        def changelist():
+        def changelist(**map):
             cl = self.repo.changelog
             count = 0
             qw = query.lower().split()
@@ -361,7 +355,7 @@ class hgweb:
             files.append(self.t("filenodelink",
                                 filenode = hex(mf.get(f, nullid)), file = f))
 
-        def diff():
+        def diff(**map):
             yield self.diff(p1, n, None)
 
         yield self.t('changeset',
@@ -382,7 +376,7 @@ class hgweb:
         fl = self.repo.file(f)
         count = fl.count()
 
-        def entries():
+        def entries(**map):
             l = []
             parity = (count - 1) & 1
 
@@ -457,7 +451,7 @@ class hgweb:
         t = float(cs[2].split(' ')[0])
         mfn = cs[0]
 
-        def annotate():
+        def annotate(**map):
             parity = 1
             last = None
             for r, l in fl.annotate(n):
@@ -527,7 +521,7 @@ class hgweb:
                 short = os.path.basename(remain)
                 files[short] = (f, n)
 
-        def filelist():
+        def filelist(**map):
             parity = 0
             fl = files.keys()
             fl.sort()
@@ -563,7 +557,7 @@ class hgweb:
         i = self.repo.tagslist()
         i.reverse()
 
-        def entries():
+        def entries(**map):
             parity = 0
             for k,n in i:
                 yield self.t("tagentry",
@@ -583,7 +577,7 @@ class hgweb:
         cs = cl.read(n)
         mf = self.repo.manifest.read(cs[0])
 
-        def diff():
+        def diff(**map):
             yield self.diff(p1, n, file)
 
         yield self.t("filediff",
@@ -600,6 +594,12 @@ class hgweb:
     # find tag, changeset, file
 
     def run(self):
+        def header(**map):
+            yield self.t("header", **map)
+
+        def footer(**map):
+            yield self.t("footer", **map)
+
         self.refresh()
         args = cgi.parse()
 
@@ -618,11 +618,14 @@ class hgweb:
         self.t = templater(m, self.filters,
                            {"url":url,
                             "repo":self.reponame,
-                            "header":self.header(),
-                            "footer":self.footer(),
+                            "header":header,
+                            "footer":footer,
                             })
 
-        if not args.has_key('cmd') or args['cmd'][0] == 'changelog':
+        if not args.has_key('cmd'):
+            args['cmd'] = [self.t.cache['default'],]
+        
+        if args['cmd'][0] == 'changelog':
             c = self.repo.changelog.count() - 1
             hi = c
             if args.has_key('rev'):
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -185,8 +185,8 @@ class revlog:
         for r in range(p + 1, self.count()):
             n = self.node(r)
             for pn in self.parents(n):
-                if pn == p:
-                    c.append(p)
+                if pn == node:
+                    c.append(n)
                     continue
                 elif pn == nullid:
                     continue
--- a/templates/map
+++ b/templates/map
@@ -1,3 +1,4 @@
+default = "changelog"
 header = header.tmpl
 footer = footer.tmpl
 search = search.tmpl
--- a/tests/test-help
+++ b/tests/test-help
@@ -1,11 +1,15 @@
 #!/bin/sh
 
+hg
+hg -q
 hg help
 hg -q help
 hg add -h
 hg add --skjdfks
 hg help diff
+hg help status
+hg -q help status
 hg help foo
-hg -q commands
+hg skjdfks
 
 exit 0
--- a/tests/test-help.out
+++ b/tests/test-help.out
@@ -1,23 +1,7 @@
-+ hg help
-basic hg commands (use "hg help -v" for more):
++ hg 
+Mercurial Distributed SCM
 
- add        add the specified files on the next commit
- annotate   show changeset information per file line
- clone      make a copy of an existing repository
- commit     commit the specified files or all outstanding changes
- diff       diff working directory (or selected files)
- export     dump the header and diffs for one or more changesets
- init       create a new repository in the current directory
- log        show the revision history of the repository or a single file
- pull       pull changes from the specified source
- push       push changes to the specified destination
- remove     remove the specified files on the next commit
- revert     revert modified files or dirs back to their unmodified states
- serve      export the repository via HTTP
- status     show changed files in the working directory
- update     update or merge working directory
-+ hg -q help
-basic hg commands (use "hg help -v" for more):
+basic commands (use "hg help" for the full list or option "-v" for details):
 
  add        add the specified files on the next commit
  annotate   show changeset information per file line
@@ -34,42 +18,170 @@ basic hg commands (use "hg help -v" for 
  serve      export the repository via HTTP
  status     show changed files in the working directory
  update     update or merge working directory
++ hg -q
+ add        add the specified files on the next commit
+ annotate   show changeset information per file line
+ clone      make a copy of an existing repository
+ commit     commit the specified files or all outstanding changes
+ diff       diff working directory (or selected files)
+ export     dump the header and diffs for one or more changesets
+ init       create a new repository in the current directory
+ log        show the revision history of the repository or a single file
+ pull       pull changes from the specified source
+ push       push changes to the specified destination
+ remove     remove the specified files on the next commit
+ revert     revert modified files or dirs back to their unmodified states
+ serve      export the repository via HTTP
+ status     show changed files in the working directory
+ update     update or merge working directory
++ hg help
+Mercurial Distributed SCM
+
+list of commands (use "hg help -v" to show aliases and global options):
+
+ add         add the specified files on the next commit
+ addremove   add all new files, delete all missing files
+ annotate    show changeset information per file line
+ cat         output the latest or given revision of a file
+ clone       make a copy of an existing repository
+ commit      commit the specified files or all outstanding changes
+ copy        mark a file as copied or renamed for the next commit
+ diff        diff working directory (or selected files)
+ export      dump the header and diffs for one or more changesets
+ forget      don't add the specified files on the next commit
+ heads       show current repository heads
+ help        show help for a given command or all commands
+ identify    print information about the working copy
+ import      import an ordered set of patches
+ init        create a new repository in the current directory
+ locate      locate files matching specific patterns
+ log         show the revision history of the repository or a single file
+ manifest    output the latest or given revision of the project manifest
+ parents     show the parents of the working dir or revision
+ paths       show path or list of available paths
+ pull        pull changes from the specified source
+ push        push changes to the specified destination
+ rawcommit   raw commit interface
+ recover     roll back an interrupted transaction
+ remove      remove the specified files on the next commit
+ revert      revert modified files or dirs back to their unmodified states
+ root        print the root (top) of the current working dir
+ serve       export the repository via HTTP
+ status      show changed files in the working directory
+ tag         add a tag for the current tip or a given revision
+ tags        list repository tags
+ tip         show the tip revision
+ undo        undo the last commit or pull
+ update      update or merge working directory
+ verify      verify the integrity of the repository
+ version     output version and copyright information
++ hg -q help
+ add         add the specified files on the next commit
+ addremove   add all new files, delete all missing files
+ annotate    show changeset information per file line
+ cat         output the latest or given revision of a file
+ clone       make a copy of an existing repository
+ commit      commit the specified files or all outstanding changes
+ copy        mark a file as copied or renamed for the next commit
+ diff        diff working directory (or selected files)
+ export      dump the header and diffs for one or more changesets
+ forget      don't add the specified files on the next commit
+ heads       show current repository heads
+ help        show help for a given command or all commands
+ identify    print information about the working copy
+ import      import an ordered set of patches
+ init        create a new repository in the current directory
+ locate      locate files matching specific patterns
+ log         show the revision history of the repository or a single file
+ manifest    output the latest or given revision of the project manifest
+ parents     show the parents of the working dir or revision
+ paths       show path or list of available paths
+ pull        pull changes from the specified source
+ push        push changes to the specified destination
+ rawcommit   raw commit interface
+ recover     roll back an interrupted transaction
+ remove      remove the specified files on the next commit
+ revert      revert modified files or dirs back to their unmodified states
+ root        print the root (top) of the current working dir
+ serve       export the repository via HTTP
+ status      show changed files in the working directory
+ tag         add a tag for the current tip or a given revision
+ tags        list repository tags
+ tip         show the tip revision
+ undo        undo the last commit or pull
+ update      update or merge working directory
+ verify      verify the integrity of the repository
+ version     output version and copyright information
 + hg add -h
 hg add: option -h not recognized
 hg add [FILE]...
 
+add the specified files on the next commit
+
+options:
+
  -I --include 
    include path in search
  -X --exclude 
    exclude path from search
-
-add the specified files on the next commit
 + hg add --skjdfks
 hg add: option --skjdfks not recognized
 hg add [FILE]...
 
+add the specified files on the next commit
+
+options:
+
  -I --include 
    include path in search
  -X --exclude 
    exclude path from search
-
-add the specified files on the next commit
 + hg help diff
 hg diff [-r REV1 [-r REV2]] [FILE]...
 
+diff working directory (or selected files)
+
+options:
+
  -r --rev 
    revision
  -I --include 
    include path in search
  -X --exclude 
    exclude path from search
++ hg help status
+hg status [FILE]...
 
-diff working directory (or selected files)
+show changed files in the working directory
+
+    M = modified
+    A = added
+    R = removed
+    ? = not tracked
+
+options:
+
+ -m --modified 
+   show only modified files
+ -a --added 
+   show only added files
+ -r --removed 
+   show only removed files
+ -u --unknown 
+   show only unknown (not tracked) files
+ -I --include 
+   include path in search
+ -X --exclude 
+   exclude path from search
++ hg -q help status
+hg status [FILE]...
+
+show changed files in the working directory
 + hg help foo
-hg: unknown command foo
-+ hg -q commands
-hg: unknown command 'commands'
-basic hg commands (use "hg help -v" for more):
+hg: unknown command 'foo'
+Mercurial Distributed SCM
+
+basic commands (use "hg help" for the full list or option "-v" for details):
 
  add        add the specified files on the next commit
  annotate   show changeset information per file line
@@ -86,3 +198,24 @@ basic hg commands (use "hg help -v" for 
  serve      export the repository via HTTP
  status     show changed files in the working directory
  update     update or merge working directory
++ hg skjdfks
+hg: unknown command 'skjdfks'
+Mercurial Distributed SCM
+
+basic commands (use "hg help" for the full list or option "-v" for details):
+
+ add        add the specified files on the next commit
+ annotate   show changeset information per file line
+ clone      make a copy of an existing repository
+ commit     commit the specified files or all outstanding changes
+ diff       diff working directory (or selected files)
+ export     dump the header and diffs for one or more changesets
+ init       create a new repository in the current directory
+ log        show the revision history of the repository or a single file
+ pull       pull changes from the specified source
+ push       push changes to the specified destination
+ remove     remove the specified files on the next commit
+ revert     revert modified files or dirs back to their unmodified states
+ serve      export the repository via HTTP
+ status     show changed files in the working directory
+ update     update or merge working directory