2013-06-21 22:40:42 +04:00
|
|
|
package commands
|
|
|
|
|
2013-06-22 00:17:52 +04:00
|
|
|
import (
|
2013-06-22 04:01:00 +04:00
|
|
|
"fmt"
|
2014-04-01 00:01:05 +04:00
|
|
|
"regexp"
|
|
|
|
|
2014-02-10 20:22:36 +04:00
|
|
|
"github.com/github/hub/github"
|
|
|
|
"github.com/github/hub/utils"
|
2013-06-22 00:17:52 +04:00
|
|
|
)
|
|
|
|
|
2013-06-21 22:40:42 +04:00
|
|
|
var cmdCheckout = &Command{
|
|
|
|
Run: checkout,
|
|
|
|
GitExtension: true,
|
|
|
|
Usage: "checkout PULLREQ-URL [BRANCH]",
|
|
|
|
Short: "Switch the active branch to another branch",
|
2013-07-01 22:29:08 +04:00
|
|
|
Long: `Checks out the head of the pull request as a local branch, to allow for
|
|
|
|
reviewing, rebasing and otherwise cleaning up the commits in the pull
|
|
|
|
request before merging. The name of the local branch can explicitly be
|
|
|
|
set with BRANCH.
|
|
|
|
`,
|
2013-06-21 22:40:42 +04:00
|
|
|
}
|
|
|
|
|
2013-12-30 02:18:14 +04:00
|
|
|
func init() {
|
|
|
|
CmdRunner.Use(cmdCheckout)
|
|
|
|
}
|
|
|
|
|
2013-06-22 00:17:52 +04:00
|
|
|
/**
|
|
|
|
$ gh checkout https://github.com/jingweno/gh/pull/73
|
2013-06-30 20:00:21 +04:00
|
|
|
> git remote add -f -t feature git://github:com/foo/gh.git
|
|
|
|
> git checkout --track -B foo-feature foo/feature
|
2013-06-22 00:17:52 +04:00
|
|
|
|
|
|
|
$ gh checkout https://github.com/jingweno/gh/pull/73 custom-branch-name
|
|
|
|
**/
|
2013-06-26 19:48:34 +04:00
|
|
|
func checkout(command *Command, args *Args) {
|
2013-07-02 22:56:45 +04:00
|
|
|
if !args.IsParamsEmpty() {
|
2013-07-02 22:28:50 +04:00
|
|
|
err := transformCheckoutArgs(args)
|
2013-07-05 03:18:28 +04:00
|
|
|
utils.Check(err)
|
2013-06-22 00:17:52 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-26 19:48:34 +04:00
|
|
|
func transformCheckoutArgs(args *Args) error {
|
2013-12-11 10:05:26 +04:00
|
|
|
words := args.Words()
|
2014-04-01 00:01:05 +04:00
|
|
|
|
2013-12-11 10:05:26 +04:00
|
|
|
if len(words) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
2013-06-22 04:01:00 +04:00
|
|
|
|
2013-12-11 10:05:26 +04:00
|
|
|
checkoutURL := words[0]
|
|
|
|
var newBranchName string
|
|
|
|
if len(words) > 1 {
|
|
|
|
newBranchName = words[1]
|
2013-07-29 21:50:28 +04:00
|
|
|
}
|
2014-04-01 00:01:05 +04:00
|
|
|
|
|
|
|
url, err := github.ParseURL(checkoutURL)
|
|
|
|
if err != nil {
|
|
|
|
// not a valid GitHub URL
|
|
|
|
return nil
|
|
|
|
}
|
2013-06-22 05:02:29 +04:00
|
|
|
|
2013-12-11 10:05:26 +04:00
|
|
|
pullURLRegex := regexp.MustCompile("^pull/(\\d+)")
|
|
|
|
projectPath := url.ProjectPath()
|
|
|
|
if !pullURLRegex.MatchString(projectPath) {
|
2014-04-01 00:01:05 +04:00
|
|
|
// not a valid PR URL
|
2013-12-11 10:05:26 +04:00
|
|
|
return nil
|
|
|
|
}
|
2013-07-02 22:28:50 +04:00
|
|
|
|
2013-12-11 10:05:26 +04:00
|
|
|
id := pullURLRegex.FindStringSubmatch(projectPath)[1]
|
2013-12-17 19:45:48 +04:00
|
|
|
gh := github.NewClient(url.Project.Host)
|
|
|
|
pullRequest, err := gh.PullRequest(url.Project, id)
|
2013-12-11 10:05:26 +04:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2013-06-22 04:01:00 +04:00
|
|
|
|
2013-12-11 10:05:26 +04:00
|
|
|
if idx := args.IndexOfParam(newBranchName); idx >= 0 {
|
|
|
|
args.RemoveParam(idx)
|
|
|
|
}
|
2013-06-22 04:01:00 +04:00
|
|
|
|
2013-12-11 10:05:26 +04:00
|
|
|
user, branch := parseUserBranchFromPR(pullRequest)
|
|
|
|
if pullRequest.Head.Repo.ID == 0 {
|
|
|
|
return fmt.Errorf("Error: %s's fork is not available anymore", user)
|
2013-07-29 21:50:28 +04:00
|
|
|
}
|
|
|
|
|
2013-12-11 10:05:26 +04:00
|
|
|
if newBranchName == "" {
|
2013-07-29 21:50:28 +04:00
|
|
|
newBranchName = fmt.Sprintf("%s-%s", user, branch)
|
2013-06-22 04:01:00 +04:00
|
|
|
}
|
2013-07-29 21:50:28 +04:00
|
|
|
|
2013-12-11 10:05:26 +04:00
|
|
|
repo := github.LocalRepo()
|
2013-12-28 13:14:07 +04:00
|
|
|
_, err = repo.RemoteByName(user)
|
2013-12-11 10:05:26 +04:00
|
|
|
if err == nil {
|
|
|
|
args.Before("git", "remote", "set-branches", "--add", user, branch)
|
|
|
|
remoteURL := fmt.Sprintf("+refs/heads/%s:refs/remotes/%s/%s", branch, user, branch)
|
|
|
|
args.Before("git", "fetch", user, remoteURL)
|
|
|
|
} else {
|
|
|
|
u := url.Project.GitURL("", user, pullRequest.Head.Repo.Private)
|
|
|
|
args.Before("git", "remote", "add", "-f", "-t", branch, user, u)
|
|
|
|
}
|
2013-06-22 04:01:00 +04:00
|
|
|
|
2013-12-11 10:05:26 +04:00
|
|
|
idx := args.IndexOfParam(checkoutURL)
|
|
|
|
args.RemoveParam(idx)
|
|
|
|
args.InsertParam(idx, "--track", "-B", newBranchName, fmt.Sprintf("%s/%s", user, branch))
|
2013-06-25 01:11:40 +04:00
|
|
|
|
2013-12-11 10:05:26 +04:00
|
|
|
return nil
|
2013-07-02 22:28:50 +04:00
|
|
|
}
|