hub/commands/checkout.go

126 строки
2.8 KiB
Go
Исходник Обычный вид История

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"
2013-06-22 00:17:52 +04:00
"github.com/jingweno/gh/git"
2013-06-22 04:01:00 +04:00
"github.com/jingweno/gh/github"
2013-06-22 00:17:52 +04:00
"github.com/jingweno/gh/utils"
2013-06-22 04:01:00 +04:00
"regexp"
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-06-22 00:17:52 +04:00
/**
$ gh checkout https://github.com/jingweno/gh/pull/73
# > git remote add -f -t feature git://github:com/foo/gh.git
# > git checkout --track -B foo-feature foo/feature
$ gh checkout https://github.com/jingweno/gh/pull/73 custom-branch-name
**/
2013-06-21 22:40:42 +04:00
func checkout(command *Command, args []string) {
2013-06-22 04:01:00 +04:00
var err error
2013-06-22 00:17:52 +04:00
if len(args) > 0 {
2013-06-22 04:01:00 +04:00
args, err = transformCheckoutArgs(args)
2013-06-22 05:02:29 +04:00
utils.Fatal(err)
2013-06-22 00:17:52 +04:00
}
2013-06-25 01:40:05 +04:00
err = git.SysExec("checkout", args...)
2013-06-22 00:17:52 +04:00
utils.Check(err)
}
2013-06-22 04:01:00 +04:00
func transformCheckoutArgs(args []string) ([]string, error) {
id := parsePullRequestId(args[0])
if id != "" {
newArgs, url := removeItem(args, 0)
gh := github.New()
pullRequest, err := gh.PullRequest(id)
if err != nil {
return nil, err
}
user := pullRequest.User.Login
branch := pullRequest.Head.Ref
if pullRequest.Head.Repo.ID == 0 {
return nil, fmt.Errorf("%s's fork is not available anymore", user)
}
2013-06-22 05:02:29 +04:00
2013-06-25 01:11:40 +04:00
remoteExists, err := checkIfRemoteExists(user)
2013-06-22 17:24:07 +04:00
if err != nil {
return nil, err
}
2013-06-25 00:43:59 +04:00
if remoteExists {
2013-06-25 01:11:40 +04:00
err = updateExistingRemote(user, branch)
2013-06-22 05:02:29 +04:00
} else {
2013-06-25 01:11:40 +04:00
err = addRmote(user, branch, url, pullRequest.Head.Repo.Private)
}
if err != nil {
return nil, err
2013-06-22 05:02:29 +04:00
}
2013-06-22 04:01:00 +04:00
var newBranchName string
if len(newArgs) > 0 {
newArgs, newBranchName = removeItem(newArgs, 0)
} else {
newBranchName = fmt.Sprintf("%s-%s", user, branch)
}
2013-06-25 01:11:40 +04:00
trackedBranch := fmt.Sprintf("%s/%s", user, branch)
2013-06-22 04:01:00 +04:00
newArgs = append(newArgs, "--track", "-B", newBranchName, trackedBranch)
return newArgs, nil
}
return args, nil
}
func parsePullRequestId(url string) string {
pullURLRegex := regexp.MustCompile("https://github\\.com/.+/.+/pull/(\\d+)")
if pullURLRegex.MatchString(url) {
return pullURLRegex.FindStringSubmatch(url)[1]
}
return ""
2013-06-21 22:40:42 +04:00
}
2013-06-25 01:11:40 +04:00
func checkIfRemoteExists(remote string) (bool, error) {
remotes, err := git.Remotes()
if err != nil {
return false, err
}
for _, r := range remotes {
if r.Name == remote {
return true, nil
}
}
return false, nil
}
func updateExistingRemote(user, branch string) error {
err := git.Spawn("remote", "set-branches", "--add", user, branch)
if err != nil {
return err
}
remoteURL := fmt.Sprintf("+refs/heads/%s:refs/remotes/%s/%s", branch, user, branch)
return git.Spawn("fetch", user, remoteURL)
}
func addRmote(user, branch, url string, isPrivate bool) error {
project, err := github.ParseProjectFromURL(url)
if err != nil {
return err
}
sshURL := project.GitURL("", user, isPrivate)
return git.Spawn("remote", "add", "-f", "-t", branch, user, sshURL)
}