repo_branch.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright 2015 The Gogs 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 git
  5. import (
  6. "fmt"
  7. "strings"
  8. "github.com/mcuadros/go-version"
  9. )
  10. const BRANCH_PREFIX = "refs/heads/"
  11. // IsReferenceExist returns true if given reference exists in the repository.
  12. func IsReferenceExist(repoPath, name string) bool {
  13. _, err := NewCommand("show-ref", "--verify", name).RunInDir(repoPath)
  14. return err == nil
  15. }
  16. // IsBranchExist returns true if given branch exists in the repository.
  17. func IsBranchExist(repoPath, name string) bool {
  18. return IsReferenceExist(repoPath, BRANCH_PREFIX+name)
  19. }
  20. func (repo *Repository) IsBranchExist(name string) bool {
  21. return IsBranchExist(repo.Path, name)
  22. }
  23. // Branch represents a Git branch.
  24. type Branch struct {
  25. Name string
  26. Path string
  27. }
  28. // GetHEADBranch returns corresponding branch of HEAD.
  29. func (repo *Repository) GetHEADBranch() (*Branch, error) {
  30. stdout, err := NewCommand("symbolic-ref", "HEAD").RunInDir(repo.Path)
  31. if err != nil {
  32. return nil, err
  33. }
  34. stdout = strings.TrimSpace(stdout)
  35. if !strings.HasPrefix(stdout, BRANCH_PREFIX) {
  36. return nil, fmt.Errorf("invalid HEAD branch: %v", stdout)
  37. }
  38. return &Branch{
  39. Name: stdout[len(BRANCH_PREFIX):],
  40. Path: stdout,
  41. }, nil
  42. }
  43. // SetDefaultBranch sets default branch of repository.
  44. func (repo *Repository) SetDefaultBranch(name string) error {
  45. if version.Compare(gitVersion, "1.7.10", "<") {
  46. return ErrUnsupportedVersion{"1.7.10"}
  47. }
  48. _, err := NewCommand("symbolic-ref", "HEAD", BRANCH_PREFIX+name).RunInDir(repo.Path)
  49. return err
  50. }
  51. // GetBranches returns all branches of the repository.
  52. func (repo *Repository) GetBranches() ([]string, error) {
  53. stdout, err := NewCommand("show-ref", "--heads").RunInDir(repo.Path)
  54. if err != nil {
  55. return nil, err
  56. }
  57. infos := strings.Split(stdout, "\n")
  58. branches := make([]string, len(infos)-1)
  59. for i, info := range infos[:len(infos)-1] {
  60. fields := strings.Fields(info)
  61. if len(fields) != 2 {
  62. continue // NOTE: I should believe git will not give me wrong string.
  63. }
  64. branches[i] = strings.TrimPrefix(fields[1], BRANCH_PREFIX)
  65. }
  66. return branches, nil
  67. }
  68. // Option(s) for delete branch
  69. type DeleteBranchOptions struct {
  70. Force bool
  71. }
  72. // DeleteBranch deletes a branch from given repository path.
  73. func DeleteBranch(repoPath, name string, opts DeleteBranchOptions) error {
  74. cmd := NewCommand("branch")
  75. if opts.Force {
  76. cmd.AddArguments("-D")
  77. } else {
  78. cmd.AddArguments("-d")
  79. }
  80. cmd.AddArguments(name)
  81. _, err := cmd.RunInDir(repoPath)
  82. return err
  83. }
  84. // DeleteBranch deletes a branch from repository.
  85. func (repo *Repository) DeleteBranch(name string, opts DeleteBranchOptions) error {
  86. return DeleteBranch(repo.Path, name, opts)
  87. }
  88. // AddRemote adds a new remote to repository.
  89. func (repo *Repository) AddRemote(name, url string, fetch bool) error {
  90. cmd := NewCommand("remote", "add")
  91. if fetch {
  92. cmd.AddArguments("-f")
  93. }
  94. cmd.AddArguments(name, url)
  95. _, err := cmd.RunInDir(repo.Path)
  96. return err
  97. }
  98. // RemoveRemote removes a remote from repository.
  99. func (repo *Repository) RemoveRemote(name string) error {
  100. _, err := NewCommand("remote", "remove", name).RunInDir(repo.Path)
  101. return err
  102. }