X Tutup
Skip to content

Commit bb9bf29

Browse files
pr merge switch to base branch if available (cli#5251)
* after merge, switch to base branch if available * Add ability to checkout new branch * Style cleanup Co-authored-by: Sam Coe <samcoe@users.noreply.github.com>
1 parent e601a89 commit bb9bf29

File tree

3 files changed

+133
-24
lines changed

3 files changed

+133
-24
lines changed

git/git.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,15 @@ func CheckoutBranch(branch string) error {
307307
return run.PrepareCmd(configCmd).Run()
308308
}
309309

310+
func CheckoutNewBranch(remoteName, branch string) error {
311+
track := fmt.Sprintf("%s/%s", remoteName, branch)
312+
configCmd, err := GitCommand("checkout", "-b", branch, "--track", track)
313+
if err != nil {
314+
return err
315+
}
316+
return run.PrepareCmd(configCmd).Run()
317+
}
318+
310319
// pull changes from remote branch without version history
311320
func Pull(remote, branch string) error {
312321
pullCmd, err := GitCommand("pull", "--ff-only", remote, branch)

pkg/cmd/pr/merge/merge.go

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"github.com/cli/cli/v2/context"
1212
"github.com/cli/cli/v2/git"
1313
"github.com/cli/cli/v2/internal/config"
14-
"github.com/cli/cli/v2/internal/ghrepo"
1514
"github.com/cli/cli/v2/pkg/cmd/pr/shared"
1615
"github.com/cli/cli/v2/pkg/cmdutil"
1716
"github.com/cli/cli/v2/pkg/iostreams"
@@ -322,18 +321,35 @@ func mergeRun(opts *MergeOptions) error {
322321

323322
var branchToSwitchTo string
324323
if currentBranch == pr.HeadRefName {
325-
branchToSwitchTo, err = api.RepoDefaultBranch(apiClient, baseRepo)
324+
branchToSwitchTo = pr.BaseRefName
325+
if branchToSwitchTo == "" {
326+
branchToSwitchTo, err = api.RepoDefaultBranch(apiClient, baseRepo)
327+
if err != nil {
328+
return err
329+
}
330+
}
331+
332+
remotes, err := opts.Remotes()
326333
if err != nil {
327334
return err
328335
}
329336

330-
err = git.CheckoutBranch(branchToSwitchTo)
337+
baseRemote, err := remotes.FindByRepo(baseRepo.RepoOwner(), baseRepo.RepoName())
331338
if err != nil {
332339
return err
333340
}
334341

335-
err := pullLatestChanges(opts, baseRepo, branchToSwitchTo)
336-
if err != nil {
342+
if git.HasLocalBranch(branchToSwitchTo) {
343+
if err := git.CheckoutBranch(branchToSwitchTo); err != nil {
344+
return err
345+
}
346+
} else {
347+
if err := git.CheckoutNewBranch(baseRemote.Name, branchToSwitchTo); err != nil {
348+
return err
349+
}
350+
}
351+
352+
if err := git.Pull(baseRemote.Name, branchToSwitchTo); err != nil {
337353
fmt.Fprintf(opts.IO.ErrOut, "%s warning: not possible to fast-forward to: %q\n", cs.WarningIcon(), branchToSwitchTo)
338354
}
339355
}
@@ -364,25 +380,6 @@ func mergeRun(opts *MergeOptions) error {
364380
return nil
365381
}
366382

367-
func pullLatestChanges(opts *MergeOptions, repo ghrepo.Interface, branch string) error {
368-
remotes, err := opts.Remotes()
369-
if err != nil {
370-
return err
371-
}
372-
373-
baseRemote, err := remotes.FindByRepo(repo.RepoOwner(), repo.RepoName())
374-
if err != nil {
375-
return err
376-
}
377-
378-
err = git.Pull(baseRemote.Name, branch)
379-
if err != nil {
380-
return err
381-
}
382-
383-
return nil
384-
}
385-
386383
func mergeMethodSurvey(baseRepo *api.Repository) (PullRequestMergeMethod, error) {
387384
type mergeOption struct {
388385
title string

pkg/cmd/pr/merge/merge_test.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ func TestPrMerge_deleteBranch(t *testing.T) {
480480
cs, cmdTeardown := run.Stub()
481481
defer cmdTeardown(t)
482482

483+
cs.Register(`git rev-parse --verify refs/heads/master`, 0, "")
483484
cs.Register(`git checkout master`, 0, "")
484485
cs.Register(`git rev-parse --verify refs/heads/blueberries`, 0, "")
485486
cs.Register(`git branch -D blueberries`, 0, "")
@@ -497,6 +498,106 @@ func TestPrMerge_deleteBranch(t *testing.T) {
497498
`), output.Stderr())
498499
}
499500

501+
func TestPrMerge_deleteBranch_nonDefault(t *testing.T) {
502+
http := initFakeHTTP()
503+
defer http.Verify(t)
504+
505+
shared.RunCommandFinder(
506+
"",
507+
&api.PullRequest{
508+
ID: "PR_10",
509+
Number: 10,
510+
State: "OPEN",
511+
Title: "Blueberries are a good fruit",
512+
HeadRefName: "blueberries",
513+
MergeStateStatus: "CLEAN",
514+
BaseRefName: "fruit",
515+
},
516+
baseRepo("OWNER", "REPO", "master"),
517+
)
518+
519+
http.Register(
520+
httpmock.GraphQL(`mutation PullRequestMerge\b`),
521+
httpmock.GraphQLMutation(`{}`, func(input map[string]interface{}) {
522+
assert.Equal(t, "PR_10", input["pullRequestId"].(string))
523+
assert.Equal(t, "MERGE", input["mergeMethod"].(string))
524+
assert.NotContains(t, input, "commitHeadline")
525+
}))
526+
http.Register(
527+
httpmock.REST("DELETE", "repos/OWNER/REPO/git/refs/heads/blueberries"),
528+
httpmock.StringResponse(`{}`))
529+
530+
cs, cmdTeardown := run.Stub()
531+
defer cmdTeardown(t)
532+
533+
cs.Register(`git rev-parse --verify refs/heads/fruit`, 0, "")
534+
cs.Register(`git checkout fruit`, 0, "")
535+
cs.Register(`git rev-parse --verify refs/heads/blueberries`, 0, "")
536+
cs.Register(`git branch -D blueberries`, 0, "")
537+
cs.Register(`git pull --ff-only`, 0, "")
538+
539+
output, err := runCommand(http, "blueberries", true, `pr merge --merge --delete-branch`)
540+
if err != nil {
541+
t.Fatalf("Got unexpected error running `pr merge` %s", err)
542+
}
543+
544+
assert.Equal(t, "", output.String())
545+
assert.Equal(t, heredoc.Doc(`
546+
✓ Merged pull request #10 (Blueberries are a good fruit)
547+
✓ Deleted branch blueberries and switched to branch fruit
548+
`), output.Stderr())
549+
}
550+
551+
func TestPrMerge_deleteBranch_checkoutNewBranch(t *testing.T) {
552+
http := initFakeHTTP()
553+
defer http.Verify(t)
554+
555+
shared.RunCommandFinder(
556+
"",
557+
&api.PullRequest{
558+
ID: "PR_10",
559+
Number: 10,
560+
State: "OPEN",
561+
Title: "Blueberries are a good fruit",
562+
HeadRefName: "blueberries",
563+
MergeStateStatus: "CLEAN",
564+
BaseRefName: "fruit",
565+
},
566+
baseRepo("OWNER", "REPO", "master"),
567+
)
568+
569+
http.Register(
570+
httpmock.GraphQL(`mutation PullRequestMerge\b`),
571+
httpmock.GraphQLMutation(`{}`, func(input map[string]interface{}) {
572+
assert.Equal(t, "PR_10", input["pullRequestId"].(string))
573+
assert.Equal(t, "MERGE", input["mergeMethod"].(string))
574+
assert.NotContains(t, input, "commitHeadline")
575+
}))
576+
http.Register(
577+
httpmock.REST("DELETE", "repos/OWNER/REPO/git/refs/heads/blueberries"),
578+
httpmock.StringResponse(`{}`))
579+
580+
cs, cmdTeardown := run.Stub()
581+
defer cmdTeardown(t)
582+
583+
cs.Register(`git rev-parse --verify refs/heads/fruit`, 1, "")
584+
cs.Register(`git checkout -b fruit --track origin/fruit`, 0, "")
585+
cs.Register(`git rev-parse --verify refs/heads/blueberries`, 0, "")
586+
cs.Register(`git branch -D blueberries`, 0, "")
587+
cs.Register(`git pull --ff-only`, 0, "")
588+
589+
output, err := runCommand(http, "blueberries", true, `pr merge --merge --delete-branch`)
590+
if err != nil {
591+
t.Fatalf("Got unexpected error running `pr merge` %s", err)
592+
}
593+
594+
assert.Equal(t, "", output.String())
595+
assert.Equal(t, heredoc.Doc(`
596+
✓ Merged pull request #10 (Blueberries are a good fruit)
597+
✓ Deleted branch blueberries and switched to branch fruit
598+
`), output.Stderr())
599+
}
600+
500601
func TestPrMerge_deleteNonCurrentBranch(t *testing.T) {
501602
http := initFakeHTTP()
502603
defer http.Verify(t)
@@ -764,6 +865,7 @@ func TestPrMerge_alreadyMerged(t *testing.T) {
764865
cs, cmdTeardown := run.Stub()
765866
defer cmdTeardown(t)
766867

868+
cs.Register(`git rev-parse --verify refs/heads/master`, 0, "")
767869
cs.Register(`git checkout master`, 0, "")
768870
cs.Register(`git rev-parse --verify refs/heads/blueberries`, 0, "")
769871
cs.Register(`git branch -D blueberries`, 0, "")
@@ -906,6 +1008,7 @@ func TestPRMerge_interactiveWithDeleteBranch(t *testing.T) {
9061008
cs, cmdTeardown := run.Stub()
9071009
defer cmdTeardown(t)
9081010

1011+
cs.Register(`git rev-parse --verify refs/heads/master`, 0, "")
9091012
cs.Register(`git checkout master`, 0, "")
9101013
cs.Register(`git rev-parse --verify refs/heads/blueberries`, 0, "")
9111014
cs.Register(`git branch -D blueberries`, 0, "")

0 commit comments

Comments
 (0)
X Tutup