gitea源码

repo_commit_gogit.go 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 The Gitea Authors. All rights reserved.
  3. // SPDX-License-Identifier: MIT
  4. //go:build gogit
  5. package git
  6. import (
  7. "strings"
  8. "code.gitea.io/gitea/modules/git/gitcmd"
  9. "github.com/go-git/go-git/v5/plumbing"
  10. "github.com/go-git/go-git/v5/plumbing/hash"
  11. "github.com/go-git/go-git/v5/plumbing/object"
  12. )
  13. // GetRefCommitID returns the last commit ID string of given reference.
  14. func (repo *Repository) GetRefCommitID(name string) (string, error) {
  15. if plumbing.IsHash(name) {
  16. return name, nil
  17. }
  18. refName := plumbing.ReferenceName(name)
  19. if err := refName.Validate(); err != nil {
  20. return "", err
  21. }
  22. ref, err := repo.gogitRepo.Reference(refName, true)
  23. if err != nil {
  24. if err == plumbing.ErrReferenceNotFound {
  25. return "", ErrNotExist{
  26. ID: name,
  27. }
  28. }
  29. return "", err
  30. }
  31. return ref.Hash().String(), nil
  32. }
  33. // ConvertToHash returns a Hash object from a potential ID string
  34. func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) {
  35. objectFormat, err := repo.GetObjectFormat()
  36. if err != nil {
  37. return nil, err
  38. }
  39. if len(commitID) == hash.HexSize && objectFormat.IsValid(commitID) {
  40. ID, err := NewIDFromString(commitID)
  41. if err == nil {
  42. return ID, nil
  43. }
  44. }
  45. actualCommitID, _, err := gitcmd.NewCommand("rev-parse", "--verify").AddDynamicArguments(commitID).RunStdString(repo.Ctx, &gitcmd.RunOpts{Dir: repo.Path})
  46. actualCommitID = strings.TrimSpace(actualCommitID)
  47. if err != nil {
  48. if strings.Contains(err.Error(), "unknown revision or path") ||
  49. strings.Contains(err.Error(), "fatal: Needed a single revision") {
  50. return objectFormat.EmptyObjectID(), ErrNotExist{commitID, ""}
  51. }
  52. return objectFormat.EmptyObjectID(), err
  53. }
  54. return NewIDFromString(actualCommitID)
  55. }
  56. // IsCommitExist returns true if given commit exists in current repository.
  57. func (repo *Repository) IsCommitExist(name string) bool {
  58. hash, err := repo.ConvertToGitID(name)
  59. if err != nil {
  60. return false
  61. }
  62. _, err = repo.gogitRepo.CommitObject(plumbing.Hash(hash.RawValue()))
  63. return err == nil
  64. }
  65. func (repo *Repository) getCommit(id ObjectID) (*Commit, error) {
  66. var tagObject *object.Tag
  67. commitID := plumbing.Hash(id.RawValue())
  68. gogitCommit, err := repo.gogitRepo.CommitObject(commitID)
  69. if err == plumbing.ErrObjectNotFound {
  70. tagObject, err = repo.gogitRepo.TagObject(commitID)
  71. if err == plumbing.ErrObjectNotFound {
  72. return nil, ErrNotExist{
  73. ID: id.String(),
  74. }
  75. }
  76. if err == nil {
  77. gogitCommit, err = repo.gogitRepo.CommitObject(tagObject.Target)
  78. }
  79. // if we get a plumbing.ErrObjectNotFound here then the repository is broken and it should be 500
  80. }
  81. if err != nil {
  82. return nil, err
  83. }
  84. commit := convertCommit(gogitCommit)
  85. commit.repo = repo
  86. tree, err := gogitCommit.Tree()
  87. if err != nil {
  88. return nil, err
  89. }
  90. commit.Tree.ID = ParseGogitHash(tree.Hash)
  91. commit.Tree.gogitTree = tree
  92. return commit, nil
  93. }