@@ -6,25 +6,60 @@ package migrations
66
77import (
88 "fmt"
9+ "math"
10+ "path/filepath"
11+ "strings"
12+ "time"
913
1014 "code.gitea.io/gitea/models"
15+ "code.gitea.io/gitea/modules/git"
1116 "code.gitea.io/gitea/modules/log"
1217 "code.gitea.io/gitea/modules/setting"
13- pull_service "code.gitea.io/gitea/services/pull"
1418
1519 "xorm.io/xorm"
1620)
1721
1822func addCommitDivergenceToPulls (x * xorm.Engine ) error {
23+ type Repository struct {
24+ ID int64 `xorm:"pk autoincr"`
25+ OwnerID int64 `xorm:"UNIQUE(s) index"`
26+ OwnerName string
27+ LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
28+ Name string `xorm:"INDEX NOT NULL"`
29+ }
30+
31+ type PullRequest struct {
32+ ID int64 `xorm:"pk autoincr"`
33+
34+ CommitsAhead int
35+ CommitsBehind int
36+
37+ BaseRepoID int64 `xorm:"INDEX"`
38+ BaseBranch string
39+
40+ HasMerged bool `xorm:"INDEX"`
41+ MergedCommitID string `xorm:"VARCHAR(40)"`
42+ }
1943
2044 if err := x .Sync2 (new (models.PullRequest )); err != nil {
2145 return fmt .Errorf ("Sync2: %v" , err )
2246 }
2347
24- var last int
48+ last := 0
49+ migrated := 0
50+
2551 batchSize := setting .Database .IterateBufferSize
2652 sess := x .NewSession ()
2753 defer sess .Close ()
54+
55+ ticker := time .NewTicker (5 * time .Second )
56+ defer ticker .Stop ()
57+ count , err := sess .Where ("has_merged = ?" , false ).Count (new (PullRequest ))
58+ if err != nil {
59+ return err
60+ }
61+ log .Info ("%d Unmerged Pull Request(s) to migrate ..." , count )
62+
2863 for {
2964 if err := sess .Begin (); err != nil {
3065 return err
@@ -37,27 +72,53 @@ func addCommitDivergenceToPulls(x *xorm.Engine) error {
3772 if len (results ) == 0 {
3873 break
3974 }
40- last += len ( results )
75+ last += batchSize
4176
4277 for _ , pr := range results {
43- divergence , err := pull_service .GetDiverging (pr )
78+ baseRepo := & Repository {ID : pr .BaseRepoID }
79+ has , err := x .Table ("repository" ).Get (baseRepo )
80+ if err != nil {
81+ return fmt .Errorf ("Unable to get base repo %d %v" , pr .BaseRepoID , err )
82+ }
83+ if ! has {
84+ log .Error ("Missing base repo with id %d for PR ID %d" , pr .BaseRepoID , pr .ID )
85+ continue
86+ }
87+ userPath := filepath .Join (setting .RepoRootPath , strings .ToLower (baseRepo .OwnerName ))
88+ repoPath := filepath .Join (userPath , strings .ToLower (baseRepo .Name )+ ".git" )
89+
90+ gitRefName := fmt .Sprintf ("refs/pull/%d/head" , pr .Index )
91+
92+ divergence , err := git .GetDivergingCommits (repoPath , pr .BaseBranch , gitRefName )
4493 if err != nil {
4594 log .Warn ("Could not recalculate Divergence for pull: %d" , pr .ID )
4695 pr .CommitsAhead = 0
4796 pr .CommitsBehind = 0
4897 }
49- if divergence != nil {
50- pr .CommitsAhead = divergence .Ahead
51- pr .CommitsBehind = divergence .Behind
52- }
98+ pr .CommitsAhead = divergence .Ahead
99+ pr .CommitsBehind = divergence .Behind
100+
53101 if _ , err = sess .ID (pr .ID ).Cols ("commits_ahead" , "commits_behind" ).Update (pr ); err != nil {
54102 return fmt .Errorf ("Update Cols: %v" , err )
55103 }
104+ migrated ++
56105 }
57106
58107 if err := sess .Commit (); err != nil {
59108 return err
60109 }
110+ select {
111+ case <- ticker .C :
112+ log .Info (
113+ "%d/%d (%2.0f%%) Pull Request(s) migrated in %d batches. %d PRs Remaining ..." ,
114+ migrated ,
115+ count ,
116+ float64 (migrated )/ float64 (count )* 100 ,
117+ int (math .Ceil (float64 (migrated )/ float64 (batchSize ))),
118+ count - int64 (migrated ))
119+ default :
120+ }
61121 }
122+ log .Info ("Completed migrating %d Pull Request(s) in: %d batches" , count , int (math .Ceil (float64 (migrated )/ float64 (batchSize ))))
62123 return nil
63124}
0 commit comments