@@ -3,78 +3,116 @@ package branch
3
3
import (
4
4
"fmt"
5
5
git2go "github.com/libgit2/git2go/v31"
6
+ "github.com/neel1996/gitconvex/git/middleware"
6
7
"github.com/neel1996/gitconvex/global"
7
8
"github.com/neel1996/gitconvex/graph/model"
9
+ "github.com/neel1996/gitconvex/validator"
8
10
"sort"
9
11
"strings"
10
12
)
11
13
12
14
type Compare interface {
13
- CompareBranch () []* model.BranchCompareResults
15
+ CompareBranch (baseBranchName string , diffBranchName string ) ( []* model.BranchCompareResults , error )
14
16
}
15
17
16
18
type branchCompare struct {
17
- repo * git2go.Repository
18
- baseBranch string
19
- diffBranch string
19
+ repo middleware.Repository
20
+ branchValidator validator.ValidatorWithStringFields
20
21
}
21
22
22
- func returnBranchCompareError (errString string ) []* model.BranchCompareResults {
23
- if errString != "" {
24
- logger .Log (errString , global .StatusWarning )
25
- return []* model.BranchCompareResults {}
26
- }
27
- return nil
23
+ func logAndReturnError (err error ) ([]* model.BranchCompareResults , error ) {
24
+ logger .Log (err .Error (), global .StatusError )
25
+ return []* model.BranchCompareResults {}, err
28
26
}
29
27
30
28
// CompareBranch compares two branches and returns the commits which are different from each other
31
29
// The function uses the git client to fetch the results as go-git lacks this feature
32
- func (b branchCompare ) CompareBranch () []* model.BranchCompareResults {
30
+ func (b branchCompare ) CompareBranch (baseBranchName string , diffBranchName string ) ( []* model.BranchCompareResults , error ) {
33
31
var diffCommits []* model.BranchCompareResults
34
32
var filteredCommits []model.GitCommits
35
- repo := b .repo
36
33
37
- if err := NewBranchFieldsValidation ( repo , b . baseBranch , b . diffBranch ). ValidateBranchFields (); err != nil {
38
- return returnBranchCompareError ( err . Error () )
34
+ if validationErr := b . branchValidator . ValidateWithFields ( baseBranchName , diffBranchName ); validationErr != nil {
35
+ return logAndReturnError ( validationErr )
39
36
}
40
37
41
- baseBranch , baseBranchErr := repo .LookupBranch (b .baseBranch , git2go .BranchLocal )
42
- compareBranch , compareBranchErr := repo .LookupBranch (b .diffBranch , git2go .BranchLocal )
43
-
44
- if baseBranchErr != nil || compareBranchErr != nil {
45
- return returnBranchCompareError (fmt .Sprintf ("Unable to lookup target branches from the repo : %v %v" , baseBranchErr , compareBranchErr ))
38
+ baseBranch , compareBranch , lookupErr := b .lookupBranch (baseBranchName , diffBranchName )
39
+ if lookupErr != nil {
40
+ return logAndReturnError (LookupError )
46
41
}
47
42
48
- compareResult := baseBranch .Cmp (compareBranch .Reference )
43
+ compareResult := baseBranch .Cmp (compareBranch .Reference () )
49
44
if compareResult == 0 {
50
- return returnBranchCompareError ( "There are no difference between both the branches" )
45
+ return logAndReturnError ( CompareError )
51
46
}
52
47
53
- baseTarget := baseBranch .Target ()
54
- compareTarget := compareBranch .Target ()
48
+ baseHeadCommit , compareHeadCommit , headCommitErr := b .getHeadCommits (baseBranch , compareBranch )
49
+ if headCommitErr != nil {
50
+ return logAndReturnError (NilHeadError )
51
+ }
52
+
53
+ baseBranchCommits , compareBranchCommits := b .getAncestorsOf (baseHeadCommit , compareHeadCommit )
55
54
56
- baseHead , _ := repo .LookupCommit (baseTarget )
57
- compareHead , _ := repo .LookupCommit (compareTarget )
55
+ filteredCommits = filterDifferingCommits (compareBranchCommits , baseBranchCommits )
56
+ commitMap := generateCommitMap (filteredCommits )
57
+ diffCommits = sortCommitsInDescendingOrderOfDate (commitMap , diffCommits )
58
58
59
- if baseHead == nil || compareHead == nil {
60
- return returnBranchCompareError ("Branch head is NIL" )
59
+ return diffCommits , nil
60
+ }
61
+
62
+ func (b branchCompare ) lookupBranch (baseBranchName string , diffBranchName string ) (middleware.Branch , middleware.Branch , error ) {
63
+ var (
64
+ baseBranchErr error
65
+ compareBranchErr error
66
+ )
67
+
68
+ baseBranch , baseBranchErr := b .repo .LookupBranch (baseBranchName , git2go .BranchLocal )
69
+
70
+ if baseBranchErr != nil {
71
+ logger .Log (baseBranchErr .Error (), global .StatusError )
72
+ return nil , nil , baseBranchErr
61
73
}
62
74
63
- baseBranchMap := make (map [string ]* git2go.Commit )
64
- compareBranchMap := make (map [string ]* git2go.Commit )
75
+ compareBranch , compareBranchErr := b .repo .LookupBranch (diffBranchName , git2go .BranchLocal )
76
+ if compareBranchErr != nil {
77
+ logger .Log (compareBranchErr .Error (), global .StatusError )
78
+ return nil , nil , compareBranchErr
79
+ }
65
80
66
- baseBranchMap = getParentCommits ( baseHead )
67
- compareBranchMap = getParentCommits ( compareHead )
81
+ return baseBranch , compareBranch , nil
82
+ }
68
83
69
- filteredCommits = filterDifferingCommits (compareBranchMap , baseBranchMap )
70
- commitMap := generateCommitMaps (filteredCommits )
71
- diffCommits = sortCommitsBasedOnDate (commitMap , diffCommits )
84
+ func (b branchCompare ) getHeadCommits (baseBranch middleware.Branch , compareBranch middleware.Branch ) (middleware.Commit , middleware.Commit , error ) {
85
+ var (
86
+ baseHeadErr error
87
+ compareHeadErr error
88
+ )
72
89
73
- return diffCommits
90
+ baseTarget := baseBranch .Target ()
91
+ baseHead , baseHeadErr := b .repo .LookupCommitV2 (baseTarget )
92
+ if baseHeadErr != nil {
93
+ logger .Log (baseHeadErr .Error (), global .StatusError )
94
+ return nil , nil , baseHeadErr
95
+ }
96
+
97
+ compareTarget := compareBranch .Target ()
98
+ compareHead , compareHeadErr := b .repo .LookupCommitV2 (compareTarget )
99
+ if compareHeadErr != nil {
100
+ logger .Log (compareHeadErr .Error (), global .StatusError )
101
+ return nil , nil , compareHeadErr
102
+ }
103
+
104
+ return baseHead , compareHead , nil
105
+ }
106
+
107
+ func (b branchCompare ) getAncestorsOf (baseHead middleware.Commit , compareHead middleware.Commit ) (map [string ]middleware.Commit , map [string ]middleware.Commit ) {
108
+ baseBranchMap := getParentCommitsOf (baseHead )
109
+ compareBranchMap := getParentCommitsOf (compareHead )
110
+
111
+ return baseBranchMap , compareBranchMap
74
112
}
75
113
76
114
// Organizing differing commits based on date
77
- func generateCommitMaps (filteredCommits []model.GitCommits ) map [string ][]* model.GitCommits {
115
+ func generateCommitMap (filteredCommits []model.GitCommits ) map [string ][]* model.GitCommits {
78
116
var commitMap = make (map [string ][]* model.GitCommits )
79
117
var commitHashMap = make (map [string ]bool )
80
118
@@ -83,7 +121,7 @@ func generateCommitMaps(filteredCommits []model.GitCommits) map[string][]*model.
83
121
84
122
j := i
85
123
for j < len (filteredCommits ) {
86
- if shouldBreakLoop (selectedDate , filteredCommits , j , commitHashMap ) {
124
+ if isCommitDateNotTheSelectedDate (selectedDate , filteredCommits , j ) && isCommitHashAlreadyInTheList ( commitHashMap , filteredCommits , j ) {
87
125
break
88
126
}
89
127
@@ -103,19 +141,23 @@ func generateCommitMaps(filteredCommits []model.GitCommits) map[string][]*model.
103
141
return commitMap
104
142
}
105
143
106
- func shouldBreakLoop (selectedDate string , filteredCommits []model.GitCommits , iterator int , commitHashMap map [ string ] bool ) bool {
144
+ func isCommitDateNotTheSelectedDate (selectedDate string , filteredCommits []model.GitCommits , iterator int ) bool {
107
145
if selectedDate != * filteredCommits [iterator ].CommitTime {
108
146
return true
109
147
}
110
148
149
+ return false
150
+ }
151
+
152
+ func isCommitHashAlreadyInTheList (commitHashMap map [string ]bool , filteredCommits []model.GitCommits , iterator int ) bool {
111
153
if len (commitHashMap ) > 0 && commitHashMap [* filteredCommits [iterator ].Hash ] {
112
154
return true
113
155
}
114
156
115
157
return false
116
158
}
117
159
118
- func filterDifferingCommits (compareBranchMap map [string ]* git2go .Commit , baseBranchMap map [string ]* git2go .Commit ) []model.GitCommits {
160
+ func filterDifferingCommits (compareBranchMap map [string ]middleware .Commit , baseBranchMap map [string ]middleware .Commit ) []model.GitCommits {
119
161
var commits []model.GitCommits
120
162
for commitHash , commit := range compareBranchMap {
121
163
if baseBranchMap [commitHash ] == nil {
@@ -135,33 +177,32 @@ func filterDifferingCommits(compareBranchMap map[string]*git2go.Commit, baseBran
135
177
return commits
136
178
}
137
179
138
- func getParentCommits (head * git2go .Commit ) map [string ]* git2go .Commit {
139
- var next * git2go .Commit
140
- commitMap := make (map [string ]* git2go .Commit )
180
+ func getParentCommitsOf (head middleware .Commit ) map [string ]middleware .Commit {
181
+ var next middleware .Commit
182
+ commitMap := make (map [string ]middleware .Commit )
141
183
142
184
if head .ParentCount () == 0 {
143
185
return commitMap
144
186
}
145
187
146
188
next = head .Parent (0 )
147
189
for next != nil {
190
+ fmt .Println ("Next : " , next )
148
191
commitMap [next .Id ().String ()] = next
149
192
next = next .Parent (0 )
150
193
}
151
194
152
195
return commitMap
153
196
}
154
197
155
- func sortCommitsBasedOnDate (commitMap map [string ][]* model.GitCommits , diffCommits []* model.BranchCompareResults ) []* model.BranchCompareResults {
156
- // Sorting commits in reverse chronological order of date
198
+ func sortCommitsInDescendingOrderOfDate (commitMap map [string ][]* model.GitCommits , diffCommits []* model.BranchCompareResults ) []* model.BranchCompareResults {
157
199
var keys []string
158
200
for k := range commitMap {
159
201
keys = append (keys , k )
160
202
}
161
203
sort .Strings (keys )
162
204
sort .Sort (sort .Reverse (sort .StringSlice (keys )))
163
205
164
- // Extracting differing commits to the resultant model
165
206
for _ , date := range keys {
166
207
diffCommits = append (diffCommits , & model.BranchCompareResults {
167
208
Date : date ,
@@ -171,10 +212,9 @@ func sortCommitsBasedOnDate(commitMap map[string][]*model.GitCommits, diffCommit
171
212
return diffCommits
172
213
}
173
214
174
- func NewBranchCompare (repo * git2go .Repository , baseBranch string , diffBranch string ) Compare {
215
+ func NewBranchCompare (repo middleware .Repository , branchValidator validator. ValidatorWithStringFields ) Compare {
175
216
return branchCompare {
176
- repo : repo ,
177
- baseBranch : baseBranch ,
178
- diffBranch : diffBranch ,
217
+ repo : repo ,
218
+ branchValidator : branchValidator ,
179
219
}
180
220
}
0 commit comments