git-review: reject empty messages in commit-msg hook

Fixes #9336

Change-Id: Ie145c116ed91cfac0eb2061c448b08c5b9595d19
Reviewed-on: https://go-review.googlesource.com/1612
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/git-review/hook.go b/git-review/hook.go
index bb5b024..7eed33f 100644
--- a/git-review/hook.go
+++ b/git-review/hook.go
@@ -12,6 +12,7 @@
 	"io/ioutil"
 	"os"
 	"path/filepath"
+	"regexp"
 	"runtime"
 )
 
@@ -108,6 +109,10 @@
 	if err != nil {
 		dief("%v", err)
 	}
+	data = stripComments(data)
+	if len(bytes.TrimSpace(data)) == 0 {
+		dief("empty commit message")
+	}
 	if bytes.Contains(data, []byte("\nChange-Id: ")) {
 		return
 	}
@@ -125,6 +130,11 @@
 	}
 }
 
+// stripComments strips lines that begin with "#".
+func stripComments(in []byte) []byte {
+	return regexp.MustCompile(`(?m)^#.*\n`).ReplaceAll(in, nil)
+}
+
 // This is NOT USED ANYMORE.
 // It is here only for comparing against old commit-hook files.
 var oldCommitMsgHook = `#!/bin/sh
diff --git a/git-review/hook_test.go b/git-review/hook_test.go
index 7770636..eaa6016 100644
--- a/git-review/hook_test.go
+++ b/git-review/hook_test.go
@@ -37,6 +37,14 @@
 	if !bytes.Equal(data, data1) {
 		t.Fatalf("second hook-invoke commit-msg changed Change-Id:\nbefore:\n%s\n\nafter:\n%s", data, data1)
 	}
+
+	// Check that hook fails when message is empty.
+	write(t, gt.client+"/empty.txt", "\n\n# just a file with\n# comments\n")
+	testMainDied(t, "hook-invoke", "commit-msg", gt.client+"/empty.txt")
+	const want = "git-review: empty commit message\n"
+	if got := stderr.String(); got != want {
+		t.Fatalf("unexpected output:\ngot: %q\nwant: %q", got, want)
+	}
 }
 
 func TestHooks(t *testing.T) {