hub/commands/cherry_pick.go

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

2013-07-20 01:26:00 +04:00
package commands
2013-07-20 09:46:47 +04:00
import (
2016-09-08 16:26:30 +03:00
"fmt"
"regexp"
2014-02-10 20:22:36 +04:00
"github.com/github/hub/github"
"github.com/github/hub/utils"
2013-07-20 09:46:47 +04:00
)
2013-07-20 01:26:00 +04:00
var cmdCherryPick = &Command{
Run: cherryPick,
GitExtension: true,
Usage: `
cherry-pick <COMMIT-URL>
cherry-pick <USER>@<SHA>
`,
Long: `Cherry-pick a commit from a fork on GitHub.
2016-01-24 18:50:01 +03:00
## See also:
hub-am(1), hub(1), git-cherry-pick(1)
2013-07-20 01:26:00 +04:00
`,
}
func init() {
CmdRunner.Use(cmdCherryPick)
}
2013-07-20 01:26:00 +04:00
func cherryPick(command *Command, args *Args) {
2013-07-20 09:46:47 +04:00
if args.IndexOfParam("-m") == -1 && args.IndexOfParam("--mainline") == -1 {
transformCherryPickArgs(args)
}
}
func transformCherryPickArgs(args *Args) {
if args.IsParamsEmpty() {
return
}
var project *github.Project
var sha, refspec string
2016-09-08 16:26:30 +03:00
shaRe := "[a-f0-9]{7,40}"
var mainProject *github.Project
localRepo, mainProjectErr := github.LocalRepo()
if mainProjectErr == nil {
mainProject, mainProjectErr = localRepo.MainProject()
}
ref := args.LastParam()
if url, err := github.ParseURL(ref); err == nil {
2013-07-20 09:46:47 +04:00
projectPath := url.ProjectPath()
2016-09-08 16:26:30 +03:00
commitRegex := regexp.MustCompile(fmt.Sprintf("^commit/(%s)", shaRe))
pullRegex := regexp.MustCompile(fmt.Sprintf(`^pull/(\d+)/commits/(%s)`, shaRe))
2016-09-08 16:26:30 +03:00
if matches := commitRegex.FindStringSubmatch(projectPath); len(matches) > 0 {
sha = matches[1]
project = url.Project
} else if matches := pullRegex.FindStringSubmatch(projectPath); len(matches) > 0 {
pullId := matches[1]
sha = matches[2]
utils.Check(mainProjectErr)
project = mainProject
refspec = fmt.Sprintf("refs/pull/%s/head", pullId)
}
} else {
ownerWithShaRegexp := regexp.MustCompile(fmt.Sprintf("^(%s)@(%s)$", OwnerRe, shaRe))
if matches := ownerWithShaRegexp.FindStringSubmatch(ref); len(matches) > 0 {
utils.Check(mainProjectErr)
project = mainProject
project.Owner = matches[1]
sha = matches[2]
}
2013-07-20 09:46:47 +04:00
}
if project != nil {
args.ReplaceParam(args.IndexOfParam(ref), sha)
tmpName := "_hub-cherry-pick"
remoteName := tmpName
if remote, err := localRepo.RemoteForProject(project); err == nil {
remoteName = remote.Name
} else {
args.Before("git", "remote", "add", remoteName, project.GitURL("", "", false))
}
2013-07-20 09:46:47 +04:00
fetchArgs := []string{"git", "fetch", "-q", "--no-tags", remoteName}
if refspec != "" {
fetchArgs = append(fetchArgs, refspec)
}
args.Before(fetchArgs...)
if remoteName == tmpName {
args.Before("git", "remote", "rm", remoteName)
}
}
2013-07-20 09:46:47 +04:00
}