Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/centic9/jgitfs

JGitFS provides access to Git branches/tags/commits like they are separate directories via a Linux FUSE userland filesystem
https://github.com/centic9/jgitfs

branches fuse-jna git java jgit linux-fuse userland-filesystem

Last synced: 19 days ago
JSON representation

JGitFS provides access to Git branches/tags/commits like they are separate directories via a Linux FUSE userland filesystem

Awesome Lists containing this project

README

        

[![Build Status](https://github.com/centic9/JGitFS/actions/workflows/gradle-build.yml/badge.svg)](https://github.com/centic9/JGitFS/actions)
[![Gradle Status](https://gradleupdate.appspot.com/centic9/JGitFS/status.svg?branch=master)](https://gradleupdate.appspot.com/centic9/JGitFS/status)
[![Tag](https://img.shields.io/github/tag/centic9/JGitFS.svg)](https://github.com/centic9/JGitFS/tags)

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

## Getting started

#### Required packages

Make sure to have Java 8+ and libfuse2 installed.

On Debian/Ubuntu based systems you can run:

sudo apt-get install openjdk-11-jdk libfuse2

Note: [fuse-jna] is based on libfuse2, so having libfuse3 installed will not be sufficient.

#### 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

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

## Support this project

If you find this tool useful and would like to support it, you can [Sponsor the author](https://github.com/sponsors/centic9)

## 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 needed for simple read-only access as well as some caching, `JGitHelper` encapsulates access to Git, `GitUtils` are local utils for computing commits, ...

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][Linux-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][Linux-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.

#### Load testing

Some scripts that might be useful for reading lots of data from the fuse filesystems:

while true;do find /fs/ > /dev/null;done

find /fs/ -type f -exec cat "{}" > /dev/null \;

#### Todos

* Only commits reachable via refs or tags are listed currently as I could not yet get JGit to return me a list of all commits, so commits which still exist, but are unreferenced currently are not visible
* Stashes are not listed yet
* We could show the state of the index as separate folder-hierarchy via DirCache
* Is there a way to include the current workspace via WorkingTreeIterator?
* JGit also supports Notes, how could we show these?
* Sometimes the history of a single file is needed, what about having dirs perfile/branch, perfile/commit, perfile/tag, ...
* Would be nice to get this on Windows via cygwin as well
** It seems there is https://github.com/openunix/fuse-cygwin/, but could not get it to compile yet.
** Another promising option is https://github.com/dokan-dev/dokany and http://www.secfs.net/winfsp/ https://github.com/billziss-gh/winfsp
** Lately there was more discussion around this at https://cygwin.com/ml/cygwin/2016-06/threads.html#00250, http://cygwin.1069669.n5.nabble.com/ITP-FUSE-2-8-td128282.html and https://cygwin.com/ml/cygwin/2016-06/msg00253.html
** Some more links are at https://news.ycombinator.com/item?id=11930888

#### Compatibility

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

* OS X with [MacFUSE]/[fuse4x]/[OSXFUSE] on Intel architectures
* Linux with [FUSE][Linux-Fuse] on Intel and PowerPC architectures
* FreeBSD with [FUSE][FreeBSD-Fuse] on Intel architectures

#### Related projects

* https://github.com/g2p/git-fs
* https://bitbucket.org/billcroberts/gitfs
* https://github.com/akiellor/githubfs
* https://github.com/centic9/jgit-cookbook

#### Licensing
* JGitFS is licensed under the [BSD 2-Clause License].
* [fuse-jna] is licensed under the [BSD 2-Clause License].
* [JNA] is licensed under the [LGPL v2.1].
* [JGit] is licensed under the [EDL].
* The Apache Commons `io` and `lang` libraries are licensed under the [Apache 2.0 License]

[fuse-jna]: https://github.com/EtiennePerot/fuse-jna
[JNA]: https://github.com/twall/jna
[JGit]: http://eclipse.org/jgit/
[jgit-cookbook]: https://github.com/centic9/jgit-cookbook
[MacFUSE]: http://code.google.com/p/macfuse/
[fuse4x]: http://fuse4x.org/
[OSXFUSE]: http://osxfuse.github.com/
[Linux-FUSE]: http://fuse.sourceforge.net/
[FreeBSD-FUSE]: http://wiki.freebsd.org/FuseFilesystem
[BSD 2-Clause License]: https://www.opensource.org/licenses/bsd-license.php
[LGPL v2.1]: https://www.opensource.org/licenses/lgpl-2.1.php
[EDL]: http://www.eclipse.org/org/documents/edl-v10.php
[Apache 2.0 License]: http://www.apache.org/licenses/LICENSE-2.0