update.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright 2014 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 models
  5. import (
  6. "container/list"
  7. "fmt"
  8. "os/exec"
  9. "strings"
  10. "github.com/gogits/gogs/modules/base"
  11. "github.com/gogits/gogs/modules/git"
  12. "github.com/gogits/gogs/modules/log"
  13. )
  14. type UpdateTask struct {
  15. ID int64 `xorm:"pk autoincr"`
  16. UUID string `xorm:"index"`
  17. RefName string
  18. OldCommitID string
  19. NewCommitID string
  20. }
  21. func AddUpdateTask(task *UpdateTask) error {
  22. _, err := x.Insert(task)
  23. return err
  24. }
  25. // GetUpdateTaskByUUID returns update task by given UUID.
  26. func GetUpdateTaskByUUID(uuid string) (*UpdateTask, error) {
  27. task := &UpdateTask{
  28. UUID: uuid,
  29. }
  30. has, err := x.Get(task)
  31. if err != nil {
  32. return nil, err
  33. } else if !has {
  34. return nil, ErrUpdateTaskNotExist{uuid}
  35. }
  36. return task, nil
  37. }
  38. func DeleteUpdateTaskByUUID(uuid string) error {
  39. _, err := x.Delete(&UpdateTask{UUID: uuid})
  40. return err
  41. }
  42. func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) error {
  43. isNew := strings.HasPrefix(oldCommitId, "0000000")
  44. if isNew &&
  45. strings.HasPrefix(newCommitId, "0000000") {
  46. return fmt.Errorf("old rev and new rev both 000000")
  47. }
  48. f := RepoPath(repoUserName, repoName)
  49. gitUpdate := exec.Command("git", "update-server-info")
  50. gitUpdate.Dir = f
  51. gitUpdate.Run()
  52. isDel := strings.HasPrefix(newCommitId, "0000000")
  53. if isDel {
  54. log.GitLogger.Info("del rev", refName, "from", userName+"/"+repoName+".git", "by", userId)
  55. return nil
  56. }
  57. repo, err := git.OpenRepository(f)
  58. if err != nil {
  59. return fmt.Errorf("runUpdate.Open repoId: %v", err)
  60. }
  61. ru, err := GetUserByName(repoUserName)
  62. if err != nil {
  63. return fmt.Errorf("runUpdate.GetUserByName: %v", err)
  64. }
  65. repos, err := GetRepositoryByName(ru.Id, repoName)
  66. if err != nil {
  67. return fmt.Errorf("runUpdate.GetRepositoryByName userId: %v", err)
  68. }
  69. // Push tags.
  70. if strings.HasPrefix(refName, "refs/tags/") {
  71. tagName := git.RefEndName(refName)
  72. tag, err := repo.GetTag(tagName)
  73. if err != nil {
  74. log.GitLogger.Fatal(4, "runUpdate.GetTag: %v", err)
  75. }
  76. var actEmail string
  77. if tag.Tagger != nil {
  78. actEmail = tag.Tagger.Email
  79. } else {
  80. cmt, err := tag.Commit()
  81. if err != nil {
  82. log.GitLogger.Fatal(4, "runUpdate.GetTag Commit: %v", err)
  83. }
  84. actEmail = cmt.Committer.Email
  85. }
  86. commit := &base.PushCommits{}
  87. if err = CommitRepoAction(userId, ru.Id, userName, actEmail,
  88. repos.ID, repoUserName, repoName, refName, commit, oldCommitId, newCommitId); err != nil {
  89. log.GitLogger.Fatal(4, "CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
  90. }
  91. return err
  92. }
  93. newCommit, err := repo.GetCommit(newCommitId)
  94. if err != nil {
  95. return fmt.Errorf("runUpdate GetCommit of newCommitId: %v", err)
  96. }
  97. // Push new branch.
  98. var l *list.List
  99. if isNew {
  100. l, err = newCommit.CommitsBefore()
  101. if err != nil {
  102. return fmt.Errorf("CommitsBefore: %v", err)
  103. }
  104. } else {
  105. l, err = newCommit.CommitsBeforeUntil(oldCommitId)
  106. if err != nil {
  107. return fmt.Errorf("CommitsBeforeUntil: %v", err)
  108. }
  109. }
  110. if err != nil {
  111. return fmt.Errorf("runUpdate.Commit repoId: %v", err)
  112. }
  113. // Push commits.
  114. commits := make([]*base.PushCommit, 0)
  115. var actEmail string
  116. for e := l.Front(); e != nil; e = e.Next() {
  117. commit := e.Value.(*git.Commit)
  118. if actEmail == "" {
  119. actEmail = commit.Committer.Email
  120. }
  121. commits = append(commits,
  122. &base.PushCommit{commit.ID.String(),
  123. commit.Message(),
  124. commit.Author.Email,
  125. commit.Author.Name,
  126. })
  127. }
  128. if err = CommitRepoAction(userId, ru.Id, userName, actEmail,
  129. repos.ID, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits, ""}, oldCommitId, newCommitId); err != nil {
  130. return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
  131. }
  132. return nil
  133. }