@@ -188,14 +188,10 @@ func (r *Repository) LogMsg(ctx context.Context, ref, path string) (string, erro
188188
189189// Subject returns commit subject of given commit hash
190190func (r * Repository ) Subject (ctx context.Context , hash string ) (string , error ) {
191- if err := r .ObjectExists (ctx , hash ); err != nil {
192- return "" , err
193- }
194-
195191 r .lock .RLock ()
196192 defer r .lock .RUnlock ()
197193
198- args := []string {"show" , `--no-patch` , `--format='%s' ` , hash }
194+ args := []string {"show" , `--no-patch` , `--format=%s ` , hash }
199195 msg , err := runGitCommand (ctx , r .log , r .envs , r .dir , args ... )
200196 if err != nil {
201197 return "" , err
@@ -205,19 +201,80 @@ func (r *Repository) Subject(ctx context.Context, hash string) (string, error) {
205201
206202// ChangedFiles returns path of the changed files for given commit hash
207203func (r * Repository ) ChangedFiles (ctx context.Context , hash string ) ([]string , error ) {
208- if err := r .ObjectExists (ctx , hash ); err != nil {
204+ r .lock .RLock ()
205+ defer r .lock .RUnlock ()
206+
207+ args := []string {"show" , `--name-only` , `--pretty=format:` , hash }
208+ msg , err := runGitCommand (ctx , r .log , r .envs , r .dir , args ... )
209+ if err != nil {
209210 return nil , err
210211 }
212+ return strings .Split (msg , "\n " ), nil
213+ }
214+
215+ type CommitInfo struct {
216+ Hash string
217+ ChangedFiles []string
218+ }
219+
220+ // MergeCommits lists commits from the mergeCommitHash but not from the first
221+ // parent of mergeCommitHash (mergeCommitHash^) in chronological order. (latest to oldest)
222+ func (r * Repository ) MergeCommits (ctx context.Context , mergeCommitHash string ) ([]CommitInfo , error ) {
223+ return r .ListCommitsWithChangedFiles (ctx , mergeCommitHash + "^" , mergeCommitHash )
224+ }
225+
226+ // BranchCommits lists commits from the tip of the branch but not from the HEAD
227+ // of the repository in chronological order. (latest to oldest)
228+ func (r * Repository ) BranchCommits (ctx context.Context , branch string ) ([]CommitInfo , error ) {
229+ return r .ListCommitsWithChangedFiles (ctx , "HEAD" , branch )
230+ }
211231
232+ // ListCommitsWithChangedFiles returns path of the changed files for given commit hash
233+ // list all the commits and files which are reachable from 'ref2', but not from 'ref1'
234+ // The output is given in reverse chronological order.
235+ func (r * Repository ) ListCommitsWithChangedFiles (ctx context.Context , ref1 , ref2 string ) ([]CommitInfo , error ) {
212236 r .lock .RLock ()
213237 defer r .lock .RUnlock ()
214238
215- args := []string {"show " , `--name-only` , `--pretty=format:` , hash }
239+ args := []string {"log " , `--name-only` , `--pretty=format:%H ` , ref1 + ".." + ref2 }
216240 msg , err := runGitCommand (ctx , r .log , r .envs , r .dir , args ... )
217241 if err != nil {
218242 return nil , err
219243 }
220- return strings .Split (msg , "\n " ), nil
244+ return ParseCommitWithChangedFilesList (msg ), nil
245+ }
246+
247+ // ParseCommitWithChangedFilesList will parse following output of 'show/log'
248+ // command with `--name-only`, `--pretty=format:%H` flags
249+ //
250+ // 72ea9c9de6963e97ac472d9ea996e384c6923cca
251+ //
252+ // 80e11d114dd3aa135c18573402a8e688599c69e0
253+ // one/readme.yaml
254+ // one/hello.tf
255+ // two/readme.yaml
256+ func ParseCommitWithChangedFilesList (output string ) []CommitInfo {
257+ commitCount := 0
258+ Commits := []CommitInfo {}
259+
260+ for _ , line := range strings .Split (output , "\n " ) {
261+ line = strings .TrimSpace (line )
262+ if line == "" {
263+ continue
264+ }
265+ if IsFullCommitHash (line ) {
266+ Commits = append (Commits , CommitInfo {Hash : line })
267+ commitCount += 1
268+ continue
269+ }
270+ // if line is not commit or empty then its assumed to be changed file name
271+ // also this file change belongs to the last commit
272+ if commitCount > 0 {
273+ Commits [commitCount - 1 ].ChangedFiles = append (Commits [commitCount - 1 ].ChangedFiles , line )
274+ }
275+ }
276+
277+ return Commits
221278}
222279
223280// ObjectExists returns error is given object is not valid or if it doesn't exists
0 commit comments