repo: refactor help output handling

Currently we have the behavior:
* `repo`: Equivalent to `repo help` -- only shows common subcommands
  (with short description), and then exits 0.
* `repo --help`: Shows repo's core options, lists all commands (no
  specific info), and then exits 0.

The first case is not behaving well:
* If you run `repo` without a specific subcommand, that's an error,
  so we should be exiting 1 instead.
* Showing only subcommands and no actual option summary makes it seem
  like repo itself doesn't take any options.  This confuses users.

Let's rework things a bit.  Now we have the behavior:
* `repo`: Shows repo's core options, lists all commands (no specific
  info), and then exits 1.
* `repo --help`: Shows repo's core options, shows common subcommands
  (with short description), and then exits 0.
* `repo --help-all`: Shows repo's core options, shows all subcommands
  (with short description), and then exits 0.

Basically we swap the behavior of `repo` and `repo --help`, and fix
the exit status when the subcommand is missing.

The addition of --help-all is mostly for the man pages.  We were
relying on `repo help --all` to generate the repo(1) man page, but
that too omitted the core repo options.  Now the man page includes
all the core repo options and provides a summary of all commands.

Change-Id: I1f99b99d5b8af2591f96a078d0647a3d76d6b0fc
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/312908
Reviewed-by: Xin Li <delphij@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
diff --git a/main.py b/main.py
index 253f311..229cb72 100755
--- a/main.py
+++ b/main.py
@@ -95,6 +95,8 @@
     add_help_option=False)
 global_options.add_option('-h', '--help', action='store_true',
                           help='show this help message and exit')
+global_options.add_option('--help-all', action='store_true',
+                          help='show this help message with all subcommands and exit')
 global_options.add_option('-p', '--paginate',
                           dest='pager', action='store_true',
                           help='display command output in the pager')
@@ -128,6 +130,23 @@
     self.repodir = repodir
     self.commands = all_commands
 
+  def _PrintHelp(self, short: bool = False, all_commands: bool = False):
+    """Show --help screen."""
+    global_options.print_help()
+    print()
+    if short:
+      commands = ' '.join(sorted(self.commands))
+      wrapped_commands = textwrap.wrap(commands, width=77)
+      print('Available commands:\n  %s' % ('\n  '.join(wrapped_commands),))
+      print('\nRun `repo help <command>` for command-specific details.')
+      print('Bug reports:', Wrapper().BUG_URL)
+    else:
+      cmd = self.commands['help']()
+      if all_commands:
+        cmd.PrintAllCommandsBody()
+      else:
+        cmd.PrintCommonCommandsBody()
+
   def _ParseArgs(self, argv):
     """Parse the main `repo` command line options."""
     for i, arg in enumerate(argv):
@@ -177,19 +196,16 @@
       SetTrace()
 
     # Handle options that terminate quickly first.
-    if gopts.help:
-      global_options.print_help()
-      commands = ' '.join(sorted(self.commands))
-      wrapped_commands = textwrap.wrap(commands, width=77)
-      print('\nAvailable commands:\n  %s' % ('\n  '.join(wrapped_commands),))
-      print('\nRun `repo help <command>` for command-specific details.')
+    if gopts.help or gopts.help_all:
+      self._PrintHelp(short=False, all_commands=gopts.help_all)
       return 0
     elif gopts.show_version:
       # Always allow global --version regardless of subcommand validity.
       name = 'version'
     elif not name:
       # No subcommand specified, so show the help/subcommand.
-      name = 'help'
+      self._PrintHelp(short=True)
+      return 1
 
     SetDefaultColoring(gopts.color)
 
diff --git a/man/repo-manifest.1 b/man/repo-manifest.1
index e42cc42..be46760 100644
--- a/man/repo-manifest.1
+++ b/man/repo-manifest.1
@@ -36,6 +36,9 @@
 \fB\-\-pretty\fR
 format output for humans to read
 .TP
+\fB\-\-no\-local\-manifests\fR
+ignore local manifests
+.TP
 \fB\-o\fR \-|NAME.xml, \fB\-\-output\-file\fR=\fI\,\-\/\fR|NAME.xml
 file to save the manifest to
 .SS Logging options:
@@ -95,7 +98,7 @@
 .IP
 <!ELEMENT notice (#PCDATA)>
 .IP
-<!ELEMENT remote EMPTY>
+<!ELEMENT remote (annotation*)>
 <!ATTLIST remote name         ID    #REQUIRED>
 <!ATTLIST remote alias        CDATA #IMPLIED>
 <!ATTLIST remote fetch        CDATA #REQUIRED>
@@ -393,13 +396,13 @@
 .PP
 Element annotation
 .PP
-Zero or more annotation elements may be specified as children of a project
-element. Each element describes a name\-value pair that will be exported into
-each project's environment during a 'forall' command, prefixed with REPO__. In
-addition, there is an optional attribute "keep" which accepts the case
-insensitive values "true" (default) or "false". This attribute determines
-whether or not the annotation will be kept when exported with the manifest
-subcommand.
+Zero or more annotation elements may be specified as children of a project or
+remote element. Each element describes a name\-value pair. For projects, this
+name\-value pair will be exported into each project's environment during a
+\&'forall' command, prefixed with `REPO__`. In addition, there is an optional
+attribute "keep" which accepts the case insensitive values "true" (default) or
+"false". This attribute determines whether or not the annotation will be kept
+when exported with the manifest subcommand.
 .PP
 Element copyfile
 .PP
diff --git a/man/repo.1 b/man/repo.1
index 0bc3acd..0e85b0b 100644
--- a/man/repo.1
+++ b/man/repo.1
@@ -2,9 +2,44 @@
 .TH REPO "1" "July 2021" "repo" "Repo Manual"
 .SH NAME
 repo \- repository management tool built on top of git
-.SH DESCRIPTION
-usage: repo COMMAND [ARGS]
-The complete list of recognized repo commands are:
+.SH SYNOPSIS
+.B repo
+[\fI\,-p|--paginate|--no-pager\/\fR] \fI\,COMMAND \/\fR[\fI\,ARGS\/\fR]
+.SH OPTIONS
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+show this help message and exit
+.TP
+\fB\-\-help\-all\fR
+show this help message with all subcommands and exit
+.TP
+\fB\-p\fR, \fB\-\-paginate\fR
+display command output in the pager
+.TP
+\fB\-\-no\-pager\fR
+disable the pager
+.TP
+\fB\-\-color\fR=\fI\,COLOR\/\fR
+control color usage: auto, always, never
+.TP
+\fB\-\-trace\fR
+trace git command execution (REPO_TRACE=1)
+.TP
+\fB\-\-trace\-python\fR
+trace python command execution
+.TP
+\fB\-\-time\fR
+time repo command execution
+.TP
+\fB\-\-version\fR
+display this version of repo
+.TP
+\fB\-\-event\-log\fR=\fI\,EVENT_LOG\/\fR
+filename of event log to append timeline to
+.TP
+\fB\-\-git\-trace2\-event\-log\fR=\fI\,GIT_TRACE2_EVENT_LOG\/\fR
+directory to write git trace2 event log to
+.SS "The complete list of recognized repo commands are:"
 .TP
 abandon
 Permanently abandon a development branch
@@ -91,3 +126,4 @@
 Display the version of repo
 .PP
 See 'repo help <command>' for more information on a specific command.
+Bug reports: https://bugs.chromium.org/p/gerrit/issues/entry?template=Repo+tool+issue
diff --git a/release/update-manpages b/release/update-manpages
index 3aeee20..f841f30 100755
--- a/release/update-manpages
+++ b/release/update-manpages
@@ -59,7 +59,7 @@
   cmdlist.append(['help2man', '-N', '-n', 'repository management tool built on top of git',
     '-S', 'repo', '-m', 'Repo Manual', f'--version-string={version}',
     '-o', MANDIR.joinpath('repo.1'), TOPDIR.joinpath('repo'),
-    '-h', 'help --all'])
+    '-h', '--help-all'])
 
   with tempfile.TemporaryDirectory() as tempdir:
     repo_dir = Path(tempdir) / '.repo'
diff --git a/subcmds/help.py b/subcmds/help.py
index f302e75..1a60ef4 100644
--- a/subcmds/help.py
+++ b/subcmds/help.py
@@ -50,14 +50,21 @@
 
   def _PrintAllCommands(self):
     print('usage: repo COMMAND [ARGS]')
+    self.PrintAllCommandsBody()
+
+  def PrintAllCommandsBody(self):
     print('The complete list of recognized repo commands are:')
     commandNames = list(sorted(all_commands))
     self._PrintCommands(commandNames)
     print("See 'repo help <command>' for more information on a "
           'specific command.')
+    print('Bug reports:', Wrapper().BUG_URL)
 
   def _PrintCommonCommands(self):
     print('usage: repo COMMAND [ARGS]')
+    self.PrintCommonCommandsBody()
+
+  def PrintCommonCommandsBody(self):
     print('The most commonly used repo commands are:')
 
     def gitc_supported(cmd):