55package git
66
77import (
8+ "fmt"
9+ "path"
10+ "path/filepath"
811 "sort"
912 "strconv"
1013 "strings"
@@ -84,10 +87,10 @@ var sorter = []func(t1, t2 *TreeEntry) bool{
8487 },
8588}
8689
87- func (bs Entries ) Len () int { return len (bs ) }
88- func (bs Entries ) Swap (i , j int ) { bs [i ], bs [j ] = bs [j ], bs [i ] }
89- func (bs Entries ) Less (i , j int ) bool {
90- t1 , t2 := bs [i ], bs [j ]
90+ func (tes Entries ) Len () int { return len (tes ) }
91+ func (tes Entries ) Swap (i , j int ) { tes [i ], tes [j ] = tes [j ], tes [i ] }
92+ func (tes Entries ) Less (i , j int ) bool {
93+ t1 , t2 := tes [i ], tes [j ]
9194 var k int
9295 for k = 0 ; k < len (sorter )- 1 ; k ++ {
9396 sort := sorter [k ]
@@ -101,6 +104,83 @@ func (bs Entries) Less(i, j int) bool {
101104 return sorter [k ](t1 , t2 )
102105}
103106
104- func (bs Entries ) Sort () {
105- sort .Sort (bs )
107+ func (tes Entries ) Sort () {
108+ sort .Sort (tes )
109+ }
110+
111+ type commitInfo struct {
112+ id string
113+ infos []interface {}
114+ err error
115+ }
116+
117+ // GetCommitsInfo takes advantages of concurrey to speed up getting information
118+ // of all commits that are corresponding to these entries.
119+ // TODO: limit max goroutines at same time
120+ func (tes Entries ) GetCommitsInfo (commit * Commit , treePath string ) ([][]interface {}, error ) {
121+ if len (tes ) == 0 {
122+ return nil , nil
123+ }
124+
125+ revChan := make (chan commitInfo , 10 )
126+
127+ infoMap := make (map [string ][]interface {}, len (tes ))
128+ for i := range tes {
129+ if tes [i ].Type != OBJECT_COMMIT {
130+ go func (i int ) {
131+ cinfo := commitInfo {id : tes [i ].ID .String ()}
132+ c , err := commit .GetCommitByPath (filepath .Join (treePath , tes [i ].Name ()))
133+ if err != nil {
134+ cinfo .err = fmt .Errorf ("GetCommitByPath (%s/%s): %v" , treePath , tes [i ].Name (), err )
135+ } else {
136+ cinfo .infos = []interface {}{tes [i ], c }
137+ }
138+ revChan <- cinfo
139+ }(i )
140+ continue
141+ }
142+
143+ // Handle submodule
144+ go func (i int ) {
145+ cinfo := commitInfo {id : tes [i ].ID .String ()}
146+ sm , err := commit .GetSubModule (path .Join (treePath , tes [i ].Name ()))
147+ if err != nil {
148+ cinfo .err = fmt .Errorf ("GetSubModule (%s/%s): %v" , treePath , tes [i ].Name (), err )
149+ revChan <- cinfo
150+ return
151+ }
152+
153+ smUrl := ""
154+ if sm != nil {
155+ smUrl = sm .Url
156+ }
157+
158+ c , err := commit .GetCommitByPath (filepath .Join (treePath , tes [i ].Name ()))
159+ if err != nil {
160+ cinfo .err = fmt .Errorf ("GetCommitByPath (%s/%s): %v" , treePath , tes [i ].Name (), err )
161+ } else {
162+ cinfo .infos = []interface {}{tes [i ], NewSubModuleFile (c , smUrl , tes [i ].ID .String ())}
163+ }
164+ revChan <- cinfo
165+ }(i )
166+ }
167+
168+ i := 0
169+ for info := range revChan {
170+ if info .err != nil {
171+ return nil , info .err
172+ }
173+
174+ infoMap [info .id ] = info .infos
175+ i ++
176+ if i == len (tes ) {
177+ break
178+ }
179+ }
180+
181+ commitsInfo := make ([][]interface {}, len (tes ))
182+ for i := 0 ; i < len (tes ); i ++ {
183+ commitsInfo [i ] = infoMap [tes [i ].ID .String ()]
184+ }
185+ return commitsInfo , nil
106186}
0 commit comments