diff --git a/pkg/cmd/pr/update/update.go b/pkg/cmd/pr/update/update.go index 4d170ac96..dda1fa3e8 100644 --- a/pkg/cmd/pr/update/update.go +++ b/pkg/cmd/pr/update/update.go @@ -78,7 +78,7 @@ func NewCmdUpdate(f *cmdutil.Factory, runF func(*UpdateOptions) error) *cobra.Co func updateRun(opts *UpdateOptions) error { findOptions := shared.FindOptions{ Selector: opts.SelectorArg, - Fields: []string{"id", "number", "headRefName", "headRefOid", "headRepositoryOwner"}, + Fields: []string{"id", "number", "headRefName", "headRefOid", "headRepositoryOwner", "mergeable"}, } pr, repo, err := opts.Finder.Find(findOptions) @@ -86,6 +86,12 @@ func updateRun(opts *UpdateOptions) error { return err } + cs := opts.IO.ColorScheme() + if pr.Mergeable == api.PullRequestMergeableConflicting { + fmt.Fprintf(opts.IO.ErrOut, "%s Cannot update PR branch due to conflicts\n", cs.FailureIcon()) + return cmdutil.SilentError + } + httpClient, err := opts.HttpClient() if err != nil { return err @@ -106,7 +112,6 @@ func updateRun(opts *UpdateOptions) error { return err } - cs := opts.IO.ColorScheme() if comparison.BehindBy == 0 { // The PR branch is not behind the base branch, so it'a already up-to-date. fmt.Fprintf(opts.IO.Out, "%s PR branch already up-to-date\n", cs.SuccessIcon()) diff --git a/pkg/cmd/pr/update/update_test.go b/pkg/cmd/pr/update/update_test.go index e7bfd51e9..546ca0ed2 100644 --- a/pkg/cmd/pr/update/update_test.go +++ b/pkg/cmd/pr/update/update_test.go @@ -105,6 +105,7 @@ func Test_updateRun(t *testing.T) { HeadRefOid: "head-ref-oid", HeadRefName: "head-ref-name", HeadRepositoryOwner: api.Owner{Login: "head-repository-owner"}, + Mergeable: api.PullRequestMergeableMergeable, }, ghrepo.New("OWNER", "REPO")), } } @@ -114,6 +115,7 @@ func Test_updateRun(t *testing.T) { input *UpdateOptions httpStubs func(*testing.T, *httpmock.Registry) stdout string + stderr string wantsErr string }{ { @@ -163,6 +165,7 @@ func Test_updateRun(t *testing.T) { HeadRefOid: "head-ref-oid", HeadRefName: "head-ref-name", HeadRepositoryOwner: api.Owner{Login: "OWNER"}, + Mergeable: api.PullRequestMergeableMergeable, }, ghrepo.New("OWNER", "REPO")), }, httpStubs: func(t *testing.T, reg *httpmock.Registry) { @@ -189,6 +192,22 @@ func Test_updateRun(t *testing.T) { }, stdout: "✓ PR branch already up-to-date\n", }, + { + name: "failure, not mergeable due to conflicts", + input: &UpdateOptions{ + SelectorArg: "123", + Finder: shared.NewMockFinder("123", &api.PullRequest{ + ID: "123", + Number: 123, + HeadRefOid: "head-ref-oid", + HeadRefName: "head-ref-name", + HeadRepositoryOwner: api.Owner{Login: "OWNER"}, + Mergeable: api.PullRequestMergeableConflicting, + }, ghrepo.New("OWNER", "REPO")), + }, + stderr: "X Cannot update PR branch due to conflicts\n", + wantsErr: cmdutil.SilentError.Error(), + }, { name: "success, merge", input: &UpdateOptions{ @@ -342,7 +361,7 @@ func Test_updateRun(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ios, _, stdout, _ := iostreams.Test() + ios, _, stdout, stderr := iostreams.Test() ios.SetStdoutTTY(true) ios.SetStdinTTY(true) ios.SetStderrTTY(true) @@ -377,6 +396,7 @@ func Test_updateRun(t *testing.T) { } assert.Equal(t, tt.stdout, stdout.String()) + assert.Equal(t, tt.stderr, stderr.String()) }) } }