github.com/scorpionis/hub@v2.2.1+incompatible/commands/merge.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  
     7  	"github.com/github/hub/github"
     8  	"github.com/github/hub/utils"
     9  )
    10  
    11  var cmdMerge = &Command{
    12  	Run:          merge,
    13  	GitExtension: true,
    14  	Usage:        "merge PULLREQ-URL",
    15  	Short:        "Join two or more development histories (branches) together",
    16  	Long: `Merge the pull request with a commit message that includes the pull request
    17  ID and title, similar to the GitHub Merge Button.
    18  `,
    19  }
    20  
    21  func init() {
    22  	CmdRunner.Use(cmdMerge)
    23  }
    24  
    25  /*
    26    $ gh merge https://github.com/jingweno/gh/pull/73
    27    > git fetch git://github.com/jingweno/gh.git +refs/heads/feature:refs/remotes/jingweno/feature
    28    > git merge jingweno/feature --no-ff -m 'Merge pull request #73 from jingweno/feature...'
    29  */
    30  func merge(command *Command, args *Args) {
    31  	if !args.IsParamsEmpty() {
    32  		err := transformMergeArgs(args)
    33  		utils.Check(err)
    34  	}
    35  }
    36  
    37  func transformMergeArgs(args *Args) error {
    38  	words := args.Words()
    39  	if len(words) == 0 {
    40  		return nil
    41  	}
    42  
    43  	mergeURL := words[0]
    44  	url, err := github.ParseURL(mergeURL)
    45  	if err != nil {
    46  		return nil
    47  	}
    48  
    49  	pullURLRegex := regexp.MustCompile("^pull/(\\d+)")
    50  	projectPath := url.ProjectPath()
    51  	if !pullURLRegex.MatchString(projectPath) {
    52  		return nil
    53  	}
    54  
    55  	id := pullURLRegex.FindStringSubmatch(projectPath)[1]
    56  	gh := github.NewClient(url.Project.Host)
    57  	pullRequest, err := gh.PullRequest(url.Project, id)
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	branch := pullRequest.Head.Ref
    63  	headRepo := pullRequest.Head.Repo
    64  	if headRepo == nil {
    65  		return fmt.Errorf("Error: that fork is not available anymore")
    66  	}
    67  
    68  	u := url.GitURL(headRepo.Name, headRepo.Owner.Login, headRepo.Private)
    69  	mergeHead := fmt.Sprintf("%s/%s", headRepo.Owner.Login, branch)
    70  	ref := fmt.Sprintf("+refs/heads/%s:refs/remotes/%s", branch, mergeHead)
    71  	args.Before("git", "fetch", u, ref)
    72  
    73  	// Remove pull request URL
    74  	idx := args.IndexOfParam(mergeURL)
    75  	args.RemoveParam(idx)
    76  
    77  	mergeMsg := fmt.Sprintf("Merge pull request #%v from %s\n\n%s", id, mergeHead, pullRequest.Title)
    78  	args.AppendParams(mergeHead, "-m", mergeMsg)
    79  
    80  	if args.IndexOfParam("--ff-only") == -1 && args.IndexOfParam("--squash") == -1 {
    81  		i := args.IndexOfParam("-m")
    82  		args.InsertParam(i, "--no-ff")
    83  	}
    84  
    85  	return nil
    86  }