{"id":15346678,"url":"https://github.com/centic9/jgitfs","last_synced_at":"2025-08-18T13:18:49.209Z","repository":{"id":9109550,"uuid":"10891337","full_name":"centic9/JGitFS","owner":"centic9","description":"JGitFS provides access to Git branches/tags/commits as if they are separate directories. Implemeted via a Linux FUSE userland filesystem","archived":false,"fork":false,"pushed_at":"2025-07-31T20:18:37.000Z","size":4280,"stargazers_count":32,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-07-31T23:18:04.560Z","etag":null,"topics":["branches","fuse-jna","git","java","jgit","linux-fuse","userland-filesystem"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/centic9.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"centic9"}},"created_at":"2013-06-23T20:27:27.000Z","updated_at":"2025-07-31T20:18:41.000Z","dependencies_parsed_at":"2023-11-06T09:31:16.472Z","dependency_job_id":"41722271-96fd-4e9e-b38b-93026e34a2fd","html_url":"https://github.com/centic9/JGitFS","commit_stats":{"total_commits":317,"total_committers":6,"mean_commits":"52.833333333333336","dds":"0.056782334384858024","last_synced_commit":"2c0d69decf4e25928ade99bc9c1ada8164a82dc0"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/centic9/JGitFS","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/centic9%2FJGitFS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/centic9%2FJGitFS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/centic9%2FJGitFS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/centic9%2FJGitFS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/centic9","download_url":"https://codeload.github.com/centic9/JGitFS/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/centic9%2FJGitFS/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270998264,"owners_count":24682214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["branches","fuse-jna","git","java","jgit","linux-fuse","userland-filesystem"],"created_at":"2024-10-01T11:25:59.674Z","updated_at":"2025-08-18T13:18:49.198Z","avatar_url":"https://github.com/centic9.png","language":"Java","readme":"[![Build Status](https://github.com/centic9/JGitFS/actions/workflows/gradle-build.yml/badge.svg)](https://github.com/centic9/JGitFS/actions)\n[![Gradle Status](https://gradleupdate.appspot.com/centic9/JGitFS/status.svg?branch=master)](https://gradleupdate.appspot.com/centic9/JGitFS/status)\n[![Tag](https://img.shields.io/github/tag/centic9/JGitFS.svg)](https://github.com/centic9/JGitFS/tags)\n\nJGitFS provides access to Git branches/tags/commits as if they would be separate directories. Implemented via a [FUSE][Linux-Fuse] \nuserland filesystem. \n\n## Getting started\n\n#### Required packages\n\nMake sure to have Java 17+ and libfuse2 installed.\n\nOn Debian/Ubuntu based systems you can run:\n\n    sudo apt-get install openjdk-11-jdk libfuse2\n\nNote: [fuse-jna] is based on libfuse2, so having libfuse3 installed will not be sufficient.\n\n#### Grab it\n\n    git clone --recursive git://github.com/centic9/JGitFS\n\nNote: The \"--recursive\" is necessary to clone necessary submodules as well!\nIf you did a normal clone, you can do ``git submodule update --init --recursive`` to fetch the submodule.\n\n#### Build it and create the distribution files\n\n\tcd JGitFS\n\t./gradlew installDist\n\n#### Run it\n\n    build/install/JGitFS/bin/JGitFS \u003cpath-to-git\u003e \u003clocation-for-filesystem\u003e\n\nI.e. to get a view of the Git repository located at /opt/project mounted at /mnt/git, do\n \n    build/install/JGitFS/bin/JGitFS /opt/project /mnt/git\n\n## Support this project\n\nIf you find this tool useful and would like to support it, you can [Sponsor the author](https://github.com/sponsors/centic9)\n\n## The longer stuff\n\n#### Details\n\nIf you have a Git repository at /opt/project, then after calling \n \n    build/install/JGitFS/bin/JGitFS /opt/project /mnt/git\n\nyou 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.\n\nThis 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.  \n\nNote: 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.\n\n#### Change it\n\nImplementation 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, ...\n\nRun unit tests\n\n\t./gradlew test jacocoTestReport\n\n#### The idea\n\nI 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. \n\nI did find a number of projects, developed in native, python or caml, but they were either dormant or not fully working for some reason. \n\nAs 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! \n\nOn 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.\n\nFinally 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.\n\n#### Load testing\n\nSome scripts that might be useful for reading lots of data from the fuse filesystems:\n\n    while true;do find /fs/ \u003e /dev/null;done\n\n    find /fs/ -type f -exec cat \"{}\" \u003e /dev/null \\;\n\n#### Todos\n\n* 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\n* Stashes are not listed yet\n* We could show the state of the index as separate folder-hierarchy via DirCache\n* Is there a way to include the current workspace via WorkingTreeIterator?\n* JGit also supports Notes, how could we show these?\t\n* Sometimes the history of a single file is needed, what about having dirs perfile/branch, perfile/commit, perfile/tag, ...\n* Would be nice to get this on Windows via cygwin as well\n** It seems there is https://github.com/openunix/fuse-cygwin/, but could not get it to compile yet.\n** Another promising option is https://github.com/dokan-dev/dokany and http://www.secfs.net/winfsp/ https://github.com/billziss-gh/winfsp\n** 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\n** Some more links are at https://news.ycombinator.com/item?id=11930888\n\n#### Compatibility\n\nBecause it is based on [fuse-jna], JGitFS should work with:\n\n* OS X with [MacFUSE]/[fuse4x]/[OSXFUSE] on Intel architectures\n* Linux with [FUSE][Linux-Fuse] on Intel and PowerPC architectures\n* FreeBSD with [FUSE][FreeBSD-Fuse] on Intel architectures\n\n#### Related projects\n\n* https://github.com/g2p/git-fs\n* https://bitbucket.org/billcroberts/gitfs\n* https://github.com/akiellor/githubfs\n* https://github.com/centic9/jgit-cookbook\n\n#### Licensing\n* JGitFS is licensed under the [BSD 2-Clause License].\n* [fuse-jna] is licensed under the [BSD 2-Clause License].\n* [JNA] is licensed under the [LGPL v2.1].\n* [JGit] is licensed under the [EDL]. \n* The Apache Commons `io` and `lang` libraries are licensed under the [Apache 2.0 License] \n\n[fuse-jna]: https://github.com/EtiennePerot/fuse-jna\n[JNA]: https://github.com/twall/jna\n[JGit]: http://eclipse.org/jgit/\n[jgit-cookbook]: https://github.com/centic9/jgit-cookbook\n[MacFUSE]: http://code.google.com/p/macfuse/\n[fuse4x]: http://fuse4x.org/\n[OSXFUSE]: http://osxfuse.github.com/\n[Linux-FUSE]: http://fuse.sourceforge.net/\n[FreeBSD-FUSE]: http://wiki.freebsd.org/FuseFilesystem\n[BSD 2-Clause License]: https://www.opensource.org/licenses/bsd-license.php\n[LGPL v2.1]: https://www.opensource.org/licenses/lgpl-2.1.php\n[EDL]: http://www.eclipse.org/org/documents/edl-v10.php\n[Apache 2.0 License]: http://www.apache.org/licenses/LICENSE-2.0\n","funding_links":["https://github.com/sponsors/centic9"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcentic9%2Fjgitfs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcentic9%2Fjgitfs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcentic9%2Fjgitfs/lists"}