You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

branch.go 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package repository
  5. import (
  6. "fmt"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/git"
  9. )
  10. // GetBranch returns a branch by its name
  11. func GetBranch(repo *models.Repository, branch string) (*git.Branch, error) {
  12. gitRepo, err := git.OpenRepository(repo.RepoPath())
  13. if err != nil {
  14. return nil, err
  15. }
  16. defer gitRepo.Close()
  17. return gitRepo.GetBranch(branch)
  18. }
  19. // GetBranches returns all the branches of a repository
  20. func GetBranches(repo *models.Repository) ([]*git.Branch, error) {
  21. return git.GetBranchesByPath(repo.RepoPath())
  22. }
  23. // checkBranchName validates branch name with existing repository branches
  24. func checkBranchName(repo *models.Repository, name string) error {
  25. gitRepo, err := git.OpenRepository(repo.RepoPath())
  26. if err != nil {
  27. return err
  28. }
  29. defer gitRepo.Close()
  30. branches, err := GetBranches(repo)
  31. if err != nil {
  32. return err
  33. }
  34. for _, branch := range branches {
  35. if branch.Name == name {
  36. return models.ErrBranchAlreadyExists{
  37. BranchName: branch.Name,
  38. }
  39. } else if (len(branch.Name) < len(name) && branch.Name+"/" == name[0:len(branch.Name)+1]) ||
  40. (len(branch.Name) > len(name) && name+"/" == branch.Name[0:len(name)+1]) {
  41. return models.ErrBranchNameConflict{
  42. BranchName: branch.Name,
  43. }
  44. }
  45. }
  46. if _, err := gitRepo.GetTag(name); err == nil {
  47. return models.ErrTagAlreadyExists{
  48. TagName: name,
  49. }
  50. }
  51. return nil
  52. }
  53. // CreateNewBranch creates a new repository branch
  54. func CreateNewBranch(doer *models.User, repo *models.Repository, oldBranchName, branchName string) (err error) {
  55. // Check if branch name can be used
  56. if err := checkBranchName(repo, branchName); err != nil {
  57. return err
  58. }
  59. if !git.IsBranchExist(repo.RepoPath(), oldBranchName) {
  60. return fmt.Errorf("OldBranch: %s does not exist. Cannot create new branch from this", oldBranchName)
  61. }
  62. if err := git.Push(repo.RepoPath(), git.PushOptions{
  63. Remote: repo.RepoPath(),
  64. Branch: fmt.Sprintf("%s:%s%s", oldBranchName, git.BranchPrefix, branchName),
  65. Env: models.PushingEnvironment(doer, repo),
  66. }); err != nil {
  67. if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) {
  68. return err
  69. }
  70. return fmt.Errorf("Push: %v", err)
  71. }
  72. return nil
  73. }
  74. // CreateNewBranchFromCommit creates a new repository branch
  75. func CreateNewBranchFromCommit(doer *models.User, repo *models.Repository, commit, branchName string) (err error) {
  76. // Check if branch name can be used
  77. if err := checkBranchName(repo, branchName); err != nil {
  78. return err
  79. }
  80. if err := git.Push(repo.RepoPath(), git.PushOptions{
  81. Remote: repo.RepoPath(),
  82. Branch: fmt.Sprintf("%s:%s%s", commit, git.BranchPrefix, branchName),
  83. Env: models.PushingEnvironment(doer, repo),
  84. }); err != nil {
  85. if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) {
  86. return err
  87. }
  88. return fmt.Errorf("Push: %v", err)
  89. }
  90. return nil
  91. }