github.com/pengwynn/gh@v1.0.1-0.20140118055701-14327ca3942e/commands/merge.go (about)

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