@@ -7,7 +7,6 @@ package git
77import (
88 "bytes"
99 "container/list"
10- "fmt"
1110 "strconv"
1211 "strings"
1312)
@@ -272,71 +271,60 @@ func (repo *Repository) CommitsCountBetween(start, end string) (int64, error) {
272271}
273272
274273// 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 ())
279280 }
280281
281- commit , err := repo . getCommit ( id )
282+ stdout , err := cmd . RunInDirBytes ( repo . Path )
282283 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
313285 }
314286
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
318290 }
319291
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 )
322296 if err != nil {
323- return err
297+ return nil , err
324298 }
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
328302 }
303+
304+ commits .PushBack (commit )
329305 }
330306
331- return nil
307+ return commits , nil
332308}
333309
334310func (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 )
337312}
338313
339314func (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
342330}
0 commit comments