Looping over commits for a file with jGit

前端 未结 4 1482
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-28 10:12

I\'ve managed to get to grips with the basics of jGit file in terms of connecting to a repos and adding, commiting, and even looping of the commit messages for the files.

4条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-28 10:52

    Here is how to find the changes of a commit based on all parent commits

            var tree = new TreeWalk(repository)
            tree.addTree(commit.getTree)
            commit.getParents foreach {
                parent => tree.addTree(parent.getTree)
            }
            tree.setFilter(TreeFilter.ANY_DIFF)
    

    (scala code)

    Note that TreeFilter.ANY_DIFF works for a single tree walker and will return all elements available in a root commit.

    You would then have to iterate over the tree to see if your file is in the given delta (this is quite easy).

        while (tree.next)
                if (tree.getDepth == cleanPath.size) {
                    // we are at the right level, do what you want
                } else {
                    if (tree.isSubtree &&
                        name == cleanPath(tree.getDepth)) {
                        tree.enterSubtree
                    }
                }
        }
    

    (cleanPath is the pure in repo path, split by '/')

    Now wrap that code into a RevWalk.next loop and you'll get the commits and files altered by the commit.

    You may want to use a different filter than ANY_DIFF, because ANY_DIFF is true if one tree differs. This is a bit counter-intuitive in case of a merge where the blob didn't change compared to all parent trees. So here is the core of an ALL_DIFF, that will only show elements that differ from all parent trees:

    override def include(walker: TreeWalk): Boolean = {
        val n = walker.getTreeCount();
        if (n == 1) {
            return true;
        }
        val m = walker.getRawMode(0)
        var i = 1
        while (i < n) {
            if (walker.getRawMode(i) == m && walker.idEqual(i, 0)) {
                return false
            }
            i += 1
        }
        true
    }
    

    (scala code, derived from AnyDiffFilter)

提交回复
热议问题