@@ -6,6 +6,7 @@ package git
66
77import (
88 "bytes"
9+ "context"
910 "io"
1011 "os"
1112 "strconv"
@@ -304,23 +305,47 @@ func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (in
304305
305306// CommitsBetween returns a list that contains commits between [before, last).
306307// If before is detached (removed by reset + push) it is not included.
307- func (repo * Repository ) CommitsBetween (last , before * Commit ) ([]* Commit , error ) {
308+ func (repo * Repository ) CommitsBetween (lastCommitID , beforeCommitID string ) ([]* Commit , error ) {
309+ commitIDs , err := CommitIDsBetween (repo .Ctx , repo .Path , beforeCommitID , lastCommitID )
310+ if err != nil {
311+ return nil , err
312+ }
313+
314+ commits := make ([]* Commit , 0 , len (commitIDs ))
315+ for _ , commitID := range commitIDs {
316+ commit , err := repo .GetCommit (commitID )
317+ if err != nil {
318+ return nil , err
319+ }
320+ commits = append (commits , commit )
321+ }
322+ return commits , nil
323+ }
324+
325+ func CommitIDsBetween (ctx context.Context , repoPath , beforeCommitID , afterCommitID string ) ([]string , error ) {
308326 var stdout []byte
309327 var err error
310- if before == nil {
311- stdout , _ , err = NewCommand ("rev-list" ).AddDynamicArguments (last . ID . String ()) .RunStdBytes (repo . Ctx , & RunOpts {Dir : repo . Path })
328+ if beforeCommitID == "" {
329+ stdout , _ , err = NewCommand ("rev-list" ).AddDynamicArguments (afterCommitID ) .RunStdBytes (ctx , & RunOpts {Dir : repoPath })
312330 } else {
313- stdout , _ , err = NewCommand ("rev-list" ).AddDynamicArguments (before . ID . String () + ".." + last . ID . String ()) .RunStdBytes (repo . Ctx , & RunOpts {Dir : repo . Path })
331+ stdout , _ , err = NewCommand ("rev-list" ).AddDynamicArguments (beforeCommitID + ".." + afterCommitID ) .RunStdBytes (ctx , & RunOpts {Dir : repoPath })
314332 if err != nil && strings .Contains (err .Error (), "no merge base" ) {
315333 // future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
316334 // previously it would return the results of git rev-list before last so let's try that...
317- stdout , _ , err = NewCommand ("rev-list" ).AddDynamicArguments (before . ID . String (), last . ID . String ()) .RunStdBytes (repo . Ctx , & RunOpts {Dir : repo . Path })
335+ stdout , _ , err = NewCommand ("rev-list" ).AddDynamicArguments (beforeCommitID , afterCommitID ) .RunStdBytes (ctx , & RunOpts {Dir : repoPath })
318336 }
319337 }
320338 if err != nil {
321339 return nil , err
322340 }
323- return repo .parsePrettyFormatLogToList (bytes .TrimSpace (stdout ))
341+
342+ commitIDs := make ([]string , 0 , 10 )
343+ for commitID := range bytes .SplitSeq (stdout , []byte {'\n' }) {
344+ if len (commitID ) > 0 {
345+ commitIDs = append (commitIDs , string (commitID ))
346+ }
347+ }
348+ return commitIDs , nil
324349}
325350
326351// CommitsBetweenLimit returns a list that contains at most limit commits skipping the first skip commits between [before, last)
@@ -375,18 +400,17 @@ func (repo *Repository) CommitsBetweenNotBase(last, before *Commit, baseBranch s
375400
376401// CommitsBetweenIDs return commits between twoe commits
377402func (repo * Repository ) CommitsBetweenIDs (last , before string ) ([]* Commit , error ) {
378- lastCommit , err := repo .GetCommit (last )
403+ _ , err := repo .GetCommit (last )
379404 if err != nil {
380405 return nil , err
381406 }
382- if before == "" {
383- return repo .CommitsBetween (lastCommit , nil )
384- }
385- beforeCommit , err := repo .GetCommit (before )
386- if err != nil {
387- return nil , err
407+ if before != "" {
408+ _ , err := repo .GetCommit (before )
409+ if err != nil {
410+ return nil , err
411+ }
388412 }
389- return repo .CommitsBetween (lastCommit , beforeCommit )
413+ return repo .CommitsBetween (last , before )
390414}
391415
392416// CommitsCountBetween return numbers of commits between two commits
0 commit comments