// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"net/url"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strings"

	"fuchsia.googlesource.com/jiri"
	"fuchsia.googlesource.com/jiri/cmdline"
	"fuchsia.googlesource.com/jiri/collect"
	"fuchsia.googlesource.com/jiri/gerrit"
	"fuchsia.googlesource.com/jiri/gitutil"
	"fuchsia.googlesource.com/jiri/project"
	"fuchsia.googlesource.com/jiri/runutil"
)

const (
	commitMessageFileName     = ".gerrit_commit_message"
	dependencyPathFileName    = ".dependency_path"
	multiPartMetaDataFileName = "multipart_index"
)

var (
	autosubmitFlag        bool
	ccsFlag               string
	draftFlag             bool
	editFlag              bool
	forceFlag             bool
	hostFlag              string
	messageFlag           string
	commitMessageBodyFlag string
	presubmitFlag         string
	remoteBranchFlag      string
	reviewersFlag         string
	setTopicFlag          bool
	topicFlag             string
	uncommittedFlag       bool
	verifyFlag            bool
	currentProjectFlag    bool
	cleanupMultiPartFlag  bool
	branchFlag            string
	deleteFlag            bool
)

// Special labels stored in the commit message.
var (
	// Auto submit label.
	autosubmitLabelRE *regexp.Regexp = regexp.MustCompile("AutoSubmit")

	// Change-Ids start with 'I' and are followed by 40 characters of hex.
	changeIDRE *regexp.Regexp = regexp.MustCompile("Change-Id: (I[0123456789abcdefABCDEF]{40})")

	// MultiPart messages are of the form: MultiPart: <n>/<m>
	multiPartRE *regexp.Regexp = regexp.MustCompile(`(?m)^MultiPart: \d+/\d+$`)

	// Presubmit test label.
	// PresubmitTest: <type>
	presubmitTestLabelRE *regexp.Regexp = regexp.MustCompile(`PresubmitTest:\s*(.*)`)

	noChangesRE *regexp.Regexp = regexp.MustCompile(`! \[remote rejected\] HEAD -> refs/(for|drafts)/\S+ \(no new changes\)`)
)

// init carries out the package initialization.
func init() {
	cmdCLUpload = newCmdCLUpload("upload", runCLUpload)
	cmdCLMail = newCmdCLUpload("mail", runCLMail)
	cmdCL = newCmdCL()
	cmdCLCleanup.Flags.BoolVar(&forceFlag, "f", false, `Ignore unmerged changes.`)
	cmdCLCleanup.Flags.StringVar(&remoteBranchFlag, "remote-branch", "master", `Name of the remote branch the CL pertains to, without the leading "origin/".`)
	cmdCLSync.Flags.StringVar(&remoteBranchFlag, "remote-branch", "master", `Name of the remote branch the CL pertains to, without the leading "origin/".`)
}

func getCommitMessageFileName(jirix *jiri.X, branch string) (string, error) {
	topLevel, err := gitutil.New(jirix).TopLevel()
	if err != nil {
		return "", err
	}
	return filepath.Join(topLevel, jiri.ProjectMetaDir, branch, commitMessageFileName), nil
}

func getDependencyPathFileName(jirix *jiri.X, branch string) (string, error) {
	topLevel, err := gitutil.New(jirix).TopLevel()
	if err != nil {
		return "", err
	}
	return filepath.Join(topLevel, jiri.ProjectMetaDir, branch, dependencyPathFileName), nil
}

func getDependentCLs(jirix *jiri.X, branch string) ([]string, error) {
	file, err := getDependencyPathFileName(jirix, branch)
	if err != nil {
		return nil, err
	}
	data, err := jirix.NewSeq().ReadFile(file)
	var branches []string
	if err != nil {
		if !runutil.IsNotExist(err) {
			return nil, err
		}
		if branch != remoteBranchFlag {
			branches = []string{remoteBranchFlag}
		}
	} else {
		branches = strings.Split(strings.TrimSpace(string(data)), "\n")
	}
	return branches, nil
}

// cmdCL represents the "jiri cl" command.
var cmdCL *cmdline.Command

// Use a factory to avoid an initialization loop between between the
// Runner function and the ParsedFlags field in the Command.
func newCmdCL() *cmdline.Command {
	return &cmdline.Command{
		Name:     "cl",
		Short:    "Manage changelists for multiple projects(deprecated, use jiri upload)",
		Long:     "Manage changelists for multiple projects. This has been deprecated, please use jiri upload",
		Children: []*cmdline.Command{cmdCLCleanup, cmdCLMail, cmdCLNew, cmdCLSync, cmdCLUpload},
	}
}

// cmdCLCleanup represents the "jiri cl cleanup" command.
//
// TODO(jsimsa): Replace this with a "submit" command that talks to
// Gerrit to submit the CL and then (optionally) removes it locally.
var cmdCLCleanup = &cmdline.Command{
	Runner: jiri.RunnerFunc(runCLCleanup),
	Name:   "cleanup",
	Short:  "Clean up changelists that have been merged(deprecated, use jiri upload)",
	Long: `
Command "cleanup" checks that the given branches have been merged into
the corresponding remote branch. If a branch differs from the
corresponding remote branch, the command reports the difference and
stops. Otherwise, it deletes the given branches.
`,
	ArgsName: "<branches>",
	ArgsLong: "<branches> is a list of branches to cleanup.",
}

func cleanupCL(jirix *jiri.X, branches []string) (e error) {
	git := gitutil.New(jirix)
	originalBranch, err := git.CurrentBranchName()
	if err != nil {
		return err
	}
	stashed, err := git.Stash()
	if err != nil {
		return err
	}
	if stashed {
		defer collect.Error(func() error { return git.StashPop() }, &e)
	}
	if err := git.CheckoutBranch(remoteBranchFlag); err != nil {
		return err
	}
	checkoutOriginalBranch := true
	defer collect.Error(func() error {
		if checkoutOriginalBranch {
			return git.CheckoutBranch(originalBranch)
		}
		return nil
	}, &e)
	if err := git.FetchRefspec("origin", remoteBranchFlag); err != nil {
		return err
	}
	s := jirix.NewSeq()
	for _, branch := range branches {
		cleanupFn := func() error { return cleanupBranch(jirix, branch) }
		if err := s.Call(cleanupFn, "Cleaning up branch: %s", branch).Done(); err != nil {
			return err
		}
		if branch == originalBranch {
			checkoutOriginalBranch = false
		}
	}
	return nil
}

func cleanupBranch(jirix *jiri.X, branch string) error {
	git := gitutil.New(jirix)
	if err := git.CheckoutBranch(branch); err != nil {
		return err
	}
	if !forceFlag {
		trackingBranch := "origin/" + remoteBranchFlag
		if err := git.Merge(trackingBranch); err != nil {
			return err
		}
		files, err := git.ModifiedFiles(trackingBranch, branch)
		if err != nil {
			return err
		}
		if len(files) != 0 {
			return fmt.Errorf("unmerged changes in\n%s", strings.Join(files, "\n"))
		}
	}
	if err := git.CheckoutBranch(remoteBranchFlag); err != nil {
		return err
	}
	if err := git.DeleteBranch(branch, gitutil.ForceOpt(true)); err != nil {
		return err
	}
	reviewBranch := branch + "-REVIEW"
	if git.BranchExists(reviewBranch) {
		if err := git.DeleteBranch(reviewBranch, gitutil.ForceOpt(true)); err != nil {
			return err
		}
	}
	// Delete branch metadata.
	topLevel, err := git.TopLevel()
	if err != nil {
		return err
	}
	s := jirix.NewSeq()
	// Remove the branch from all dependency paths.
	metadataDir := filepath.Join(topLevel, jiri.ProjectMetaDir)
	fileInfos, err := s.RemoveAll(filepath.Join(metadataDir, branch)).
		ReadDir(metadataDir)
	if err != nil {
		return err
	}
	for _, fileInfo := range fileInfos {
		if !fileInfo.IsDir() {
			continue
		}
		file, err := getDependencyPathFileName(jirix, fileInfo.Name())
		if err != nil {
			return err
		}
		data, err := s.ReadFile(file)
		if err != nil {
			if !runutil.IsNotExist(err) {
				return err
			}
			continue
		}
		branches := strings.Split(string(data), "\n")
		for i, tmpBranch := range branches {
			if branch == tmpBranch {
				data := []byte(strings.Join(append(branches[:i], branches[i+1:]...), "\n"))
				if err := s.WriteFile(file, data, os.FileMode(0644)).Done(); err != nil {
					return err
				}
				break
			}
		}
	}
	return nil
}

func runCLCleanup(jirix *jiri.X, args []string) error {
	jirix.Logger.Warningf("jiri cl has been deprecated please use jiri upload. It will be removed soon.")
	if len(args) == 0 {
		return jirix.UsageErrorf("cleanup requires at least one argument")
	}
	return cleanupCL(jirix, args)
}

// cmdCLUpload represents the "jiri cl upload" command.
var cmdCLUpload *cmdline.Command
var cmdCLMail *cmdline.Command

// Use a factory to avoid an initialization loop between between the
// Runner function and the ParsedFlags field in the Command.
func newCmdCLUpload(name string, runner func(*jiri.X, []string) error) *cmdline.Command {
	cmdCLUpload := &cmdline.Command{
		Runner: jiri.RunnerFunc(runner),
		Name:   name,
		Short:  "Upload a changelist for review(deprecated, use jiri upload)",
		Long: `
Command "upload" squashes all commits of a local branch into a single
"changelist" and uploads this changelist to Gerrit as a single
commit. First time the command is invoked, it generates a Change-Id
for the changelist, which is appended to the commit
message. Consecutive invocations of the command use the same Change-Id
by default, informing Gerrit that the incomming commit is an update of
an existing changelist.
`,
	}
	cmdCLUpload.Flags.BoolVar(&autosubmitFlag, "autosubmit", false, `Automatically submit the changelist when feasible.`)
	cmdCLUpload.Flags.StringVar(&ccsFlag, "cc", "", `Comma-seperated list of emails or LDAPs to cc.`)
	cmdCLUpload.Flags.BoolVar(&draftFlag, "d", false, `Send a draft changelist.`)
	cmdCLUpload.Flags.BoolVar(&editFlag, "edit", true, `Open an editor to edit the CL description.`)
	cmdCLUpload.Flags.StringVar(&hostFlag, "host", "", `Gerrit host to use.  Defaults to gerrit host specified in manifest.`)
	cmdCLUpload.Flags.StringVar(&messageFlag, "m", "", `CL description.`)
	cmdCLUpload.Flags.StringVar(&commitMessageBodyFlag, "commit-message-body-file", "", `file containing the body of the CL description, that is, text without a ChangeID, MultiPart etc.`)
	cmdCLUpload.Flags.StringVar(&presubmitFlag, "presubmit", string(gerrit.PresubmitTestTypeAll),
		fmt.Sprintf("The type of presubmit tests to run. Valid values: %s.", strings.Join(gerrit.PresubmitTestTypes(), ",")))
	cmdCLUpload.Flags.StringVar(&remoteBranchFlag, "remote-branch", "master", `Name of the remote branch the CL pertains to, without the leading "origin/".`)
	cmdCLUpload.Flags.StringVar(&reviewersFlag, "r", "", `Comma-seperated list of emails or LDAPs to request review.`)
	cmdCLUpload.Flags.BoolVar(&setTopicFlag, "set-topic", true, `Set Gerrit CL topic.`)
	cmdCLUpload.Flags.StringVar(&topicFlag, "topic", "", `CL topic, defaults to <username>-<branchname>.`)
	cmdCLUpload.Flags.BoolVar(&uncommittedFlag, "check-uncommitted", true, `Check that no uncommitted changes exist.`)
	cmdCLUpload.Flags.BoolVar(&verifyFlag, "verify", true, `Run pre-push git hooks.`)
	cmdCLUpload.Flags.BoolVar(&currentProjectFlag, "current-project-only", false, `Run upload in the current project only.`)
	cmdCLUpload.Flags.BoolVar(&cleanupMultiPartFlag, "clean-multipart-metadata", false, `Cleanup the metadata associated with multipart CLs pertaining the MultiPart: x/y message without uploading any CLs.`)
	return cmdCLUpload
}

type changeConflictError struct {
	localBranch  string
	message      string
	remoteBranch string
}

func (e changeConflictError) Error() string {
	result := "changelist conflicts with the remote " + e.remoteBranch + " branch\n\n"
	result += "To resolve this problem, run 'git pull origin " + e.remoteBranch + ":" + e.localBranch + "',\n"
	result += "resolve the conflicts identified below, and then try again.\n"
	result += e.message
	return result
}

type emptyChangeError struct{}

func (_ emptyChangeError) Error() string {
	return "current branch has no commits"
}

type gerritError string

func (e gerritError) Error() string {
	result := "sending code review failed\n\n"
	result += string(e)
	return result
}

type noChangeIDError struct{}

func (_ noChangeIDError) Error() string {
	result := "changelist is missing a Change-ID"
	return result
}

type uncommittedChangesError []string

func (e uncommittedChangesError) Error() string {
	result := "uncommitted local changes in files:\n"
	result += "  " + strings.Join(e, "\n  ")
	return result
}

var defaultMessageHeader = `
# Describe your changelist, specifying what package(s) your change
# pertains to, followed by a short summary and, in case of non-trivial
# changelists, provide a detailed description.
#
# For example:
#
# rpc/stream/proxy: add publish address
#
# The listen address is not always the same as the address that external
# users need to connect to. This CL adds a new argument to proxy.New()
# to specify the published address that clients should connect to.

# FYI, you are about to submit the following local commits for review:
#
`

// currentProject returns the Project containing the current working directory.
// The current working directory must be inside root.
func currentProject(jirix *jiri.X) (project.Project, error) {
	dir, err := os.Getwd()
	if err != nil {
		return project.Project{}, fmt.Errorf("os.Getwd() failed: %v", err)
	}

	// Walk up the path until we find a project at that path, or hit the jirix.Root.
	// Note that we can't just compare path prefixes because of soft links.
	for dir != jirix.Root && dir != string(filepath.Separator) {
		p, err := project.ProjectAtPath(jirix, dir)
		if err != nil {
			dir = filepath.Dir(dir)
			continue
		}
		return p, nil
	}
	return project.Project{}, fmt.Errorf("directory %q is not contained in a project", dir)
}

type multiPart struct {
	clean, current bool
	currentKey     project.ProjectKey
	currentBranch  string
	states         map[project.ProjectKey]*project.ProjectState
	keys           project.ProjectKeys
}

// initForMultiPart determines the actions to be taken
// based on command line flags and project state.
func initForMultiPart(jirix *jiri.X) (*multiPart, error) {
	mp := &multiPart{}
	mp.clean = cleanupMultiPartFlag
	if currentProjectFlag {
		mp.current = true
		return mp, nil
	}
	if mp.clean {
		states, keys, err := projectStates(jirix, true)
		if err != nil {
			return nil, err
		}
		mp.states = states
		mp.keys = keys
		return mp, nil
	}
	states, keys, err := projectStates(jirix, false)
	if err != nil {
		return nil, err
	}
	if len(states) == 0 {
		return nil, fmt.Errorf("Failed to find any projects")
	}
	current, err := currentProject(jirix)
	if err != nil {
		return nil, err
	}
	mp.currentKey = current.Key()
	mp.currentBranch = states[mp.currentKey].CurrentBranch.Name
	if len(keys) == 1 {
		filename := filepath.Join(states[keys[0]].Project.Path, jiri.ProjectMetaDir, mp.currentBranch, multiPartMetaDataFileName)
		os.Remove(filename)
		if mp.currentKey == states[keys[0]].Project.Key() {
			mp.current = true
			return mp, nil
		}
	}
	mp.states = states
	mp.keys = keys
	return mp, nil
}

// projectStates returns a map with all projects that are on the same
// current branch as the current project, as well as a slice of their
// project keys sorted lexicographically. Unless "allowdirty" is true,
// an error is returned if any matching project has uncommitted changes.
// The keys are returned, sorted, to avoid the caller having to recreate
// the them by iterating over the map.
func projectStates(jirix *jiri.X, allowdirty bool) (map[project.ProjectKey]*project.ProjectState, project.ProjectKeys, error) {
	git := gitutil.New(jirix)
	branch, err := git.CurrentBranchName()
	if err != nil {
		return nil, nil, err
	}
	projects, err := project.LocalProjects(jirix, project.FastScan)
	if err != nil {
		return nil, nil, err
	}
	states, err := project.GetProjectStates(jirix, projects, false)
	if err != nil {
		return nil, nil, err
	}
	uncommitted := []string{}
	var keys project.ProjectKeys
	for _, s := range states {
		if s.CurrentBranch.Name == branch {
			key := s.Project.Key()
			fullState, err := project.GetProjectState(jirix, key, true)
			if err != nil {
				return nil, nil, err
			}
			if !allowdirty && fullState.HasUncommitted {
				uncommitted = append(uncommitted, string(key))
			} else {
				keys = append(keys, key)
			}
		}
	}
	if len(uncommitted) > 0 {
		return nil, nil, fmt.Errorf("the following projects have uncommitted changes: %s", strings.Join(uncommitted, ", "))
	}
	members := map[project.ProjectKey]*project.ProjectState{}
	for _, key := range keys {
		members[key] = states[key]
	}
	if len(members) == 0 {
		return nil, nil, nil
	}
	sort.Sort(keys)
	return members, keys, nil
}

func (mp *multiPart) writeMultiPartMetadata(jirix *jiri.X) error {
	total := len(mp.states)
	index := 1
	s := jirix.NewSeq()
	for _, key := range mp.keys {
		state := mp.states[key]
		dir := filepath.Join(state.Project.Path, jiri.ProjectMetaDir, mp.currentBranch)
		filename := filepath.Join(dir, multiPartMetaDataFileName)
		if total < 2 {
			os.Remove(filename)
			continue
		}
		msg := fmt.Sprintf("MultiPart: %d/%d\n", index, total)
		if err := s.MkdirAll(dir, os.FileMode(0755)).
			WriteFile(filename, []byte(msg), os.FileMode(0644)).
			Done(); err != nil {
			return err
		}
		index++
	}
	return nil
}

func (mp *multiPart) cleanMultiPartMetadata(jirix *jiri.X) error {
	s := jirix.NewSeq()
	for _, state := range mp.states {
		filename := filepath.Join(state.Project.Path, jiri.ProjectMetaDir, mp.currentBranch, multiPartMetaDataFileName)
		ok, err := s.IsFile(filename)
		if err != nil {
			return err
		}
		if ok {
			if err := s.Remove(filename).Done(); err != nil {
				return err
			}
		}
	}
	return nil
}

func (mp *multiPart) commandline(excludeKey project.ProjectKey, flags []string) []string {
	keyflag := "--projects="
	for _, k := range mp.keys {
		if k == excludeKey {
			continue
		}
		keyflag += string(k) + ","
	}
	keyflag = strings.TrimSuffix(keyflag, ",")
	clargs := []string{
		"runp",
		"--interactive",
		keyflag,
	}
	clargs = append(clargs, "jiri", "cl", "upload", "--current-project-only=true")
	return append(clargs, flags...)
}

// clUploadMultiFlags extracts flags from the invocation of cl upload
// that should be passed on to the sub invocations of cl upload when
// operating across multiple repos.
// These are:
// -autosubmit, -cc, -d, -edit, -host, -m, -presubmit, remote-branch, -r,
// -set-topic, -topic, -check-uncommitted and -verify,
func clUploadMultiFlags() []string {
	flags := []string{}
	stringFlag := func(name, value string) {
		if isFlagSet(cmdCLUpload.ParsedFlags, name) {
			flags = append(flags, fmt.Sprintf("--%s=%s", name, value))
		}
	}
	boolFlag := func(name string, value bool) {
		if isFlagSet(cmdCLUpload.ParsedFlags, name) {
			flags = append(flags, fmt.Sprintf("--%s=%t", name, value))
		}
	}

	// --edit is handled differently to other flags, if it is not
	// specifically set, the default is to run the editor once
	// and then reuse that message for the other parts of a multipart
	// CL - that is, set -edit=false for the other repos. If edit
	// is specifically set then that setting is used for all repos.
	// So using --edit=true allows for a different CL message in
	// each repo of a multipart CL.
	if isFlagSet(cmdCLUpload.ParsedFlags, "edit") {
		// if --edit is set on the command line, use that value
		// for all subcommands
		flags = append(flags, fmt.Sprintf("--edit=%t", editFlag))
	} else {
		// if --edit is not set on the command line, use --edit=false
		// for subcommands.
		flags = append(flags, "--edit=false")
	}

	boolFlag("autosubmit", autosubmitFlag)
	stringFlag("cc", ccsFlag)
	boolFlag("d", draftFlag)
	stringFlag("host", hostFlag)
	stringFlag("m", messageFlag)
	stringFlag("presubmit", presubmitFlag)
	stringFlag("remote-branch", remoteBranchFlag)
	stringFlag("r", reviewersFlag)
	boolFlag("set-topic", setTopicFlag)
	boolFlag("check-uncommitted", uncommittedFlag)
	boolFlag("verify", verifyFlag)
	return flags
}

// runCLMail is a wrapper around runCLUpload
func runCLMail(jirix *jiri.X, args []string) error {
	jirix.Logger.Warningf("jiri cl has been deprecated please use jiri upload. It will be removed soon.")
	return runCLUpload(jirix, args)
}

// runCLUpload is a wrapper that sets up and runs a review instance across
// multiple projects.
func runCLUpload(jirix *jiri.X, _ []string) error {
	jirix.Logger.Warningf("jiri cl has been deprecated please use jiri upload. It will be removed soon.")
	mp, err := initForMultiPart(jirix)
	if err != nil {
		return err
	}
	if mp.clean {
		if err := mp.cleanMultiPartMetadata(jirix); err != nil {
			return err
		}
		return nil
	}
	if mp.current {
		return runCLUploadCurrent(jirix, []string{})
	}
	// multipart mode
	if err := mp.writeMultiPartMetadata(jirix); err != nil {
		mp.cleanMultiPartMetadata(jirix)
		return err
	}
	if err := runCLUploadCurrent(jirix, []string{}); err != nil {
		return err
	}
	git := gitutil.New(jirix)
	branch, err := git.CurrentBranchName()
	if err != nil {
		return err
	}
	initialMessage, err := strippedGerritCommitMessage(jirix, branch)
	if err != nil {
		return err
	}
	s := jirix.NewSeq()
	tmp, err := s.TempFile("", branch+"-")
	if err != nil {
		return err
	}
	defer func() {
		tmp.Close()
		os.Remove(tmp.Name())
	}()
	if _, err := io.WriteString(tmp, initialMessage); err != nil {
		return err
	}
	// Use Capture to make sure that all output from the subcommands is
	// sent to stdout/stderr.
	flags := clUploadMultiFlags()
	flags = append(flags, "--commit-message-body-file="+tmp.Name())
	return s.Capture(jirix.Stdout(), jirix.Stderr()).Last("jiri", mp.commandline(mp.currentKey, flags)...)
}

func runCLUploadCurrent(jirix *jiri.X, _ []string) error {
	jirix.Logger.Warningf("jiri cl has been deprecated please use jiri upload. It will be removed soon.")
	// Check that working dir exist on remote branch.  Otherwise checking out
	// remote branch will break the users working dir.
	git := gitutil.New(jirix)
	wd, err := os.Getwd()
	if err != nil {
		return err
	}
	topLevel, err := git.TopLevel()
	if err != nil {
		return err
	}
	relWd, err := filepath.Rel(topLevel, wd)
	if err != nil {
		return err
	}
	if !git.DirExistsOnBranch(relWd, remoteBranchFlag) {
		return fmt.Errorf("directory %q does not exist on branch %q.\nPlease run 'jiri cl upload' from root directory of this repo.", relWd, remoteBranchFlag)
	}

	// Sanity checks for the <presubmitFlag> flag.
	if !checkPresubmitFlag() {
		return jirix.UsageErrorf("invalid value for the -presubmit flag. Valid values: %s.",
			strings.Join(gerrit.PresubmitTestTypes(), ","))
	}

	p, err := currentProject(jirix)
	if err != nil {
		return err
	}

	host := hostFlag
	if host == "" {
		if p.GerritHost == "" {
			return fmt.Errorf("No gerrit host found.  Please use the '--host' flag, or add a 'gerrithost' attribute for project %q.", p.Name)
		}
		host = p.GerritHost
	}
	hostUrl, err := url.Parse(host)
	if err != nil {
		return fmt.Errorf("invalid Gerrit host %q: %v", host, err)
	}
	projectRemoteUrl, err := url.Parse(p.Remote)
	if err != nil {
		return fmt.Errorf("invalid project remote: %v", p.Remote, err)
	}
	gerritRemote := *hostUrl
	gerritRemote.Path = projectRemoteUrl.Path
	topic := topicFlag

	// Create and run the review.
	review, err := newReview(jirix, git, p, gerrit.CLOpts{
		Autosubmit:   autosubmitFlag,
		Ccs:          parseEmails(ccsFlag),
		Draft:        draftFlag,
		Edit:         editFlag,
		Remote:       gerritRemote.String(),
		Host:         hostUrl,
		Presubmit:    gerrit.PresubmitTestType(presubmitFlag),
		RemoteBranch: remoteBranchFlag,
		Topic:        topic,
		Reviewers:    parseEmails(reviewersFlag),
		Verify:       verifyFlag,
	})
	if err != nil {
		return err
	}
	if confirmed, err := review.confirmFlagChanges(); err != nil {
		return err
	} else if !confirmed {
		return nil
	}
	err = review.run(git)
	// Ignore the error that is returned when there are no differences
	// between the local and gerrit branches.
	if err != nil && noChangesRE.MatchString(err.Error()) {
		return nil
	}
	return err
}

// parseEmails input a list of comma separated tokens and outputs a
// list of email addresses. The tokens can either be email addresses
// or Google LDAPs in which case the suffix @google.com is appended to
// them to turn them into email addresses.
func parseEmails(value string) []string {
	var emails []string
	tokens := strings.Split(value, ",")
	for _, token := range tokens {
		if token == "" {
			continue
		}
		if !strings.Contains(token, "@") {
			token += "@google.com"
		}
		emails = append(emails, token)
	}
	return emails
}

// checkDependents makes sure that all CLs in the sequence of
// dependent CLs leading to (but not including) the current branch
// have been exported to Gerrit.
func checkDependents(jirix *jiri.X) (e error) {
	originalBranch, err := gitutil.New(jirix).CurrentBranchName()
	if err != nil {
		return err
	}
	branches, err := getDependentCLs(jirix, originalBranch)
	if err != nil {
		return err
	}
	for i := 1; i < len(branches); i++ {
		file, err := getCommitMessageFileName(jirix, branches[i])
		if err != nil {
			return err
		}
		if _, err := jirix.NewSeq().Stat(file); err != nil {
			if !runutil.IsNotExist(err) {
				return err
			}
			return fmt.Errorf(`Failed to export the branch %q to Gerrit because its ancestor %q has not been exported to Gerrit yet.
The following steps are needed before the operation can be retried:
$ git checkout %v
$ jiri cl upload
$ git checkout %v
# retry the original command
`, originalBranch, branches[i], branches[i], originalBranch)
		}
	}

	return nil
}

type review struct {
	jirix         *jiri.X
	featureBranch string
	reviewBranch  string
	project       project.Project
	gerrit.CLOpts
}

func newReview(jirix *jiri.X, git *gitutil.Git, project project.Project, opts gerrit.CLOpts) (*review, error) {
	// Sync all CLs in the sequence of dependent CLs ending in the
	// current branch.
	if err := syncCL(jirix, git); err != nil {
		return nil, err
	}

	// Make sure that all CLs in the above sequence (possibly except for
	// the current branch) have been exported to Gerrit. This is needed
	// to make sure we have commit messages for all but the last CL.
	//
	// NOTE: The alternative here is to prompt the user for multiple
	// commit messages, which seems less user friendly.
	if err := checkDependents(jirix); err != nil {
		return nil, err
	}

	branch, err := gitutil.New(jirix).CurrentBranchName()
	if err != nil {
		return nil, err
	}
	opts.Branch = branch
	if setTopicFlag && opts.Topic == "" {
		opts.Topic = fmt.Sprintf("%s-%s", os.Getenv("USER"), branch) // use <username>-<branchname> as the default
	} else if !setTopicFlag {
		opts.Topic = ""
	}
	if opts.Presubmit == gerrit.PresubmitTestType("") {
		opts.Presubmit = gerrit.PresubmitTestTypeAll // use gerrit.PresubmitTestTypeAll as the default
	}
	if opts.RemoteBranch == "" {
		opts.RemoteBranch = "master" // use master as the default
	}
	return &review{
		jirix:         jirix,
		project:       project,
		featureBranch: branch,
		reviewBranch:  branch + "-REVIEW",
		CLOpts:        opts,
	}, nil
}

func checkPresubmitFlag() bool {
	for _, t := range gerrit.PresubmitTestTypes() {
		if presubmitFlag == t {
			return true
		}
	}
	return false
}

// confirmFlagChanges asks users to confirm if any of the
// presubmit and autosubmit flags changes.
func (review *review) confirmFlagChanges() (bool, error) {
	file, err := getCommitMessageFileName(review.jirix, review.CLOpts.Branch)
	if err != nil {
		return false, err
	}
	bytes, err := review.jirix.NewSeq().ReadFile(file)
	if err != nil {
		if runutil.IsNotExist(err) {
			return true, nil
		}
		return false, err
	}
	content := string(bytes)
	changes := []string{}

	// Check presubmit label change.
	prevPresubmitType := string(gerrit.PresubmitTestTypeAll)
	matches := presubmitTestLabelRE.FindStringSubmatch(content)
	if matches != nil {
		prevPresubmitType = matches[1]
	}
	if presubmitFlag != prevPresubmitType {
		changes = append(changes, fmt.Sprintf("- presubmit=%s to presubmit=%s", prevPresubmitType, presubmitFlag))
	}

	// Check autosubmit label change.
	prevAutosubmit := autosubmitLabelRE.MatchString(content)
	if autosubmitFlag != prevAutosubmit {
		changes = append(changes, fmt.Sprintf("- autosubmit=%v to autosubmit=%v", prevAutosubmit, autosubmitFlag))

	}

	if len(changes) > 0 {
		fmt.Printf("Changes:\n%s\n", strings.Join(changes, "\n"))
		fmt.Print("Are you sure you want to make the above changes? y/N:")
		var response string
		if _, err := fmt.Scanf("%s\n", &response); err != nil || response != "y" {
			return false, nil
		}
	}
	return true, nil
}

// cleanup cleans up after the review.
func (review *review) cleanup(stashed bool) error {
	git := gitutil.New(review.jirix)
	if err := git.CheckoutBranch(review.CLOpts.Branch); err != nil {
		return err
	}
	if git.BranchExists(review.reviewBranch) {
		if err := git.DeleteBranch(review.reviewBranch, gitutil.ForceOpt(true)); err != nil {
			return err
		}
	}
	if stashed {
		if err := git.StashPop(); err != nil {
			return err
		}
	}
	return nil
}

// createReviewBranch creates a clean review branch from the remote
// branch this CL pertains to and then iterates over the sequence of
// dependent CLs leading to the current branch, creating one commit
// per CL by squashing all commits of each individual CL. The commit
// message for all but that last CL is derived from their
// <commitMessageFileName>, while the <message> argument is used as
// the commit message for the last commit.
func (review *review) createReviewBranch(git *gitutil.Git, message string) (e error) {
	// Create the review branch.
	if err := git.FetchRefspec("origin", review.CLOpts.RemoteBranch); err != nil {
		return err
	}
	if git.BranchExists(review.reviewBranch) {
		if err := git.DeleteBranch(review.reviewBranch, gitutil.ForceOpt(true)); err != nil {
			return err
		}
	}
	upstream := "origin/" + review.CLOpts.RemoteBranch
	if err := git.CreateBranchWithUpstream(review.reviewBranch, upstream); err != nil {
		return err
	}
	if err := git.CheckoutBranch(review.reviewBranch); err != nil {
		return err
	}
	// Register a cleanup handler in case of subsequent errors.
	cleanup := true
	defer collect.Error(func() error {
		if !cleanup {
			return git.CheckoutBranch(review.CLOpts.Branch)
		}
		git.CheckoutBranch(review.CLOpts.Branch, gitutil.ForceOpt(true))
		git.DeleteBranch(review.reviewBranch, gitutil.ForceOpt(true))
		return nil
	}, &e)

	// Report an error if the CL is empty.
	hasDiff, err := git.BranchesDiffer(review.CLOpts.Branch, review.reviewBranch)
	if err != nil {
		return err
	}
	if !hasDiff {
		return emptyChangeError(struct{}{})
	}

	// If <message> is empty, replace it with the default message.
	if len(message) == 0 {
		var err error
		message, err = review.defaultCommitMessage()
		if err != nil {
			return err
		}
	}

	// Iterate over all dependent CLs leading to (and including) the
	// current branch, creating one commit in the review branch per CL
	// by squashing all commits of each individual CL.
	branches, err := getDependentCLs(review.jirix, review.CLOpts.Branch)
	if err != nil {
		return err
	}
	branches = append(branches, review.CLOpts.Branch)
	if err := review.squashBranches(git, branches, message); err != nil {
		return err
	}

	cleanup = false
	return nil
}

// squashBranches iterates over the given list of branches, creating
// one commit per branch in the current branch by squashing all
// commits of each individual branch.
//
// TODO(jsimsa): Consider using "git rebase --onto" to avoid having to
// deal with merge conflicts.
func (review *review) squashBranches(git *gitutil.Git, branches []string, message string) (e error) {
	for i := 1; i < len(branches); i++ {
		// We want to merge the <branches[i]> branch on top of the review
		// branch, forcing all conflicts to be reviewed in favor of the
		// <branches[i]> branch. Unfortunately, git merge does not offer a
		// strategy that would do that for us. The solution implemented
		// here is based on:
		//
		// http://stackoverflow.com/questions/173919/is-there-a-theirs-version-of-git-merge-s-ours
		if err := git.Merge(branches[i], gitutil.SquashOpt(true), gitutil.StrategyOpt("ours")); err != nil {
			return changeConflictError{
				localBranch:  branches[i],
				remoteBranch: review.CLOpts.RemoteBranch,
				message:      err.Error(),
			}
		}
		// Fetch the timestamp of the last commit of <branches[i]> and use
		// it to create the squashed commit. This is needed to make sure
		// that the commit hash of the squashed commit stays the same as
		// long as the squashed sequence of commits does not change. If
		// this was not the case, consecutive invocations of "jiri cl upload"
		// could fail if some, but not all, of the dependent CLs submitted
		// to Gerrit have changed.
		output, err := git.Log(branches[i], branches[i]+"^", "%ad%n%cd")
		if err != nil {
			return err
		}
		if len(output) < 1 || len(output[0]) < 2 {
			return fmt.Errorf("unexpected output length: %v", output)
		}
		if i < len(branches)-1 {
			file, err := getCommitMessageFileName(review.jirix, branches[i])
			if err != nil {
				return err
			}
			message, err := review.jirix.NewSeq().ReadFile(file)
			if err != nil {
				return err
			}
			if err := git.CommitWithMessage(string(message)); err != nil {
				return err
			}
		} else {
			committer := git.NewCommitter(review.CLOpts.Edit)
			if err := committer.Commit(message); err != nil {
				return err
			}
		}
		tmpBranch := review.reviewBranch + "-" + branches[i] + "-TMP"
		if err := git.CreateBranch(tmpBranch); err != nil {
			return err
		}
		defer collect.Error(func() error {
			return git.DeleteBranch(tmpBranch, gitutil.ForceOpt(true))
		}, &e)
		if err := git.Reset(branches[i]); err != nil {
			return err
		}
		if err := git.Reset(tmpBranch, gitutil.ModeOpt("soft")); err != nil {
			return err
		}
		if err := git.CommitAmend(); err != nil {
			return err
		}
	}
	return nil
}

func (review *review) readMultiPart() string {
	s := review.jirix.NewSeq()
	filename := filepath.Join(review.project.Path, jiri.ProjectMetaDir, review.featureBranch, multiPartMetaDataFileName)
	mpart, err := s.ReadFile(filename)
	if err != nil {
		return ""
	}
	return strings.TrimSpace(string(mpart))
}

// strippedGerritCommitMessage returns the commit message stripped of variable
// meta-data such as multipart messages, or change IDs:
func strippedGerritCommitMessage(jirix *jiri.X, branch string) (string, error) {
	filename, err := getCommitMessageFileName(jirix, branch)
	if err != nil {
		return "", err
	}
	msg, err := jirix.NewSeq().ReadFile(filename)
	if err != nil {
		return "", err
	}
	// Strip "MultiPart ..." from the commit messages.
	strippedMessages := multiPartRE.ReplaceAllLiteralString(string(msg), "")
	// Strip "Change-Id: ..." from the commit messages.
	strippedMessages = changeIDRE.ReplaceAllLiteralString(strippedMessages, "")
	return strippedMessages, nil
}

// defaultCommitMessage creates the default commit message from the
// list of commits on the branch.
func (review *review) defaultCommitMessage() (string, error) {
	commitMessages := ""
	var err error
	if commitMessageBodyFlag != "" {
		msg, tmpErr := ioutil.ReadFile(commitMessageBodyFlag)
		commitMessages = string(msg)
		err = tmpErr
	} else {
		commitMessages, err = gitutil.New(review.jirix).CommitMessages(review.CLOpts.Branch, review.reviewBranch)
	}
	if err != nil {
		return "", err
	}
	// Strip "MultiPart ..." from the commit messages.
	strippedMessages := multiPartRE.ReplaceAllLiteralString(commitMessages, "")
	// Strip "Change-Id: ..." from the commit messages.
	strippedMessages = changeIDRE.ReplaceAllLiteralString(strippedMessages, "")
	// Add comment markers (#) to every line.
	commentedMessages := "# " + strings.Replace(strippedMessages, "\n", "\n# ", -1)
	message := defaultMessageHeader + commentedMessages
	if multipart := review.readMultiPart(); multipart != "" {
		message = message + "\n" + multipart + "\n"
	}
	return message, nil
}

// ensureChangeID makes sure that the last commit contains a Change-Id, and
// returns an error if it does not.
func (review *review) ensureChangeID() error {
	latestCommitMessage, err := gitutil.New(review.jirix).LatestCommitMessage()
	if err != nil {
		return err
	}
	changeID := changeIDRE.FindString(latestCommitMessage)
	if changeID == "" {
		return noChangeIDError(struct{}{})
	}
	return nil
}

// processLabelsAndCommitFile adds/removes labels for the given commit
// message and merges in the contents of the initial-message-file.
func (review *review) processLabelsAndCommitFile(message string) string {
	// Find the Change-ID and MultiPart lines.
	changeIDLine := changeIDRE.FindString(message)
	multiPartLine := multiPartRE.FindString(message)

	if commitMessageBodyFlag != "" {
		if msg, err := ioutil.ReadFile(commitMessageBodyFlag); err == nil {
			message = string(msg)
		}
	}

	// Strip existing labels and change-ID.
	message = autosubmitLabelRE.ReplaceAllLiteralString(message, "")
	message = presubmitTestLabelRE.ReplaceAllLiteralString(message, "")
	message = changeIDRE.ReplaceAllLiteralString(message, "")
	message = multiPartRE.ReplaceAllLiteralString(message, "")

	// Insert labels and change-ID back.
	if review.CLOpts.Autosubmit {
		message += fmt.Sprintf("AutoSubmit\n")
	}
	if review.CLOpts.Presubmit != gerrit.PresubmitTestTypeAll {
		message += fmt.Sprintf("PresubmitTest: %s\n", review.CLOpts.Presubmit)
	}
	if multiPartLine != "" && !strings.HasSuffix(message, "\n") {
		message += "\n"
	} else {
		if multipart := review.readMultiPart(); multipart != "" {
			if !strings.HasSuffix(message, "\n") {
				message += "\n"
			}
			multiPartLine = multipart
		}
	}
	message += multiPartLine
	if changeIDLine != "" && !strings.HasSuffix(message, "\n") {
		message += "\n"
	}
	message += changeIDLine
	return message
}

// run implements checks that the review passes all local checks
// and then uploads it to Gerrit.
func (review *review) run(git *gitutil.Git) (e error) {
	if uncommittedFlag {
		changes, err := git.FilesWithUncommittedChanges()
		if err != nil {
			return err
		}
		if len(changes) != 0 {
			return uncommittedChangesError(changes)
		}
	}
	if review.CLOpts.Branch == remoteBranchFlag {
		return fmt.Errorf("cannot do a review from the %q branch.", remoteBranchFlag)
	}
	stashed, err := git.Stash()
	if err != nil {
		return err
	}
	defer collect.Error(func() error { return review.cleanup(stashed) }, &e)
	wd, err := os.Getwd()
	if err != nil {
		return fmt.Errorf("Getwd() failed: %v", err)
	}
	topLevel, err := git.TopLevel()
	if err != nil {
		return err
	}
	s := review.jirix.NewSeq()
	if err := s.Chdir(topLevel).Done(); err != nil {
		return err
	}
	defer collect.Error(func() error { return review.jirix.NewSeq().Chdir(wd).Done() }, &e)

	file, err := getCommitMessageFileName(review.jirix, review.CLOpts.Branch)
	if err != nil {
		return err
	}

	message := messageFlag
	if message == "" {
		// Message was not passed in flag.  Attempt to read it from file.
		data, err := s.ReadFile(file)
		if err != nil {
			if !runutil.IsNotExist(err) {
				return err
			}
		} else {
			message = string(data)
		}
	}

	// Add/remove labels to/from the commit message before asking users
	// to edit it. We do this only when this is not the initial commit
	// where the message is empty.
	//
	// For the initial commit, the labels will be processed after the
	// message is edited by users, which happens in the
	// updateReviewMessage method.
	if message != "" {
		message = review.processLabelsAndCommitFile(message)
	}
	if err := review.createReviewBranch(git, message); err != nil {
		return err
	}
	if err := review.updateReviewMessage(git, file); err != nil {
		return err
	}
	if err := review.send(); err != nil {
		return err
	}
	return nil
}

// send uploads the current branch out for review.
func (review *review) send() error {
	if err := review.ensureChangeID(); err != nil {
		return err
	}
	if err := gerrit.Push(review.jirix.NewSeq(), review.CLOpts); err != nil {
		return gerritError(err.Error())
	}
	return nil
}

// getChangeID reads the commit message and extracts the change-Id
func (review *review) getChangeID() (string, error) {
	file, err := getCommitMessageFileName(review.jirix, review.CLOpts.Branch)
	if err != nil {
		return "", err
	}
	bytes, err := review.jirix.NewSeq().ReadFile(file)
	if err != nil {
		return "", err
	}
	changeID := changeIDRE.FindSubmatch(bytes)
	if changeID == nil || len(changeID) < 2 {
		return "", fmt.Errorf("could not find Change-Id in:\n%s", bytes)
	}
	return string(changeID[1]), nil
}

// updateReviewMessage writes the commit message to the given file.
func (review *review) updateReviewMessage(git *gitutil.Git, file string) error {
	if err := git.CheckoutBranch(review.reviewBranch); err != nil {
		return err
	}
	newMessage, err := git.LatestCommitMessage()
	if err != nil {
		return err
	}
	// update MultiPart metadata.
	mpart := review.readMultiPart()
	newMessage = multiPartRE.ReplaceAllLiteralString(newMessage, mpart)
	s := review.jirix.NewSeq()
	// For the initial commit where the commit message file doesn't exist,
	// add/remove labels after users finish editing the commit message.
	//
	// This behavior is consistent with how Change-ID is added for the
	// initial commit so we don't confuse users.
	if _, err := s.Stat(file); err != nil {
		if runutil.IsNotExist(err) {
			newMessage = review.processLabelsAndCommitFile(newMessage)
			if err := git.CommitAmendWithMessage(newMessage); err != nil {
				return err
			}
		} else {
			return err
		}
	}
	topLevel, err := git.TopLevel()
	if err != nil {
		return err
	}
	newMetadataDir := filepath.Join(topLevel, jiri.ProjectMetaDir, review.CLOpts.Branch)
	if err := s.MkdirAll(newMetadataDir, os.FileMode(0755)).
		WriteFile(file, []byte(newMessage), 0644).Done(); err != nil {
		return err
	}
	return nil
}

// cmdCLNew represents the "jiri cl new" command.
var cmdCLNew = &cmdline.Command{
	Runner: jiri.RunnerFunc(runCLNew),
	Name:   "new",
	Short:  "Create a new local branch for a changelist(deprecated, use jiri upload)",
	Long: fmt.Sprintf(`
Command "new" creates a new local branch for a changelist. In
particular, it forks a new branch with the given name from the current
branch and records the relationship between the current branch and the
new branch in the %v metadata directory. The information recorded in
the %v metadata directory tracks dependencies between CLs and is used
by the "jiri cl sync" and "jiri cl upload" commands.
`, jiri.ProjectMetaDir, jiri.ProjectMetaDir),
	ArgsName: "<name>",
	ArgsLong: "<name> is the changelist name.",
}

func runCLNew(jirix *jiri.X, args []string) error {
	jirix.Logger.Warningf("jiri cl has been deprecated please use jiri upload. It will be removed soon.")
	if got, want := len(args), 1; got != want {
		return jirix.UsageErrorf("unexpected number of arguments: got %v, want %v", got, want)
	}
	return newCL(jirix, args)
}

func newCL(jirix *jiri.X, args []string) error {
	git := gitutil.New(jirix)
	topLevel, err := git.TopLevel()
	if err != nil {
		return err
	}
	originalBranch, err := git.CurrentBranchName()
	if err != nil {
		return err
	}

	// Create a new branch using the current branch.
	newBranch := args[0]
	if err := git.CreateAndCheckoutBranch(newBranch); err != nil {
		return err
	}

	// Register a cleanup handler in case of subsequent errors.
	cleanup := true
	defer func() {
		if cleanup {
			git.CheckoutBranch(originalBranch, gitutil.ForceOpt(true))
			git.DeleteBranch(newBranch, gitutil.ForceOpt(true))
		}
	}()

	s := jirix.NewSeq()
	// Record the dependent CLs for the new branch. The dependent CLs
	// are recorded in a <dependencyPathFileName> file as a
	// newline-separated list of branch names.
	branches, err := getDependentCLs(jirix, originalBranch)
	if err != nil {
		return err
	}
	branches = append(branches, originalBranch)
	newMetadataDir := filepath.Join(topLevel, jiri.ProjectMetaDir, newBranch)
	if err := s.MkdirAll(newMetadataDir, os.FileMode(0755)).Done(); err != nil {
		return err
	}
	file, err := getDependencyPathFileName(jirix, newBranch)
	if err != nil {
		return err
	}
	if err := s.WriteFile(file, []byte(strings.Join(branches, "\n")), os.FileMode(0644)).Done(); err != nil {
		return err
	}

	cleanup = false
	return nil
}

// cmdCLSync represents the "jiri cl sync" command.
var cmdCLSync = &cmdline.Command{
	Runner: jiri.RunnerFunc(runCLSync),
	Name:   "sync",
	Short:  "Bring a changelist up to date(deprecated, use jiri upload)",
	Long: fmt.Sprintf(`
Command "sync" brings the CL identified by the current branch up to
date with the branch tracking the remote branch this CL pertains
to. To do that, the command uses the information recorded in the %v
metadata directory to identify the sequence of dependent CLs leading
to the current branch. The command then iterates over this sequence
bringing each of the CLs up to date with its ancestor. The end result
of this process is that all CLs in the sequence are up to date with
the branch that tracks the remote branch this CL pertains to.

NOTE: It is possible that the command cannot automatically merge
changes in an ancestor into its dependent. When that occurs, the
command is aborted and prints instructions that need to be followed
before the command can be retried.
`, jiri.ProjectMetaDir),
}

func runCLSync(jirix *jiri.X, _ []string) error {
	jirix.Logger.Warningf("jiri cl has been deprecated please use jiri upload. It will be removed soon.")
	git := gitutil.New(jirix)
	return syncCL(jirix, git)
}

func syncCL(jirix *jiri.X, git *gitutil.Git) (e error) {
	stashed, err := git.Stash()
	if err != nil {
		return err
	}
	if stashed {
		defer collect.Error(func() error { return git.StashPop() }, &e)
	}

	// Register a cleanup handler in case of subsequent errors.
	forceOriginalBranch := true
	originalBranch, err := git.CurrentBranchName()
	if err != nil {
		return err
	}
	originalWd, err := os.Getwd()
	if err != nil {
		return err
	}

	defer func() {
		if forceOriginalBranch {
			git.CheckoutBranch(originalBranch, gitutil.ForceOpt(true))
		}
		jirix.NewSeq().Chdir(originalWd)
	}()

	s := jirix.NewSeq()
	// Switch to an existing directory in master so we can run commands.
	topLevel, err := git.TopLevel()
	if err != nil {
		return err
	}
	if err := s.Chdir(topLevel).Done(); err != nil {
		return err
	}

	// Identify the dependents CLs leading to (and including) the
	// current branch.
	branches, err := getDependentCLs(jirix, originalBranch)
	if err != nil {
		return err
	}
	branches = append(branches, originalBranch)

	// Sync from upstream.
	if err := git.CheckoutBranch(branches[0]); err != nil {
		return err
	}
	if err := git.Pull("origin", branches[0]); err != nil {
		return err
	}

	// Bring all CLs in the sequence of dependent CLs leading to the
	// current branch up to date with the <remoteBranchFlag> branch.
	for i := 1; i < len(branches); i++ {
		if err := git.CheckoutBranch(branches[i]); err != nil {
			return err
		}
		if err := git.Merge(branches[i-1]); err != nil {
			return fmt.Errorf(`Failed to automatically merge branch %v into branch %v: %v
The following steps are needed before the operation can be retried:
$ git checkout %v
$ git merge %v
# resolve all conflicts
$ git commit -a
$ git checkout %v
# retry the original operation
`, branches[i], branches[i-1], err, branches[i], branches[i-1], originalBranch)
		}
	}

	forceOriginalBranch = false
	return nil
}
