// Validate that the user's request to rebase a review makes sense. // // This checks both that the request is well formed, and that the // corresponding review is in a state where rebasing is appropriate. func validateRebaseRequest(repo repository.Repo, args []string) (*review.Review, error) { var r *review.Review var err error if len(args) > 1 { return nil, errors.New("Only rebasing a single review is supported.") } if len(args) == 1 { r, err = review.Get(repo, args[0]) } else { r, err = review.GetCurrent(repo) } if err != nil { return nil, fmt.Errorf("Failed to load the review: %v\n", err) } if r == nil { return nil, errors.New("There is no matching review.") } if r.Submitted { return nil, errors.New("The review has already been submitted.") } target := r.Request.TargetRef if err := repo.VerifyGitRef(target); err != nil { return nil, err } return r, nil }
// Submit the current code review request. // // The "args" parameter contains all of the command line arguments that followed the subcommand. func submitReview(repo repository.Repo, args []string) error { submitFlagSet.Parse(args) args = submitFlagSet.Args() if *submitMerge && *submitRebase { return errors.New("Only one of --merge or --rebase is allowed.") } var r *review.Review var err error if len(args) > 1 { return errors.New("Only accepting a single review is supported.") } if len(args) == 1 { r, err = review.Get(repo, args[0]) } else { r, err = review.GetCurrent(repo) } if err != nil { return fmt.Errorf("Failed to load the review: %v\n", err) } if r == nil { return errors.New("There is no matching review.") } if r.Submitted { return errors.New("The review has already been submitted.") } if !*submitTBR && (r.Resolved == nil || !*r.Resolved) { return errors.New("Not submitting as the review has not yet been accepted.") } target := r.Request.TargetRef if err := repo.VerifyGitRef(target); err != nil { return err } source, err := r.GetHeadCommit() if err != nil { return err } isAncestor, err := repo.IsAncestor(target, source) if err != nil { return err } if !isAncestor { return errors.New("Refusing to submit a non-fast-forward review. First merge the target ref.") } if !(*submitRebase || *submitMerge || *submitFastForward) { submitStrategy, err := repo.GetSubmitStrategy() if err != nil { return err } if submitStrategy == "merge" && !*submitRebase && !*submitFastForward { *submitMerge = true } if submitStrategy == "rebase" && !*submitMerge && !*submitFastForward { *submitRebase = true } if submitStrategy == "fast-forward" && !*submitRebase && !*submitMerge { *submitFastForward = true } } if *submitRebase { if err := r.Rebase(*submitArchive); err != nil { return err } source, err = r.GetHeadCommit() if err != nil { return err } } if err := repo.SwitchToRef(target); err != nil { return err } if *submitMerge { submitMessage := fmt.Sprintf("Submitting review %.12s", r.Revision) return repo.MergeRef(source, false, submitMessage, r.Request.Description) } else { return repo.MergeRef(source, true) } }
// Create a new code review request. // // The "args" parameter is all of the command line arguments that followed the subcommand. func requestReview(repo repository.Repo, args []string) error { requestFlagSet.Parse(args) if !*requestAllowUncommitted { // Requesting a code review with uncommited local changes is usually a mistake, so // we want to report that to the user instead of creating the request. hasUncommitted, err := repo.HasUncommittedChanges() if err != nil { return err } if hasUncommitted { return errors.New("You have uncommitted or untracked files. Use --allow-uncommitted to ignore those.") } } userEmail, err := repo.GetUserEmail() if err != nil { return err } r := buildRequestFromFlags(userEmail) if r.ReviewRef == "HEAD" { headRef, err := repo.GetHeadRef() if err != nil { return err } r.ReviewRef = headRef } if err := repo.VerifyGitRef(r.TargetRef); err != nil { return err } if err := repo.VerifyGitRef(r.ReviewRef); err != nil { return err } base, err := repo.MergeBase(r.TargetRef, r.ReviewRef) if err != nil { return err } r.BaseCommit = base reviewCommits, err := repo.ListCommitsBetween(base, r.ReviewRef) if err != nil { return err } if reviewCommits == nil { return errors.New("There are no commits included in the review request") } if r.Description == "" { description, err := repo.GetCommitMessage(reviewCommits[0]) if err != nil { return err } r.Description = description } note, err := r.Write() if err != nil { return err } repo.AppendNote(request.Ref, reviewCommits[0], note) if !*requestQuiet { fmt.Printf(requestSummaryTemplate, reviewCommits[0], r.TargetRef, r.ReviewRef, r.Description) } return nil }