git-codereview: clean up usage message, docs

Change-Id: I634a9d47401c1000bcb38e9dd7e84296a3de00e6
Reviewed-on: https://go-review.googlesource.com/c/review/+/254746
Trust: Russ Cox <rsc@golang.org>
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/git-codereview/change.go b/git-codereview/change.go
index 790d4e6..ccc7836 100644
--- a/git-codereview/change.go
+++ b/git-codereview/change.go
@@ -17,12 +17,13 @@
 var changeQuick bool
 
 func cmdChange(args []string) {
+	// NOTE: New flags should be added to the usage message below as well as doc.go.
 	flags.StringVar(&commitMsg, "m", "", "specify a commit message")
 	flags.BoolVar(&changeAuto, "a", false, "add changes to any tracked files")
 	flags.BoolVar(&changeQuick, "q", false, "do not edit pending commit msg")
 	flags.Parse(args)
 	if len(flags.Args()) > 1 {
-		fmt.Fprintf(stderr(), "Usage: %s change %s [branch]\n", os.Args[0], globalFlags)
+		fmt.Fprintf(stderr(), "Usage: %s change %s [-a] [-m msg] [-q] [branch]\n", progName, globalFlags)
 		os.Exit(2)
 	}
 
@@ -41,7 +42,7 @@
 	// Create or amend change commit.
 	b := CurrentBranch()
 	if !b.IsLocalOnly() {
-		dief("can't commit to %s branch (use '%s change branchname').", b.Name, os.Args[0])
+		dief("can't commit to %s branch (use '%s change branchname').", b.Name, progName)
 	}
 
 	amend := b.HasPendingCommit()
diff --git a/git-codereview/doc.go b/git-codereview/doc.go
index 8cf1e64..4232869 100644
--- a/git-codereview/doc.go
+++ b/git-codereview/doc.go
@@ -6,16 +6,29 @@
 Git-codereview manages the code review process for Git changes using a Gerrit
 server.
 
-The git-codereview tool manages ``change branches'' in the local git repository.
-Each such branch tracks a single commit, or ``pending change'',
+The git-codereview tool manages “change branches” in the local git repository.
+Each such branch tracks a single commit, or “pending change”,
 that is reviewed using a Gerrit server; the Gerrit remote must be
-named ``origin'' in the local git repo.
+named “origin” in the local git repo.
 
 Modifications to the pending change are applied by amending the commit.
-This process implements the ``single-commit feature branch'' model.
+This process implements the “single-commit feature branch” model.
 Creating multiple-commit feature branches, for example to break a large
 change into a reviewable sequence, is also supported; see the discussion below.
 
+Each local git branch is expected to have a configured upstream branch on the server.
+For example, for a local “work” branch, .git/config might contain:
+
+	[branch "work"]
+		remote = origin
+		merge = refs/heads/main
+
+to instruct git itself that the local “work” branch tracks the upstream “main” branch.
+Git-codereview inspects this setting, which is referred to as “upstream” below.
+If upstream is not configured, which can happen when using checkouts managed by
+very old versions of git-codereview or other tools, git-codereview initializes upstream
+to “main” if that branch exists, or else “master”.
+
 Once installed as git-codereview, the tool's commands are available through git
 either by running
 
@@ -26,7 +39,7 @@
 	git <command>
 
 The review tool's command names do not conflict with any extant git commands.
-This document uses the first form for clarity but most users install these
+This document uses the first form for clarity, but most users install these
 aliases in their .gitconfig file:
 
 	[alias]
@@ -43,15 +56,15 @@
 For simple, unrelated changes, the typical usage of the git-codereview tool
 is to place each pending change in its own Git branch.
 In this workflow, the work branch contains
-either no pending change beyond origin/master (when there's no local work)
-or exactly one pending change beyond origin/master (the change being developed).
+either no pending change beyond upstream (when there's no local work)
+or exactly one pending change beyond upstream (the change being developed).
 
 When there is no pending change on the work branch,
-``git codereview change'' creates one by running ``git commit''.
+“git codereview change” creates one by running “git commit”.
 Otherwise, when there is already a pending change,
-``git codereview change'' revises it by running ``git commit --amend''.
+“git codereview change” revises it by running “git commit --amend”.
 
-The ``git codereview mail'' and ``git codereview submit'' commands
+The “git codereview mail” and “git codereview submit” commands
 implicitly operate on the lone pending change.
 
 Multiple-Commit Work Branches
@@ -60,48 +73,48 @@
 A sequence of changes that build on one another is more easily
 managed as multiple commits on a single branch, and the git-codereview tool
 supports this workflow as well.
-To add a new pending change, invoke ``git commit'' directly,
-instead of ``git codereview change''.
+To add a new pending change, invoke “git commit” directly,
+instead of “git codereview change”.
 The git-codereview tool adjusts its behavior when there are
 multiple pending changes.
 
-The ``git codereview change'' command amends the top commit in the stack (HEAD).
+The “git codereview change” command amends the top commit in the stack (HEAD).
 To amend a commit further down the stack, use Git's rebase support,
-for example by using ``git commit --fixup'' followed by ``git codereview rebase-work''.
+for example by using “git commit --fixup” followed by “git codereview rebase-work”.
 
-The ``git codereview mail'' command requires an explicit revision argument,
-but note that since ``git codereview mail'' is implemented as a ``git push'',
+The “git codereview mail” command requires an explicit revision argument,
+but note that since “git codereview mail” is implemented as a “git push”,
 any commits earlier in the stack are necessarily also mailed.
 
-The ``git codereview submit'' command also requires an explicit revision argument,
+The “git codereview submit” command also requires an explicit revision argument,
 and while earlier commits are necessarily still uploaded and mailed,
-only the named revision or revisions are submitted (merged into origin/master).
-In a single-commit work branch, a successful ``git codereview submit''
-effectively runs ``git codereview sync'' automatically.
+only the named revision or revisions are submitted (merged into upstream).
+In a single-commit work branch, a successful “git codereview submit”
+effectively runs “git codereview sync” automatically.
 In a multiple-commit work branch, it does not, because
-the implied ``git rebase'' may conflict with the remaining pending commits.
-Instead it is necessary to run ``git codereview sync'' explicitly
-(when ready) after ``git codereview submit''.
+the implied “git rebase” may conflict with the remaining pending commits.
+Instead it is necessary to run “git codereview sync” explicitly
+(when ready) after “git codereview submit”.
 
 Reusing Work Branches
 
 Although one common practice is to create a new branch for each pending change,
-running ``git codereview submit'' (and possibly ``git codereview sync'')
+running “git codereview submit” (and possibly “git codereview sync”)
 leaves the current branch ready for reuse with a future change.
 Some developers find it helpful to create a single work branch
-(``git change work'') and then do all work in that branch,
+(“git change work”) and then do all work in that branch,
 possibly in the multiple-commit mode, never changing between branches.
 
-Command Details
+Commands
 
 All commands accept these global flags:
 
+The -n flag prints all commands that would be run, but does not run them.
+
 The -v flag prints all commands that make changes. Multiple occurrences
 trigger more verbosity in some commands, including sync.
 
-The -n flag prints all commands that would be run, but does not run them.
-
-Descriptions of each command follow.
+These are omitted from the per-command descriptions below.
 
 Branchpoint
 
@@ -112,8 +125,8 @@
 
 This commit is the point where local work branched from the published tree.
 The command is intended mainly for use in scripts. For example,
-``git diff $(git codereview branchpoint)'' or
-``git log $(git codereview branchpoint)..HEAD''.
+“git diff $(git codereview branchpoint)” or
+“git log $(git codereview branchpoint)..HEAD”.
 
 Change
 
@@ -141,6 +154,10 @@
 option is only useful when creating commits (e.g. if there are unstaged
 changes). If a commit already exists, it is overwritten. If -q is also
 present, -q will be ignored.
+997As a special case, if branchname is a decimal CL number, such as 987, the change
+command downloads the latest patch set of that CL from the server and switches to it.
+A specific patch set can be requested by adding a decimal point: 987.2 for patch set 2
+of CL 987.
 
 Gofmt
 
@@ -168,16 +185,17 @@
 	git codereview hooks
 
 The pre-commit hook checks that all Go code is formatted with gofmt and that
-the commit is not being made directly to the master branch.
+the commit is not being made directly to a branch with the same name as the
+upstream branch.
 
-The commit-msg hook adds the Gerrit ``Change-Id'' line to the commit message if
+The commit-msg hook adds the Gerrit “Change-Id” line to the commit message if
 not present. It also checks that the message uses the convention established by
 the Go project that the first line has the form, pkg/path: summary.
 
 The hooks command will not overwrite an existing hook.
-If it is not installing hooks, use ``git codereview hooks -v'' for details.
+If it is not installing hooks, use “git codereview hooks -v” for details.
 This hook installation is also done at startup by all other git codereview
-commands, except ``git codereview help''.
+commands, except “git codereview help”.
 
 Hook-Invoke
 
@@ -185,19 +203,30 @@
 
 	git codereview hook-invoke <hook> [args]
 
-It is run by the shell scripts installed by the ``git codereview hooks'' command.
+It is run by the shell scripts installed by the “git codereview hooks” command.
 
 Mail
 
 The mail command starts the code review process for the pending change.
 
-	git codereview mail [-f] [-r email] [-cc email] [-trybot] [-wip] [revision]
+	git codereview mail [-r email,...] [-cc email,...]
+		[-diff] [-f] [-nokeycheck] [-hashtag tag,...] [-nokeycheck]
+		[-topic topic] [-trust] [-trybot] [-wip]
+		[revision]
 
 It pushes the pending change commit in the current branch to the Gerrit code
 review server and prints the URL for the change on the server.
 If the change already exists on the server, the mail command updates that
 change with a new changeset.
 
+If there are multiple pending commits, the revision argument is mandatory.
+If no revision is specified, the mail command prints a short summary of
+the pending commits for use in deciding which to mail.
+
+If any commit that would be pushed to the server contains the text
+“DO NOT MAIL” (case insensitive) in its commit message, the mail command
+will refuse to send the commit to the server.
+
 The -r and -cc flags identify the email addresses of people to do the code
 review and to be CC'ed about the code review.
 Multiple addresses are given as a comma-separated list.
@@ -207,26 +236,28 @@
 from the git repository log to find email addresses of the form name@somedomain
 and then, in case of ambiguity, using the reviewer who appears most often.
 
-The -trybot flag runs the trybots on all new or updated changes. It is
-equivalent to setting the Run-Trybot+1 label from Gerrit.
+The -diff flag shows a diff of the named revision compared against the latest
+upstream commit incorporated into the local branch.
 
-The -wip flag sets the status of the change to work-in-progress.
+The -f flag forces mail to proceed even if there are staged changes that have
+not been committed. By default, mail fails in that case.
 
-The mail command fails if there are staged edits that are not committed.
-The -f flag overrides this behavior.
+The -nokeycheck flag disables the Gerrit server check for committed files
+containing data that looks like public keys. (The most common time -nokeycheck
+is needed is when checking in test cases for cryptography libraries.)
+
+The -trust flag sets a Trust+1 vote on any uploaded changes.
+The Go project uses this vote to identify trusted commit authors.
+
+The -trybot flag sets a Run-TryBot+1 vote on any uploaded changes.
+The Go project uses this vote to start running integration tests on the CL.
+
+The -wip flag marks any uploaded changes as work-in-progress.
 
 The mail command updates the tag <branchname>.mailed to refer to the
-commit that was most recently mailed, so running ``git diff <branchname>.mailed''
+commit that was most recently mailed, so running “git diff <branchname>.mailed”
 shows diffs between what is on the Gerrit server and the current directory.
 
-If there are multiple pending commits, the revision argument is mandatory.
-If no revision is specified, the mail command prints a short summary of
-the pending commits for use in deciding which to mail.
-
-If any commit that would be pushed to the server contains the text
-"DO NOT MAIL" (case insensitive) in its commit message, the mail command
-will refuse to send the commit to the server.
-
 Pending
 
 The pending command prints to standard output the status of all pending changes
@@ -242,24 +273,24 @@
 
 The -s flag causes the command to print abbreviated (short) output.
 
-Common shorter aliases include ``git p'' for ``git pending''
-and ``git pl'' for ``git pending -l'' (notably faster but without Gerrit information).
+Useful aliases include “git p” for “git pending” and “git pl” for “git pending -l”
+(notably faster but without Gerrit information).
 
 Rebase-work
 
 The rebase-work command runs git rebase in interactive mode over pending changes.
-It is shorthand for ``git rebase -i $(git codereview branchpoint)''.
-It differs from plain ``git rebase -i'' in that the latter will try to incorporate
+It is shorthand for “git rebase -i $(git codereview branchpoint)”.
+It differs from plain “git rebase -i” in that the latter will try to incorporate
 new commits from the origin branch during the rebase;
-``git codereview rebase-work'' does not.
+“git codereview rebase-work” does not.
 
-In multiple-commit workflows, rebase-work is used so often
-that it can be helpful to alias it to ``git rw''.
+In multiple-commit workflows, rebase-work is used so often that it can be helpful
+to alias it to “git rw”.
 
 Submit
 
 The submit command pushes the pending change to the Gerrit server and tells
-Gerrit to submit it to the master branch.
+Gerrit to submit it to the upstream branch.
 
 	git codereview submit [-i | revision...]
 
@@ -267,7 +298,7 @@
 part of the pending change.
 
 The -i option causes the submit command to open a list of commits to submit
-in the configured text editor, similar to ``git rebase -i''.
+in the configured text editor, similar to “git rebase -i”.
 
 If multiple revisions are specified, the submit command submits each one in turn,
 stopping at the first failure.
@@ -279,7 +310,7 @@
 
 After submitting the pending changes, the submit command tries to synchronize the
 current branch to the submitted commit, if it can do so cleanly.
-If not, it will prompt the user to run ``git codereview sync'' manually.
+If not, it will prompt the user to run “git codereview sync” manually.
 
 After a successful sync, the branch can be used to prepare a new change.
 
@@ -300,15 +331,15 @@
 
 	key: value
 
-The ``gerrit'' key sets the Gerrit URL for this project. Git-codereview
+The “gerrit” key sets the Gerrit URL for this project. Git-codereview
 automatically derives the Gerrit URL from repositories hosted in
 *.googlesource.com. If not set or derived, the repository is assumed to
 not have Gerrit, and certain features won't work.
 
-The ``issuerepo'' key specifies the GitHub repository to use for issues, if
-different from the source repository. If set to ``golang/go'', for example,
-lines such as ``Fixes #123'' in a commit message will be rewritten to ``Fixes
-golang/go#123''.
+The “issuerepo” key specifies the GitHub repository to use for issues,
+if different from the source repository. If set to “golang/go”, for example,
+lines such as “Fixes #123” in a commit message will be rewritten to
+“Fixes golang/go#123”.
 
 */
 package main
diff --git a/git-codereview/gofmt.go b/git-codereview/gofmt.go
index f47c43d..bfba123 100644
--- a/git-codereview/gofmt.go
+++ b/git-codereview/gofmt.go
@@ -18,10 +18,11 @@
 var gofmtList bool
 
 func cmdGofmt(args []string) {
+	// NOTE: New flags should be added to the usage message below as well as doc.go.
 	flags.BoolVar(&gofmtList, "l", false, "list files that need to be formatted")
 	flags.Parse(args)
 	if len(flag.Args()) > 0 {
-		fmt.Fprintf(stderr(), "Usage: %s gofmt %s [-l]\n", os.Args[0], globalFlags)
+		fmt.Fprintf(stderr(), "Usage: %s gofmt %s [-l]\n", progName, globalFlags)
 		os.Exit(2)
 	}
 
diff --git a/git-codereview/mail.go b/git-codereview/mail.go
index 1fe35e5..e6cdb90 100644
--- a/git-codereview/mail.go
+++ b/git-codereview/mail.go
@@ -15,24 +15,29 @@
 )
 
 func cmdMail(args []string) {
+	// NOTE: New flags should be added to the usage message below as well as doc.go.
 	var (
-		diff       = flags.Bool("diff", false, "show change commit diff and don't upload or mail")
-		force      = flags.Bool("f", false, "mail even if there are staged changes")
-		wip        = flags.Bool("wip", false, "set the status of a change to Work-in-Progress")
-		topic      = flags.String("topic", "", "set Gerrit topic")
-		trybot     = flags.Bool("trybot", false, "run trybots on the uploaded CLs")
-		trust      = flags.Bool("trust", false, "add a Trust+1 vote to the CL")
-		rList      = new(stringList) // installed below
-		ccList     = new(stringList) // installed below
-		tagList    = new(stringList) // installed below
-		noKeyCheck = flags.Bool("nokeycheck", false, "set 'git push -o nokeycheck', to prevent Gerrit from checking for private keys")
+		rList  = new(stringList) // installed below
+		ccList = new(stringList) // installed below
+
+		diff        = flags.Bool("diff", false, "show change commit diff and don't upload or mail")
+		force       = flags.Bool("f", false, "mail even if there are staged changes")
+		hashtagList = new(stringList) // installed below
+		noKeyCheck  = flags.Bool("nokeycheck", false, "set 'git push -o nokeycheck', to prevent Gerrit from checking for private keys")
+		topic       = flags.String("topic", "", "set Gerrit topic")
+		trust       = flags.Bool("trust", false, "add a Trust+1 vote to the CL")
+		trybot      = flags.Bool("trybot", false, "run trybots on the uploaded CLs")
+		wip         = flags.Bool("wip", false, "set the status of a change to Work-in-Progress")
 	)
 	flags.Var(rList, "r", "comma-separated list of reviewers")
 	flags.Var(ccList, "cc", "comma-separated list of people to CC:")
-	flags.Var(tagList, "hashtag", "comma-separated list of tags to set")
+	flags.Var(hashtagList, "hashtag", "comma-separated list of tags to set")
 
 	flags.Usage = func() {
-		fmt.Fprintf(stderr(), "Usage: %s mail %s [-r reviewer,...] [-cc mail,...] [-f] [-diff] [-hashtag tag,...] [-nokeycheck] [-topic topic] [-trust] [-trybot] [-wip] [commit]\n", os.Args[0], globalFlags)
+		fmt.Fprintf(stderr(),
+			"Usage: %s mail %s [-r reviewer,...] [-cc mail,...]\n"+
+				"\t[-f] [-diff] [-hashtag tag,...] [-nokeycheck] [-topic topic]\n"+
+				"\t[-trust] [-trybot] [-wip] [commit]\n", progName, globalFlags)
 	}
 	flags.Parse(args)
 	if len(flags.Args()) > 1 {
@@ -90,7 +95,7 @@
 
 	if !*force && HasStagedChanges() {
 		dief("there are staged changes; aborting.\n"+
-			"Use '%s change' to include them or '%s mail -f' to force it.", os.Args[0], os.Args[0])
+			"Use '%s change' to include them or '%s mail -f' to force it.", progName, progName)
 	}
 
 	if !utf8.ValidString(c.Message) {
@@ -115,8 +120,8 @@
 		refSpec += mailList(start, "cc", string(*ccList))
 		start = ","
 	}
-	if *tagList != "" {
-		for _, tag := range strings.Split(string(*tagList), ",") {
+	if *hashtagList != "" {
+		for _, tag := range strings.Split(string(*hashtagList), ",") {
 			if tag == "" {
 				dief("hashtag may not contain empty tags")
 			}
diff --git a/git-codereview/pending.go b/git-codereview/pending.go
index 2e6fe60..bd8d508 100644
--- a/git-codereview/pending.go
+++ b/git-codereview/pending.go
@@ -80,12 +80,13 @@
 }
 
 func cmdPending(args []string) {
+	// NOTE: New flags should be added to the usage message below as well as doc.go.
 	flags.BoolVar(&pendingCurrentOnly, "c", false, "show only current branch")
 	flags.BoolVar(&pendingLocal, "l", false, "use only local information - no network operations")
 	flags.BoolVar(&pendingShort, "s", false, "show short listing")
 	flags.Parse(args)
 	if len(flags.Args()) > 0 {
-		fmt.Fprintf(stderr(), "Usage: %s pending %s [-c] [-l] [-s]\n", os.Args[0], globalFlags)
+		fmt.Fprintf(stderr(), "Usage: %s pending %s [-c] [-l] [-s]\n", progName, globalFlags)
 		os.Exit(2)
 	}
 
diff --git a/git-codereview/review.go b/git-codereview/review.go
index afc61d9..0242ec7 100644
--- a/git-codereview/review.go
+++ b/git-codereview/review.go
@@ -27,102 +27,48 @@
 	noRun   = new(bool)
 )
 
+const progName = "git-codereview"
+
 func initFlags() {
 	flags = flag.NewFlagSet("", flag.ExitOnError)
 	flags.Usage = func() {
-		fmt.Fprintf(stderr(), usage, os.Args[0], os.Args[0])
+		fmt.Fprintf(stderr(), usage, progName, progName)
 	}
-	flags.Var(verbose, "v", "report commands")
 	flags.BoolVar(noRun, "n", false, "print but do not run commands")
+	flags.Var(verbose, "v", "report commands")
 }
 
 const globalFlags = "[-n] [-v]"
 
 const usage = `Usage: %s <command> ` + globalFlags + `
-Type "%s help" for more information.
+
+Use "%s help" for a list of commands.
 `
 
 const help = `Usage: %s <command> ` + globalFlags + `
 
-The git-codereview command is a wrapper for the git command that provides a
-simple interface to the "single-commit feature branch" development model.
+Git-codereview is a git helper command for managing pending commits
+against an upstream server, typically a Gerrit server.
 
-See the docs for details: https://godoc.org/golang.org/x/review/git-codereview
-
-The -v flag prints all commands that make changes.
-The -n flag prints all commands that would be run, but does not run them.
+The -n flag prints commands that would make changes but does not run them.
+The -v flag prints those commands as they run.
 
 Available commands:
 
+	branchpoint
 	change [name]
-		Create a change commit, or amend an existing change commit,
-		with the staged changes. If a branch name is provided, check
-		out that branch (creating it if it does not exist).
-		Does not amend the existing commit when switching branches.
-		If -q is specified, skip the editing of an extant pending
-		change's commit message.
-		If -a is specified, automatically add any unstaged changes in
-		tracked files during commit.
-		If -m is specified and a message given, a commit is created
-		and the editor prompt is skipped.
-
 	change NNNN[/PP]
-		Checkout the commit corresponding to CL number NNNN and
-		patch set PP from Gerrit.
-		If the patch set is omitted, use the current patch set.
-
 	gofmt [-l]
-		Run gofmt on all tracked files in the staging area and the
-		working tree.
-		If -l is specified, list files that need formatting.
-		Otherwise, reformat files in place.
-
 	help
-		Show this help text.
-
 	hooks
-		Install Git commit hooks for Gerrit and gofmt.
-		Every other operation except help also does this,
-		if they are not already installed.
-
-	mail [-f] [-r reviewer,...] [-cc mail,...] [-trybot] [-hashtag tag,...] [commit]
-		Upload change commit to the code review server and send mail
-		requesting a code review.
-		If there are multiple commits on this branch, upload commits
-		up to and including the named commit.
-		If -f is specified, upload even if there are staged changes.
-		The -r and -cc flags identify the email addresses of people to
-		do the code review and to be CC'ed about the code review.
-		Multiple addresses are given as a comma-separated list.
-		If -trybot is specified, the trybots are run on the changes,
-		if permitted.
-		The -hashtag flag applies hashtags to the code review.
-
-	mail -diff
-		Show the changes but do not send mail or upload.
-
+	mail [-r reviewer,...] [-cc mail,...] [options] [commit]
 	pending [-c] [-l] [-s]
-		Show the status of all pending changes and staged, unstaged,
-		and untracked files in the local repository.
-		If -c is specified, show only changes on the current branch.
-		If -l is specified, only use locally available information.
-		If -s is specified, show short output.
-
 	rebase-work
-		Run git rebase in interactive mode over pending changes
-		(shorthand for "git rebase -i $(git codereview branchpoint)").
-		This rebase does not incorporate any new changes from the origin
-		branch, in contrast with a normal "git rebase -i".
-
 	submit [-i | commit...]
-		Push the pending change to the Gerrit server and tell Gerrit to
-		submit it to the master branch.
-
 	sync
-		Fetch changes from the remote repository and merge them into
-		the current branch, rebasing the change commit on top of them.
 
-
+See https://pkg.go.dev/golang.org/x/review/git-codereview
+for the full details of each command.
 `
 
 func main() {
@@ -137,14 +83,19 @@
 	}
 	command, args := os.Args[1], os.Args[2:]
 
+	// NOTE: Keep this switch in sync with the list of commands above.
 	var cmd func([]string)
 	switch command {
+	default:
+		flags.Usage()
+		return // avoid installing hooks.
 	case "help":
-		fmt.Fprintf(stdout(), help, os.Args[0])
+		fmt.Fprintf(stdout(), help, progName)
 		return // avoid installing hooks.
 	case "hooks": // in case hooks weren't installed.
 		installHook(args)
 		return // avoid invoking installHook twice.
+
 	case "branchpoint":
 		cmd = cmdBranchpoint
 	case "change":
@@ -165,9 +116,6 @@
 		cmd = cmdSync
 	case "test-loadAuth": // for testing only.
 		cmd = func([]string) { loadAuth() }
-	default:
-		flags.Usage()
-		return // avoid installing hooks.
 	}
 
 	// Install hooks automatically, but only if this is a Gerrit repo.
@@ -191,7 +139,7 @@
 func expectZeroArgs(args []string, command string) {
 	flags.Parse(args)
 	if len(flags.Args()) > 0 {
-		fmt.Fprintf(stderr(), "Usage: %s %s %s\n", os.Args[0], command, globalFlags)
+		fmt.Fprintf(stderr(), "Usage: %s %s %s\n", progName, command, globalFlags)
 		os.Exit(2)
 	}
 }
@@ -381,7 +329,7 @@
 }
 
 func printf(format string, args ...interface{}) {
-	fmt.Fprintf(stderr(), "%s: %s\n", os.Args[0], fmt.Sprintf(format, args...))
+	fmt.Fprintf(stderr(), "%s: %s\n", progName, fmt.Sprintf(format, args...))
 }
 
 // count is a flag.Value that is like a flag.Bool and a flag.Int.
diff --git a/git-codereview/submit.go b/git-codereview/submit.go
index 1f6f25f..9045ea4 100644
--- a/git-codereview/submit.go
+++ b/git-codereview/submit.go
@@ -12,13 +12,12 @@
 	"time"
 )
 
-// TODO(rsc): Add -tbr, along with standard exceptions (doc/go1.5.txt)
-
 func cmdSubmit(args []string) {
+	// NOTE: New flags should be added to the usage message below as well as doc.go.
 	var interactive bool
 	flags.BoolVar(&interactive, "i", false, "interactively select commits to submit")
 	flags.Usage = func() {
-		fmt.Fprintf(stderr(), "Usage: %s submit %s [-i | commit...]\n", os.Args[0], globalFlags)
+		fmt.Fprintf(stderr(), "Usage: %s submit %s [-i | commit...]\n", progName, globalFlags)
 	}
 	flags.Parse(args)
 	if interactive && flags.NArg() > 0 {