JGitFS provides access to Git branches/tags/commits like they are separate directories via a Linux FUSE userland filesystem
Java
Switch branches/tags
Clone or download
Latest commit d8321b6 Nov 29, 2017

README.md

Build Status Gradle Status

JGitFS provides access to Git branches/tags/commits like if they would be separate directories via a FUSE userland filesystem.

Getting started

Grab it

git clone --recursive git://github.com/centic9/JGitFS

Note: The "--recursive" is necessary to clone necessary submodules as well! If you did a normal clone, you can do git submodule update --init --recursive to fetch the submodule.

Build it and create the distribution files

cd JGitFS
./gradlew installDist

Run it

build/install/JGitFS/bin/JGitFS <path-to-git> <location-for-filesystem>

I.e. to get a view of the Git repository located at /opt/project mounted at /mnt/git, do

build/install/JGitFS/bin/JGitFS /opt/project /mnt/git

The longer stuff

Details

If you have a Git repository at /opt/project, then after calling

build/install/JGitFS/bin/JGitFS /opt/project /mnt/git

you will have a directory structure under /mnt/git which shows sub-directories branches, tags and commit which provide access to previous versions of your project. This is useful if you want to look at more than one version at the same time, e.g. to use a more powerful compare-tool like Beyond Compare to visualize the differences between two branches.

This allows to use a Git repository a bit like IBM/Rational ClearCase dynamic views, because you can directly access past points in the history of your project without having to switch to them.

Note: Access is strictly read-only, no writing of new commits on branches is possible. Branches and Tags are actually implemented as symbolic links to the respective commit. The commit-directory uses the same two-byte directory-substructure like Git uses in .git/objects.

Change it

Implementation should be straightforward, the class JGitFS implements the commandline handling, JGitFilesystem implements the filesystem interfaces that are neede for simple read-only access as well as some caching, JGitHelper encapsulates access to Git, GitUtils are local utils for computing commits, ...

Create matching Eclipse project files

./gradlew eclipse

Run unit tests

./gradlew test jacocoTestReport

The idea

I was looking for a way to visualize branches of my Git repositories as separate directories so I could easier compare different versions. There are ways to do a 2nd checkout from an existing repository to have two working copies, but this is cumbersome.

I did find a number of projects, developed in native, python or caml, but they were either dormant or not fully working for some reason.

As part of some further research I stumbled upon the great fuse-jna library which makes building a FUSE userland filesystem in 100% pure Java very easy and straightforward by making use of JNA instead of using JNI compiled code. This means no native code, no compile troubles, no nothing but full access to the FUSE functionality! Amazing!

On the Git side I had heard about JGit and wanted to give it a try anyway, using it was a bit of a rough ride and in order to get to grips with it I ended up putting together a collection of code-snippets at jgit-cookbook, but in the end pure-Java access to Git repositories worked fine as well.

Finally after some performance tuning sessions and adding some caching at the right spots I was also satisfied with the performance, naturally there is a bit of overhead but overall I am able to work with fairly large repositories without large delays, only some more CPU is used because of all the compression/format reading in JGit and this doesn't seem to be a big concern with fairly up-to-date hardware.

Todos

Compatibility

Because it is based on fuse-jna, JGitFS should work with:

  • OS X with MacFUSE/fuse4x/OSXFUSE on Intel architectures
  • Linux with FUSE on Intel and PowerPC architectures
  • FreeBSD with FUSE on Intel architectures

Related projects

Licensing