@@ -7,7 +7,6 @@ package git
7
7
import (
8
8
"bytes"
9
9
"container/list"
10
- "fmt"
11
10
"strconv"
12
11
"strings"
13
12
)
@@ -272,71 +271,60 @@ func (repo *Repository) CommitsCountBetween(start, end string) (int64, error) {
272
271
}
273
272
274
273
// commitsBefore the limit is depth, not total number of returned commits.
275
- func (repo * Repository ) commitsBefore (l * list.List , parent * list.Element , id SHA1 , current , limit int ) error {
276
- // Reach the limit
277
- if limit > 0 && current > limit {
278
- return nil
274
+ func (repo * Repository ) commitsBefore (id SHA1 , limit int ) (* list.List , error ) {
275
+ cmd := NewCommand ("log" )
276
+ if limit > 0 {
277
+ cmd .AddArguments ("-" + strconv .Itoa (limit ), prettyLogFormat , id .String ())
278
+ } else {
279
+ cmd .AddArguments (prettyLogFormat , id .String ())
279
280
}
280
281
281
- commit , err := repo . getCommit ( id )
282
+ stdout , err := cmd . RunInDirBytes ( repo . Path )
282
283
if err != nil {
283
- return fmt .Errorf ("getCommit: %v" , err )
284
- }
285
-
286
- var e * list.Element
287
- if parent == nil {
288
- e = l .PushBack (commit )
289
- } else {
290
- var in = parent
291
- for {
292
- if in == nil {
293
- break
294
- } else if in .Value .(* Commit ).ID .Equal (commit .ID ) {
295
- return nil
296
- } else if in .Next () == nil {
297
- break
298
- }
299
-
300
- if in .Value .(* Commit ).Committer .When .Equal (commit .Committer .When ) {
301
- break
302
- }
303
-
304
- if in .Value .(* Commit ).Committer .When .After (commit .Committer .When ) &&
305
- in .Next ().Value .(* Commit ).Committer .When .Before (commit .Committer .When ) {
306
- break
307
- }
308
-
309
- in = in .Next ()
310
- }
311
-
312
- e = l .InsertAfter (commit , in )
284
+ return nil , err
313
285
}
314
286
315
- pr := parent
316
- if commit . ParentCount () > 1 {
317
- pr = e
287
+ formattedLog , err := repo . parsePrettyFormatLogToList ( bytes . TrimSpace ( stdout ))
288
+ if err != nil {
289
+ return nil , err
318
290
}
319
291
320
- for i := 0 ; i < commit .ParentCount (); i ++ {
321
- id , err := commit .ParentID (i )
292
+ commits := list .New ()
293
+ for logEntry := formattedLog .Front (); logEntry != nil ; logEntry = logEntry .Next () {
294
+ commit := logEntry .Value .(* Commit )
295
+ branches , err := repo .getBranches (commit , 2 )
322
296
if err != nil {
323
- return err
297
+ return nil , err
324
298
}
325
- err = repo . commitsBefore ( l , pr , id , current + 1 , limit )
326
- if err != nil {
327
- return err
299
+
300
+ if len ( branches ) > 1 {
301
+ break
328
302
}
303
+
304
+ commits .PushBack (commit )
329
305
}
330
306
331
- return nil
307
+ return commits , nil
332
308
}
333
309
334
310
func (repo * Repository ) getCommitsBefore (id SHA1 ) (* list.List , error ) {
335
- l := list .New ()
336
- return l , repo .commitsBefore (l , nil , id , 1 , 0 )
311
+ return repo .commitsBefore (id , 0 )
337
312
}
338
313
339
314
func (repo * Repository ) getCommitsBeforeLimit (id SHA1 , num int ) (* list.List , error ) {
340
- l := list .New ()
341
- return l , repo .commitsBefore (l , nil , id , 1 , num )
315
+ return repo .commitsBefore (id , num )
316
+ }
317
+
318
+ func (repo * Repository ) getBranches (commit * Commit , limit int ) ([]string , error ) {
319
+ stdout , err := NewCommand ("for-each-ref" , "--count=" + strconv .Itoa (limit ), "--format=%(refname)" , "--contains" , commit .ID .String (), BranchPrefix ).RunInDir (repo .Path )
320
+ if err != nil {
321
+ return nil , err
322
+ }
323
+
324
+ refs := strings .Split (stdout , "\n " )
325
+ branches := make ([]string , len (refs )- 1 )
326
+ for i , ref := range refs [:len (refs )- 1 ] {
327
+ branches [i ] = strings .TrimPrefix (ref , BranchPrefix )
328
+ }
329
+ return branches , nil
342
330
}
0 commit comments