/commands/merge.go

https://gitlab.com/jslee1/hub · Go · 88 lines · 72 code · 15 blank · 1 comment · 16 complexity · 8e5bd20536c3c3ff0571d95843533378 MD5 · raw file

  1. package commands
  2. import (
  3. "fmt"
  4. "regexp"
  5. "github.com/github/hub/github"
  6. "github.com/github/hub/utils"
  7. )
  8. var cmdMerge = &Command{
  9. Run: merge,
  10. GitExtension: true,
  11. Usage: "merge <PULLREQ-URL>",
  12. Long: `Merge a pull request with a message like the GitHub Merge Button.
  13. ## Examples:
  14. $ hub merge https://github.com/jingweno/gh/pull/73
  15. > git fetch git://github.com/jingweno/gh.git +refs/heads/feature:refs/remotes/jingweno/feature
  16. > git merge jingweno/feature --no-ff -m "Merge pull request #73 from jingweno/feature..."
  17. ## See also:
  18. hub-checkout(1), hub(1), git-merge(1)
  19. `,
  20. }
  21. func init() {
  22. CmdRunner.Use(cmdMerge)
  23. }
  24. func merge(command *Command, args *Args) {
  25. if !args.IsParamsEmpty() {
  26. err := transformMergeArgs(args)
  27. utils.Check(err)
  28. }
  29. }
  30. func transformMergeArgs(args *Args) error {
  31. words := args.Words()
  32. if len(words) == 0 {
  33. return nil
  34. }
  35. mergeURL := words[0]
  36. url, err := github.ParseURL(mergeURL)
  37. if err != nil {
  38. return nil
  39. }
  40. pullURLRegex := regexp.MustCompile("^pull/(\\d+)")
  41. projectPath := url.ProjectPath()
  42. if !pullURLRegex.MatchString(projectPath) {
  43. return nil
  44. }
  45. id := pullURLRegex.FindStringSubmatch(projectPath)[1]
  46. gh := github.NewClient(url.Project.Host)
  47. pullRequest, err := gh.PullRequest(url.Project, id)
  48. if err != nil {
  49. return err
  50. }
  51. branch := pullRequest.Head.Ref
  52. headRepo := pullRequest.Head.Repo
  53. if headRepo == nil {
  54. return fmt.Errorf("Error: that fork is not available anymore")
  55. }
  56. u := url.GitURL(headRepo.Name, headRepo.Owner.Login, headRepo.Private)
  57. mergeHead := fmt.Sprintf("%s/%s", headRepo.Owner.Login, branch)
  58. ref := fmt.Sprintf("+refs/heads/%s:refs/remotes/%s", branch, mergeHead)
  59. args.Before("git", "fetch", u, ref)
  60. // Remove pull request URL
  61. idx := args.IndexOfParam(mergeURL)
  62. args.RemoveParam(idx)
  63. mergeMsg := fmt.Sprintf("Merge pull request #%v from %s\n\n%s", id, mergeHead, pullRequest.Title)
  64. args.AppendParams(mergeHead, "-m", mergeMsg)
  65. if args.IndexOfParam("--ff-only") == -1 && args.IndexOfParam("--squash") == -1 && args.IndexOfParam("--ff") == -1 {
  66. i := args.IndexOfParam("-m")
  67. args.InsertParam(i, "--no-ff")
  68. }
  69. return nil
  70. }