github.com/abhinav/git-pr@v0.6.1-0.20171029234004-54218d68c11b/pr/land.go (about) 1 package pr 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/abhinav/git-pr/service" 8 ) 9 10 // Land the given pull request. 11 func (s *Service) Land(ctx context.Context, req *service.LandRequest) (*service.LandResponse, error) { 12 pr := req.PullRequest 13 if err := UpdateMessage(req.Editor, pr); err != nil { 14 return nil, err 15 } 16 17 // If the base branch doesn't exist locally, check it out. If it exists, 18 // it's okay for it to be out of sync with the remote. 19 base := *pr.Base.Ref 20 if !s.git.DoesBranchExist(base) { 21 if err := s.git.CreateBranch(base, *pr.Base.Ref); err != nil { 22 return nil, err 23 } 24 } 25 26 // If the branch is checked out locally, make sure it's in sync with 27 // remote. 28 if req.LocalBranch != "" { 29 hash, err := s.git.SHA1(req.LocalBranch) 30 if err != nil { 31 return nil, err 32 } 33 34 if hash != *pr.Head.SHA { 35 return nil, fmt.Errorf( 36 "SHA1 of local branch %v of pull request %v does not match GitHub. "+ 37 "Make sure that your local checkout of %v is in sync.", 38 req.LocalBranch, *pr.HTMLURL, req.LocalBranch) 39 } 40 } 41 42 if err := s.gh.SquashPullRequest(ctx, pr); err != nil { 43 return nil, err 44 } 45 46 if err := s.git.Checkout(base); err != nil { 47 return nil, err 48 } 49 50 // TODO: Remove hard coded remote name 51 if err := s.git.Pull("origin", base); err != nil { 52 return nil, err 53 } 54 55 if req.LocalBranch != "" { 56 if err := s.git.DeleteBranch(req.LocalBranch); err != nil { 57 return nil, err 58 } 59 } 60 61 // Nothing else to do if we don't own this pull request. 62 if !s.gh.IsOwned(ctx, pr.Head) { 63 return nil, nil 64 } 65 66 dependents, err := s.gh.ListPullRequestsByBase(ctx, *pr.Head.Ref) 67 if err != nil { 68 return nil, err 69 } 70 71 var res service.LandResponse 72 if len(dependents) > 0 { 73 rebaseRes, err := s.Rebase(ctx, &service.RebaseRequest{PullRequests: dependents, Base: base}) 74 if err != nil { 75 return nil, fmt.Errorf("failed to rebase dependents of %v: %v", *pr.HTMLURL, err) 76 } 77 res.BranchesNotUpdated = rebaseRes.BranchesNotUpdated 78 } 79 80 // TODO: What happens on branch deletion if we had dependents but none 81 // were owned by us? 82 if err := s.gh.DeleteBranch(ctx, *pr.Head.Ref); err != nil { 83 return nil, err 84 } 85 86 if req.LocalBranch != "" { 87 // TODO: Remove hard coded remote name 88 if err := s.git.DeleteRemoteTrackingBranch("origin", req.LocalBranch); err != nil { 89 return nil, err 90 } 91 } 92 93 return &res, nil 94 }