aboutsummaryrefslogtreecommitdiff
path: root/git-codereview/submit.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2015-11-05 16:02:35 -0500
committerAustin Clements <austin@google.com>2015-11-11 00:38:01 +0000
commit7cc8d7720ed2e3ca6aba0cea191b9e19690dc9f7 (patch)
treef44204abf453f4c17c7f8e9ea6c6411d433983f0 /git-codereview/submit.go
parenta993a2d94a08a2ae58d984e48613d4ff387adf57 (diff)
downloadgo-x-review-7cc8d7720ed2e3ca6aba0cea191b9e19690dc9f7.tar.xz
git-codereview: add interactive mode to submit
This adds a -i option to submit that brings up a list of commits to submit in an editor (a la git rebase -i), lets the user edit the list, and then submits the specified commits in the specified order. Change-Id: I88149140527c987ae856aac2598f0a992fe5654d Reviewed-on: https://go-review.googlesource.com/16677 Reviewed-by: Andrew Gerrand <adg@golang.org>
Diffstat (limited to 'git-codereview/submit.go')
-rw-r--r--git-codereview/submit.go75
1 files changed, 73 insertions, 2 deletions
diff --git a/git-codereview/submit.go b/git-codereview/submit.go
index f6b48d4..809bbe7 100644
--- a/git-codereview/submit.go
+++ b/git-codereview/submit.go
@@ -5,22 +5,39 @@
package main
import (
+ "bytes"
"fmt"
"os"
+ "strings"
"time"
)
// TODO(rsc): Add -tbr, along with standard exceptions (doc/go1.5.txt)
func cmdSubmit(args []string) {
+ var interactive bool
+ flags.BoolVar(&interactive, "i", false, "interactively select commits to submit")
flags.Usage = func() {
- fmt.Fprintf(stderr(), "Usage: %s submit %s [commit-hash...]\n", os.Args[0], globalFlags)
+ fmt.Fprintf(stderr(), "Usage: %s submit %s [-i | commit-hash...]\n", os.Args[0], globalFlags)
}
flags.Parse(args)
+ if interactive && flags.NArg() > 0 {
+ flags.Usage()
+ os.Exit(2)
+ }
b := CurrentBranch()
var cs []*Commit
- if args := flags.Args(); len(args) >= 1 {
+ if interactive {
+ hashes := submitHashes(b)
+ if len(hashes) == 0 {
+ printf("nothing to submit")
+ return
+ }
+ for _, hash := range hashes {
+ cs = append(cs, b.CommitByHash("submit", hash))
+ }
+ } else if args := flags.Args(); len(args) >= 1 {
for _, arg := range args {
cs = append(cs, b.CommitByHash("submit", arg))
}
@@ -179,3 +196,57 @@ func submitCheck(g *GerritChange) error {
return nil
}
+
+// submitHashes interactively prompts for commits to submit.
+func submitHashes(b *Branch) []string {
+ // Get pending commits on b.
+ pending := b.Pending()
+ for _, c := range pending {
+ // Note that DETAILED_LABELS does not imply LABELS.
+ c.g, c.gerr = b.GerritChange(c, "CURRENT_REVISION", "LABELS", "DETAILED_LABELS")
+ if c.g == nil {
+ c.g = new(GerritChange)
+ }
+ }
+
+ // Construct submit script.
+ var script bytes.Buffer
+ for i := len(pending) - 1; i >= 0; i-- {
+ c := pending[i]
+
+ if c.g.ID == "" {
+ fmt.Fprintf(&script, "# change not on Gerrit:\n#")
+ } else if err := submitCheck(c.g); err != nil {
+ fmt.Fprintf(&script, "# %v:\n#", err)
+ }
+
+ formatCommit(&script, c, true)
+ }
+
+ fmt.Fprintf(&script, `
+# The above commits will be submitted in order from top to bottom
+# when you exit the editor.
+#
+# These lines can be re-ordered, removed, and commented out.
+#
+# If you remove all lines, the submit will be aborted.
+`)
+
+ // Edit the script.
+ final := editor(script.String())
+
+ // Parse the final script.
+ var hashes []string
+ for _, line := range lines(final) {
+ line := strings.TrimSpace(line)
+ if len(line) == 0 || line[0] == '#' {
+ continue
+ }
+ if i := strings.Index(line, " "); i >= 0 {
+ line = line[:i]
+ }
+ hashes = append(hashes, line)
+ }
+
+ return hashes
+}