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.

121 lines
3.1 KiB

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