func transformCheckoutArgs(args *Args) error { words := args.Words() if len(words) == 0 { return nil } checkoutURL := words[0] url, err := github.ParseURL(checkoutURL) if err != nil { return nil } var newBranchName string if len(words) > 1 { newBranchName = words[1] } pullURLRegex := regexp.MustCompile("^pull/(\\d+)") projectPath := url.ProjectPath() if !pullURLRegex.MatchString(projectPath) { return nil } id := pullURLRegex.FindStringSubmatch(projectPath)[1] gh := github.NewClient(url.Project.Host) pullRequest, err := gh.PullRequest(url.Project, id) if err != nil { return err } if idx := args.IndexOfParam(newBranchName); idx >= 0 { args.RemoveParam(idx) } user, branch := parseUserBranchFromPR(pullRequest) if pullRequest.Head.Repo.ID == 0 { return fmt.Errorf("Error: %s's fork is not available anymore", user) } if newBranchName == "" { newBranchName = fmt.Sprintf("%s-%s", user, branch) } repo := github.LocalRepo() _, err = repo.RemoteByName(user) 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) } idx := args.IndexOfParam(checkoutURL) args.RemoveParam(idx) args.InsertParam(idx, "--track", "-B", newBranchName, fmt.Sprintf("%s/%s", user, branch)) return nil }
func convertToGitURL(pullRequestURL, user string, isSSH bool) (string, error) { url, err := github.ParseURL(pullRequestURL) if err != nil { return "", err } return url.GitURL("", user, isSSH), nil }
func parsePullRequestIssueNumber(url string) string { u, e := github.ParseURL(url) if e != nil { return "" } r := regexp.MustCompile(`^issues\/(\d+)`) p := u.ProjectPath() if r.MatchString(p) { return r.FindStringSubmatch(p)[1] } return "" }
func parsePullRequestId(rawurl string) (id string) { url, err := github.ParseURL(rawurl) if err != nil { return } pullURLRegex := regexp.MustCompile("^pull/(\\d+)") projectPath := url.ProjectPath() if pullURLRegex.MatchString(projectPath) { id = pullURLRegex.FindStringSubmatch(projectPath)[1] } return }
func transformMergeArgs(args *Args) error { words := args.Words() if len(words) == 0 { return nil } mergeURL := words[0] url, err := github.ParseURL(mergeURL) if err != nil { return nil } pullURLRegex := regexp.MustCompile("^pull/(\\d+)") projectPath := url.ProjectPath() if !pullURLRegex.MatchString(projectPath) { return nil } id := pullURLRegex.FindStringSubmatch(projectPath)[1] gh := github.NewClient(url.Project.Host) pullRequest, err := gh.PullRequest(url.Project, id) if err != nil { return err } user, branch := parseUserBranchFromPR(pullRequest) if pullRequest.Head.Repo.ID == 0 { return fmt.Errorf("Error: %s's fork is not available anymore", user) } u := url.GitURL("", user, pullRequest.Head.Repo.Private) mergeHead := fmt.Sprintf("%s/%s", user, branch) ref := fmt.Sprintf("+refs/heads/%s:refs/remotes/%s", branch, mergeHead) args.Before("git", "fetch", u, ref) // Remove pull request URL idx := args.IndexOfParam(mergeURL) args.RemoveParam(idx) mergeMsg := fmt.Sprintf(`"Merge pull request #%v from %s\n\n%s"`, id, mergeHead, pullRequest.Title) args.AppendParams(mergeHead, "-m", mergeMsg) if args.IndexOfParam("--ff-only") == -1 { i := args.IndexOfParam("-m") args.InsertParam(i, "--no-ff") } return nil }
func parseCherryPickProjectAndSha(ref string) (project *github.Project, sha string) { url, err := github.ParseURL(ref) if err == nil { commitRegex := regexp.MustCompile("^commit\\/([a-f0-9]{7,40})") projectPath := url.ProjectPath() if commitRegex.MatchString(projectPath) { sha = commitRegex.FindStringSubmatch(projectPath)[1] project = &url.Project return } } ownerWithShaRegexp := regexp.MustCompile("^(%s)@([a-f0-9]{7,40})$") if ownerWithShaRegexp.MatchString(ref) { matches := ownerWithShaRegexp.FindStringSubmatch(ref) sha = matches[2] project = github.CurrentProject() project.Owner = matches[1] } return }
/* $ gh fork [ repo forked on GitHub ] > git remote add -f YOUR_USER [email protected]:YOUR_USER/CURRENT_REPO.git $ gh fork --no-remote [ repo forked on GitHub ] */ func fork(cmd *Command, args *Args) { localRepo := github.LocalRepo() project, err := localRepo.MainProject() utils.Check(err) configs := github.CurrentConfigs() credentials := configs.PromptFor(project.Host) forkProject := github.NewProject(credentials.User, project.Name, project.Host) client := github.NewClient(project.Host) existingRepo, err := client.Repository(forkProject) if err == nil { var parentURL *github.URL if parent := existingRepo.Parent; parent != nil { parentURL, _ = github.ParseURL(parent.HTMLURL) } if parentURL == nil || !reflect.DeepEqual(parentURL.Project, project) { err = fmt.Errorf("Error creating fork: %s already exists on %s", forkProject, forkProject.Host) utils.Check(err) } } else { if !args.Noop { _, err := client.ForkRepository(project) utils.Check(err) } } if flagForkNoRemote { os.Exit(0) } else { u := forkProject.GitURL("", "", true) args.Replace("git", "remote", "add", "-f", forkProject.Owner, u) args.After("echo", fmt.Sprintf("new remote: %s", forkProject.Owner)) } }