git-codereview: add -m option

The -m option allows a user to specify an inline commit
message. This is useful for a few reasons; primary among
them are the ability to easily automate a `git change`
flow (e.g. in a CI/CD workflow) and the ease of creating
one-liner commits (e.g. "regen protos").

Fixes golang/go#24912

Change-Id: Ie06886c74552ec615623c2faac285a1896bdac06
Reviewed-on: https://go-review.googlesource.com/c/107625
Run-TryBot: Yury Smolsky <yury@smolsky.by>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Yury Smolsky <yury@smolsky.by>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
diff --git a/git-codereview/change.go b/git-codereview/change.go
index 35fa519..790d4e6 100644
--- a/git-codereview/change.go
+++ b/git-codereview/change.go
@@ -12,10 +12,12 @@
 	"strings"
 )
 
+var commitMsg string
 var changeAuto bool
 var changeQuick bool
 
 func cmdChange(args []string) {
+	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)
@@ -90,7 +92,9 @@
 				args = append(args, "--no-edit")
 			}
 		}
-		if testCommitMsg != "" {
+		if commitMsg != "" {
+			args = append(args, "-m", commitMsg)
+		} else if testCommitMsg != "" {
 			args = append(args, "-m", testCommitMsg)
 		}
 		if changeAuto {
diff --git a/git-codereview/change_test.go b/git-codereview/change_test.go
index 531f90e..8e111be 100644
--- a/git-codereview/change_test.go
+++ b/git-codereview/change_test.go
@@ -154,3 +154,12 @@
 	checkChangeCL("100/2", "refs/changes/00/100/2", hash2)
 	checkChangeCL("100", "refs/changes/00/100/3", hash1)
 }
+
+func TestChangeWithMessage(t *testing.T) {
+	gt := newGitTest(t)
+	defer gt.done()
+
+	testMain(t, "change", "new_branch")
+	testMain(t, "change", "-m", "foo: some commit message")
+	testRan(t, "git commit -q --allow-empty -m foo: some commit message")
+}
diff --git a/git-codereview/doc.go b/git-codereview/doc.go
index 5b87283..7624909 100644
--- a/git-codereview/doc.go
+++ b/git-codereview/doc.go
@@ -120,7 +120,7 @@
 The change command creates and moves between Git branches and maintains the
 pending changes on work branches.
 
-	git codereview change [-a] [-q] [branchname]
+	git codereview change [-a] [-q] [-m <message>] [branchname]
 
 Given a branch name as an argument, the change command switches to the named
 branch, creating it if necessary. If the branch is created and there are staged
@@ -132,10 +132,16 @@
 amends that change.
 
 The -q option skips the editing of an extant pending change's commit message.
+If -m is present, -q is ignored.
 
 The -a option automatically adds any unstaged edits in tracked files during
 commit; it is equivalent to the 'git commit' -a option.
 
+The -m option specifies a commit message and skips the editor prompt. This
+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.
+
 Gofmt
 
 The gofmt command applies the gofmt program to all files modified in the
diff --git a/git-codereview/review.go b/git-codereview/review.go
index a60e548..147733f 100644
--- a/git-codereview/review.go
+++ b/git-codereview/review.go
@@ -63,6 +63,8 @@
 		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