code.gitea.io/gitea@v1.21.7/models/migrations/v1_12/v136.go (about) 1 // Copyright 2020 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package v1_12 //nolint 5 6 import ( 7 "fmt" 8 "math" 9 "path/filepath" 10 "strings" 11 "time" 12 13 "code.gitea.io/gitea/modules/git" 14 "code.gitea.io/gitea/modules/graceful" 15 "code.gitea.io/gitea/modules/log" 16 "code.gitea.io/gitea/modules/setting" 17 18 "xorm.io/xorm" 19 ) 20 21 func AddCommitDivergenceToPulls(x *xorm.Engine) error { 22 type Repository struct { 23 ID int64 `xorm:"pk autoincr"` 24 OwnerID int64 `xorm:"UNIQUE(s) index"` 25 OwnerName string 26 LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"` 27 Name string `xorm:"INDEX NOT NULL"` 28 } 29 30 type PullRequest struct { 31 ID int64 `xorm:"pk autoincr"` 32 IssueID int64 `xorm:"INDEX"` 33 Index int64 34 35 CommitsAhead int 36 CommitsBehind int 37 38 BaseRepoID int64 `xorm:"INDEX"` 39 BaseBranch string 40 41 HasMerged bool `xorm:"INDEX"` 42 MergedCommitID string `xorm:"VARCHAR(40)"` 43 } 44 45 if err := x.Sync(new(PullRequest)); err != nil { 46 return fmt.Errorf("Sync: %w", err) 47 } 48 49 last := 0 50 migrated := 0 51 52 batchSize := setting.Database.IterateBufferSize 53 sess := x.NewSession() 54 defer sess.Close() 55 56 ticker := time.NewTicker(5 * time.Second) 57 defer ticker.Stop() 58 count, err := sess.Where("has_merged = ?", false).Count(new(PullRequest)) 59 if err != nil { 60 return err 61 } 62 log.Info("%d Unmerged Pull Request(s) to migrate ...", count) 63 64 for { 65 if err := sess.Begin(); err != nil { 66 return err 67 } 68 results := make([]*PullRequest, 0, batchSize) 69 err := sess.Where("has_merged = ?", false).OrderBy("id").Limit(batchSize, last).Find(&results) 70 if err != nil { 71 return err 72 } 73 if len(results) == 0 { 74 break 75 } 76 last += batchSize 77 78 for _, pr := range results { 79 baseRepo := &Repository{ID: pr.BaseRepoID} 80 has, err := x.Table("repository").Get(baseRepo) 81 if err != nil { 82 return fmt.Errorf("Unable to get base repo %d %w", pr.BaseRepoID, err) 83 } 84 if !has { 85 log.Error("Missing base repo with id %d for PR ID %d", pr.BaseRepoID, pr.ID) 86 continue 87 } 88 userPath := filepath.Join(setting.RepoRootPath, strings.ToLower(baseRepo.OwnerName)) 89 repoPath := filepath.Join(userPath, strings.ToLower(baseRepo.Name)+".git") 90 91 gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index) 92 93 divergence, err := git.GetDivergingCommits(graceful.GetManager().HammerContext(), repoPath, pr.BaseBranch, gitRefName) 94 if err != nil { 95 log.Warn("Could not recalculate Divergence for pull: %d", pr.ID) 96 pr.CommitsAhead = 0 97 pr.CommitsBehind = 0 98 } 99 pr.CommitsAhead = divergence.Ahead 100 pr.CommitsBehind = divergence.Behind 101 102 if _, err = sess.ID(pr.ID).Cols("commits_ahead", "commits_behind").Update(pr); err != nil { 103 return fmt.Errorf("Update Cols: %w", err) 104 } 105 migrated++ 106 } 107 108 if err := sess.Commit(); err != nil { 109 return err 110 } 111 select { 112 case <-ticker.C: 113 log.Info( 114 "%d/%d (%2.0f%%) Pull Request(s) migrated in %d batches. %d PRs Remaining ...", 115 migrated, 116 count, 117 float64(migrated)/float64(count)*100, 118 int(math.Ceil(float64(migrated)/float64(batchSize))), 119 count-int64(migrated)) 120 default: 121 } 122 } 123 log.Info("Completed migrating %d Pull Request(s) in: %d batches", count, int(math.Ceil(float64(migrated)/float64(batchSize)))) 124 return nil 125 }