github.com/jingweno/gh@v2.1.1-0.20221007190738-04a7985fa9a1+incompatible/commands/cherry_pick.go (about)

     1  package commands
     2  
     3  import (
     4  	"github.com/jingweno/gh/github"
     5  	"github.com/jingweno/gh/utils"
     6  	"regexp"
     7  )
     8  
     9  var cmdCherryPick = &Command{
    10  	Run:          cherryPick,
    11  	GitExtension: true,
    12  	Usage:        "cherry-pick GITHUB-REF",
    13  	Short:        "Apply the changes introduced by some existing commits",
    14  	Long: `Cherry-pick a commit from a fork using either full URL to the commit
    15  or GitHub-flavored Markdown notation, which is user@sha. If the remote
    16  doesn't yet exist, it will be added. A git-fetch(1) user is issued
    17  prior to the cherry-pick attempt.
    18  `,
    19  }
    20  
    21  func init() {
    22  	CmdRunner.Use(cmdCherryPick)
    23  }
    24  
    25  /*
    26    $ gh cherry-pick https://github.com/jingweno/gh/commit/a319d88#comments
    27    > git remote add -f jingweno git://github.com/jingweno/gh.git
    28    > git cherry-pick a319d88
    29  
    30    $ gh cherry-pick jingweno@a319d88
    31    > git remote add -f jingweno git://github.com/jingweno/gh.git
    32    > git cherry-pick a319d88
    33  
    34    $ gh cherry-pick jingweno@SHA
    35    > git fetch jingweno
    36    > git cherry-pick SHA
    37  */
    38  func cherryPick(command *Command, args *Args) {
    39  	if args.IndexOfParam("-m") == -1 && args.IndexOfParam("--mainline") == -1 {
    40  		transformCherryPickArgs(args)
    41  	}
    42  }
    43  
    44  func transformCherryPickArgs(args *Args) {
    45  	ref := args.LastParam()
    46  	project, sha := parseCherryPickProjectAndSha(ref)
    47  	if project != nil {
    48  		args.ReplaceParam(args.IndexOfParam(ref), sha)
    49  
    50  		if hasGitRemote(project.Owner) {
    51  			args.Before("git", "fetch", project.Owner)
    52  		} else {
    53  			args.Before("git", "remote", "add", "-f", project.Owner, project.GitURL("", "", false))
    54  		}
    55  	}
    56  }
    57  
    58  func parseCherryPickProjectAndSha(ref string) (project *github.Project, sha string) {
    59  	url, err := github.ParseURL(ref)
    60  	if err == nil {
    61  		commitRegex := regexp.MustCompile("^commit\\/([a-f0-9]{7,40})")
    62  		projectPath := url.ProjectPath()
    63  		if commitRegex.MatchString(projectPath) {
    64  			sha = commitRegex.FindStringSubmatch(projectPath)[1]
    65  			project = url.Project
    66  
    67  			return
    68  		}
    69  	}
    70  
    71  	ownerWithShaRegexp := regexp.MustCompile("^(%s)@([a-f0-9]{7,40})$")
    72  	if ownerWithShaRegexp.MatchString(ref) {
    73  		matches := ownerWithShaRegexp.FindStringSubmatch(ref)
    74  		sha = matches[2]
    75  		project, err := github.LocalRepo().CurrentProject()
    76  		utils.Check(err)
    77  		project.Owner = matches[1]
    78  	}
    79  
    80  	return
    81  }