Search code examples
jgitgrgit

grgit log to get equivalent of git log --name-status --reverse --pretty=format:'%H'


How can I use grgit to obtain changed paths for a commit?

In the code below I get a grgit Commit object which has metadata about the commit but not the list of files modified. I want to get the equivalent of git log --name-status --reverse --pretty=format:'%H'

Any ideas on transforming a commit sha into a grgit or jgit object with details about path and modification type?

    def commits =  grgit.log {
        range('sha', 'HEAD')
    }
    commits.each { def change ->
        def description = grgit.describe { commit = change }
        println description
        println change
    }

Solution

  • grgit is fine for what it does and it also brings with it jgit + provides access to that lower layer

    So, we can do this

    Get a list of RevCommit Object for a range

    import org.eclipse.jgit.api.Git
    import org.eclipse.jgit.treewalk.TreeWalk
    import org.eclipse.jgit.diff.DiffFormatter
    import org.eclipse.jgit.treewalk.CanonicalTreeParser
    import org.eclipse.jgit.diff.DiffEntry
    import org.eclipse.jgit.treewalk.filter.PathFilter
    
    def getCommits(def early, def later='HEAD') {
      Git git = grgit.repository.jgit
      def earliest =  git.repository.resolve(early)
      def latest = git.repository.resolve(later)
    
      return git.log()
            .addRange(earliest, latest)
            .call()
    }
    

    Get diff info per commit

    for (def commit in getCommits(earliestCommitId, latestCommitId)) {
        for (DiffEntry diffEntry in diffCommitWithParent(commit, pathFilter)) {
             println diffEntry // you'd want to do something more useful here
        }
    }
    
    def diffCommitWithParent(def commit, def pathFilter) {
      Git git = grgit.repository.jgit
      def previousTree = commit.getParentCount() > 0 ? commit.getParent(0).getTree() : null
      def currentTree = commit.getTree()
      def reader = git.repository.newObjectReader()
      def treeParserPrevious = new CanonicalTreeParser(null, reader, previousTree)
      def treeParserCurrent = new CanonicalTreeParser(null, reader, currentTree)
      return git.diff()
            .setOldTree(treeParserPrevious)
            .setNewTree(treeParserCurrent)
            .setPathFilter(new PathFilter(pathFilter))
            .call()
    }