has anyone made a read-only FUSE filesystem for a git repository where every commit is a folder and the folder contains all the files in that commit?

the idea is that you could just run `cd COMMIT_ID` and poke around instead of checking out the commit

and maybe the branches could be symbolic links to the commit folders?

guys this is such a fun idea I cannot believe people are in the replies trying to explain to me why they think it is impractical

the whole point of computers is to do impractical things and see what happens

seems like the answer is yes!

- https://github.com/fanzeyi/giblefs (fuse implementation in rust where every commit is a folder)
- https://orib.dev/git9.html (for plan 9)

would love to hear about any others

GitHub - fanzeyi/giblefs: Mapping a Git repository as a virtual filesystem

Mapping a Git repository as a virtual filesystem. Contribute to fanzeyi/giblefs development by creating an account on GitHub.

GitHub

ok I got extremely nerd sniped and made my own version of this “filesystem where every git commit is a folder" thing https://github.com/jvns/git-commit-folders

I wrote a FUSE version and an NFS version that I think will be easier for mac users to use. it definitely does not work on windows.

it probably has about 5 million bugs but it seems to kind of work

GitHub - jvns/git-commit-folders

Contribute to jvns/git-commit-folders development by creating an account on GitHub.

GitHub

the main reason I've found this "all your git commits are folders" feature to be useful is for searching past code: I can run `grep someFunction branch_histories/main/*/commit.go` to find the old version of someFunction I deleted. There are other ways to do that in git but this is easier.

or if I want to just quickly look at a file on another branch to copy a line from it, I can run `vim branches/other-branch/go.mod`

curious about other use cases

(from https://github.com/jvns/git-commit-folders)

GitHub - jvns/git-commit-folders

Contribute to jvns/git-commit-folders development by creating an account on GitHub.

GitHub
ok i made my git commit folders nonsense work with the linux kernel repo (there are some issues but it seems like it can handle 1 million commits without too many problems)
@b0rk Speaking of the kernel, have you ever used or heard about the version(s) of ClearCase that included a kernel driver to implement something a lot like this experiment of yours? I believe it would patch the system calls made by commands like ls and cd to enable file-system traversal to traverse the version control system. Talk about a heavyweight approach!
@siracusa yea people keep mentioning it, i'd never heard about it before

@b0rk I used it many years ago, but I’m pretty sure this is the feature: https://www.ibm.com/docs/en/rational-clearcase/9.0.2?topic=views-multiversion-file-system

At the time, I thought it was neat, and I was curious enough to try to figure out how it worked. But it always seemed like a strange choice as the main/default way to interact with an RCS.

The multiversion file system

@b0rk this is super cool also for a use-case I have where I sometimes need to access older versions of a data file that gets overwritten daily. Current process uses a hacky temp-checkout method, but your work makes it possible to just use `fd`/`find`!
@hrbrmstr @b0rk it can be done with git show <revision>:full/path/to/file , but I always have to google the syntax and it's annoying that tab completion doesn't work (since you need to specify the full path from root instead of current folder)
@rpetre aye that’s the hack I’ve been using in an R function wrapper. This is much cleaner
@b0rk how performant is that. Does it search all files in all commits, or only changed files?
@sumurai8 it's not that efficient but my repo is small so it's not a big deal. you do have to be careful though
@b0rk Still cool though! :-)

@b0rk if I want to find a past piece of file contents on a known branch, there are existing ways, like git log -G. I think where your thing would be *really* useful is if I can't even remember which *branch* it is.

"I remember that somewhere among my 50 half-finished dev branches I added a function called do_useful_thing(), but arrgh, which one?"

@simontatham @b0rk

There is "git grep" for that.

@albertcardona @simontatham I thought git grep only searches the current working tree

@b0rk @albertcardona you can make it search a specific commit in place of the worktree, so you could do something like

for r in $(git rev-list <params>); do git grep search_term $r; done

but it's cumbersome, and doesn't annotate the results with which commit they came from, unless you add a further "| sed" or some such. But with a git-fuse filesystem you could do this, which is short and simple and does show where it found the term:

grep search_term gitfs/*/*/foo.c

@simontatham @b0rk git log -G is great for searching in the commits diffs, but for addition/deletion specifically -S is awesome. It lists only the commits where the number of occurrences of the string changed.

https://git-scm.com/docs/git-log#Documentation/git-log.txt--Sltstringgt

Git - git-log Documentation

@bihi @b0rk I can never remember which of those is which!
@simontatham @b0rk The --branches option should cover that
@simontatham @b0rk use git log --branches -G to search across all branches. It should be more efficient than the filesystem approach since it will search commits in reverse order and you’re more likely to be thinking of a function you added recently.

@b0rk This is really neat! It feels a lot more straightforward than existing equivalents like git-grep or editor plugins. Very cool for these existing tools to suddenly work with git “for free”.

I wonder if you could make saving a file from an editor do something useful. Maybe make a branch with a name based on the process name/pid and commit to that?

@b0rk this is so cool! This brings back the every-branch-is-a-folder thing of svn I missed so dearly.
@b0rk That reminds me of a use case I struggle with in git that I used all the time in Perforce: what the P4V GUI Perforce client calls “Time-Lapse View.” Open a file in time-lapse view and you see the file contents plus a slider at the top that will take you through all revisions of the file, changing the displayed content as you slide it around. The way Perforce handles file revisions makes this straightforward, but this is less true in git. Most git GUI clients don’t have this feature at all.
@siracusa that's interesting, it doesn't seem to me like there's anything about the design of git that would make that hard to implement

@b0rk Perforce’s use of increasing revision numbers for files makes it an easy fit for the ussr’s mental model: “The latest revision is 5, but I want to see revisions 4, 3, 2, and 1.” The way Perforce handles branching also fits: different paths for each branch, so branch-a/file has a different set of revision numbers than branch-b/file.

I’m not sure how best to map a “revision slider” to users’ various mental models of git.

@siracusa what i'm doing in my commit folders project (which is kind of silly but sort of works) is numbering the revisions backwards -- so you have branch_history/main/0, branch_history/main/1, etc. 0 is the latest and the other numbers are relative

the numbers wouldn't be stable, but you can say something like “as of 912da3150d9cfa74523b42fae028bbb320b6804f, 5 versions ago”

@b0rk Hah, makes sense! I guess that concept already exists in the git CLI in the form of things like HEAD~N.
@siracusa @b0rk for me as a sporadic GUI only git user (for small, not that messy code bases and some git scraping), I’ve used sites like this one to accomplish that: https://githistory.xyz/
Git History

Quickly browse the history of a file from GitHub, GitLab, Bitbucket or any git repository

@aronambrosiani @siracusa i'd never seen this, this is great
@b0rk @siracusa there's also another site I've used specifically for viewing git scraped json data, makes interactive tables: https://flatgithub.com/
@aronambrosiani @b0rk @siracusa giving websites access to source code is a non-starter for many companies.
@aronambrosiani Yeah, I think I found that one on my last search, but I didn't figure out if it supported private repos. Maybe it does through the browser extensions?
@aronambrosiani It looks like the local command-line version works with private repos (by doing everything locally). I do wish it highlighted the line-by-line changes better (and let you jump between them) but it's a start!
@aronambrosiani @siracusa @b0rk I resorted to writing my own, but it did the job sufficiently for gitscraping extraction.
@siracusa @b0rk the closest thing in git is probably “git blame”. It allows to navigate the history of a file by the commits that affected each line. This isn't necessarily better than a plain “timeline” view, but it has its benefits.

@oblomov @siracusa @b0rk With "git gui blame" you can even go backward and forward in time, selecting the line and going back to how it looked before (and how the rest of the file looked like then).

And "git gui blame" shows when the line changed both with and without code copying detection (if they differ, it may be because the code was moved and copied from other file: one column would show when it was moved, one when it was introduced/changed).

@siracusa @b0rk my git client does this. It’s pretty similar to Tower, which I know @marcoarment liked but I found buggy. The slider is up top, although I just arrow through the commits on the left.
@yertle What client is this?
@siracusa oops, it’s Git Fork. Very similar to Tower, but fits me better, and it’s not a subscription!
@siracusa @b0rk FWIW there’s a “git Time Machine” library for Emacs that implements the forward/back sequencing file view you describe (IIUC). I use it a lot, it’s very nice
@siracusa @b0rk FWIW if you're an Emacs user, you can use https://gitlab.com/pidu/git-timemachine which sounds exactly like what you're looking for.
Peter Stiernström / git-timemachine · GitLab

Step through historic versions of git controlled file using everyone's favourite editor

GitLab
@siracusa @b0rk The gitlens extension for vscode has the "File History View" which kinda gives you this. https://help.gitkraken.com/gitlens/side-bar/#file-history-view
GitLens Side Bar Views | GitLens Views and Functionality

GitLens' side bar views provide additional functionality in VS Code. Learn how to customize the GitLens default layout via the GitLens: Set Views Layout command.

GitKraken Help Center

@siracusa @b0rk Git itself has a built-in tool that does almost exactly this -- `gitk`: https://git-scm.com/docs/gitk (Seems to be another instance of a cheekily/unclearly-named Git Thing because the UI is written in Tcl/Tk.)

Running `gitk -- path/to/file` shows a UI that lets you quickly jump between all commits that revised that file, showing only the changes to that file.

Is installable via Homebrew on Mac with `brew install git-gui` -- git-gui is another related tool: https://git-scm.com/docs/git-gui

Git - gitk Documentation

@siracusa @b0rk The gitlens extension for VS Code does this. I use it all the time. It will automatically show the file history of the active file, and you can click to get the diff.

@siracusa @b0rk same thing with the Subversion client I used to use. Of course branches and merging were near impossible on Subversion, but at least you could see changes over time.

¯\_(ツ)_/¯

@b0rk if you wanna do windows, try webdav :>
@arcade yea i wrote a webdav implementation too actually but it has a lot of problems
@b0rk I asked a friend at MS who helpfully pointed me to the fact that Windows since Win 10 build 1903 ships with a 9P client (because WSL2 uses it) so in theory if someone did want to make this idea work on Windows too then it might be possible.
@0x2ba22e11 ooh cool
@b0rk @0x2ba22e11 There is a FUSE equivalent for Windows, btw: WinFSP (https://winfsp.dev). The excellent SSHFS for Windows (https://github.com/winfsp/sshfs-win) is implemented on top of it.
WinFsp

@b0rk Brilliant!

Exposing things as filesystems rocks! It becomes ridiculously useful to be able to do things like grep and write scripts against stuff like service discovery, ldap/ad, or weird metrics exporting (jmx, snmp, etc).

"Everything SHALL be a file” :-)

@brianm @b0rk That looks useful in combination with Git scraping.

"track changes over time by [collecting changes] to a Git repository"

https://simonwillison.net/2020/Oct/9/git-scraping/

Git scraping: track changes over time by scraping to a Git repository

Git scraping is the name I’ve given a scraping technique that I’ve been experimenting with for a few years now. It’s really effective, and more people should use it. Update …

Simon Willison’s Weblog
@b0rk this might make it easier to make tools like the Obsidian-Git plugin https://github.com/denolehov/obsidian-git , which lets you autocommit changes in your Obsidian vault to a Github repo for syncing between machines
GitHub - denolehov/obsidian-git: Backup your Obsidian.md vault with git

Backup your Obsidian.md vault with git. Contribute to denolehov/obsidian-git development by creating an account on GitHub.

GitHub
@b0rk Hm... Are you recreating ClearCase? That thing is/was horrid to use.
@b0rk It is extremely satisfying to browse a homemade filesystem made with FUSE, which is good, because it counterbalances the extreme frustration of trying to understand its documentation 😆
@b0rk Interesting, thanks for making this available! It seems a hybrid of the timeshift capability of BTRFs (where you can browse snapshots without restoring) and git checkout if I understand it correctly?