17

I'd like to use JGit to display a list of all files and folders for the head revision. I'm able to list all files using TreeWalk, but this does not list folders.

Here is what I have so far:

public class MainClass {

    public static void main(String[] args) throws IOException {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        Repository repository = builder
                .setGitDir(new File("C:\\temp\\git\\.git")).readEnvironment()
                .findGitDir().build();

        listRepositoryContents(repository);

        repository.close();
    }

    private static void listRepositoryContents(Repository repository) throws IOException {
        Ref head = repository.getRef("HEAD");

        // a RevWalk allows to walk over commits based on some filtering that is defined
        RevWalk walk = new RevWalk(repository);

        RevCommit commit = walk.parseCommit(head.getObjectId());
        RevTree tree = commit.getTree();
        System.out.println("Having tree: " + tree);

        // now use a TreeWalk to iterate over all files in the Tree recursively
        // you can set Filters to narrow down the results if needed
        TreeWalk treeWalk = new TreeWalk(repository);
        treeWalk.addTree(tree);
        treeWalk.setRecursive(true);
        while (treeWalk.next()) {
            System.out.println("found: " + treeWalk.getPathString());
        }
    }
}
Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79
Gaurav Sharma
  • 4,032
  • 14
  • 46
  • 72

2 Answers2

25

You need to set recursive to false (see documentation) and then walk like this:

TreeWalk treeWalk = new TreeWalk(repository);
treeWalk.addTree(tree);
treeWalk.setRecursive(false);
while (treeWalk.next()) {
    if (treeWalk.isSubtree()) {
        System.out.println("dir: " + treeWalk.getPathString());
        treeWalk.enterSubtree();
    } else {
        System.out.println("file: " + treeWalk.getPathString());
    }
}
robinst
  • 30,027
  • 10
  • 102
  • 108
  • 1
    Yep, I use that in some projects already, the underlying FileMode attribute of tree-nodes also allows to detect symlinks, see also the jgit-cookbook at https://github.com/centic9/jgit-cookbook/blob/master/src/main/java/org/dstadler/jgit/api/GetFileAttributes.java which shows this in a ready-to-run example. – centic Nov 13 '13 at 12:25
  • 1
    That works...partially. Rüdiger Herrmann is right in that empty directories will not be listed. – Gaurav Sharma Nov 13 '13 at 15:15
5

Git does not track directories of their own. You can only derive non-empty directory names from the path string you get from the TreeWalk.

See the Git FAQ (search for 'empty directory') for a detailed explanation and possible workarounds.

Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79