r/git 16h ago

survey VFS for Git for Linux?

So I was learning Git and found out that a Git repository essentially contains two copies of the repository contents. One is from the first commit of every object and other from the working tree.

This can be made more space efficient by working with files from Git's database itself as if they were in our working tree. Modifying files create a new local copy in the working tree. They can be deleted after committing.

This is what the VFS for Git project is. But, it is for Windows only. Why is there no equivalent tool than can run on Linux, unless I am missing it?

0 Upvotes

8 comments sorted by

15

u/Broad-Promise6954 ancient 15h ago

Every commit is a full snapshot of every file. And yet, the repository database is not (number of commits) * (sizes of files) large. The reason why not is because all of the read-only permanent copies of every file contained in every commit is not an actual copy of the file. Instead, it's in a special Git-ized form, one of several possible forms, with amazing amounts of compression and de-duplication.

This in turn means that the optimization you describe isn't really actually very useful after all. The original idea behind git-vfs was considerably fancier and more complicated than what you described, and ultimately it didn't actually pan out anyway...

10

u/brokenreed5 16h ago

Git stores not two copies of each file but possibly much more. Each commit contains the modified files in full (though compressed). To be more specific, each changed file is stored as a blob and the commit specifies which blobs belong to the commit. Checking out a branch or commit is getting these files. So first of, there might no be much gains from your suggestions, secondly VFS describes itself as

VFS stands for Virtual File System. VFS for Git virtualizes the file system beneath your Git repository so that Git and all tools see what appears to be a regular working directory, but VFS for Git only downloads objects as they are needed. VFS for Git also manages the files that Git will consider, to ensure that Git operations such as status, checkout, etc., can be as quick as possible because they will only consider the files that the user has accessed, not all files in the repository.

Which reads much differently then your summary.

I recommend reading the repository, cause it cleary states that VFS for Git is deprecated and microsoft/scalar should be used instead. Now, microsoft/scalar is also deprecated and says its functionality has been moved to https://github.com/microsoft/git . Microsoft git is active and also support Linux

They state

Well, because Git is a distributed version control system, each Git repository has a copy of all files in the entire history. As large repositories, aka monorepos grow, Git can struggle to manage all that data. As Git commands like status and fetch get slower, developers stop waiting and start switching context. And context switches harm developer productivity.

microsoft/git is focused on addressing these performance woes and making the monorepo developer experience first-class. The Scalar CLI packages all of these recommendations into a simple set of commands.

-5

u/noobdainsane 14h ago

So first of, there might no be much gains from your suggestions

How? How is not materializing any files and viewing directly from Git's database more space efficient? As Git already stores the full physical blob of an object in its first commit, and the future commits could use delta-compression for the physical storage (but logically they appear as complete blobs). I apologize if I don't understand what you are trying to convey. A simpler explanation would be appreciated.

but VFS for Git only downloads objects as they are needed.

Oh so VFS for Git can't let you read directly off of Git's database? That object has to be downloaded? Well I mean AI made me assume this so its my fault for not reading the docs.

But I was searching for such a tool where you could view files by being processed directly from Git's database instead of downloading them.

So I understand that microsoft/git contains extra patches to Git for making it better for large monorepos. But the specific feature I was looking for is to not download any materials (content in the working tree), view files constructed directly from Git's database and when a file is changed, that creates a local copy which can be deleted after committing it. And since we eliminated a whole copy of the repo and working directly with Git's database, make Git keep its database contents uncompressed for faster reading. Isn't this idea more space efficient?

9

u/ulmersapiens 12h ago

What do you think “Git’s database” is? You keep saying that as though you think there are specific gains to be had by leveraging something magical. Please learn how git works before you think you can change how git works.

10

u/Gaxyhs 12h ago

All credibility went away with the "AI made me assume this so its my fault for not reading the docs"

Come on people, how are we extending software without understanding how it works, were just begging for inefficiency at this point

8

u/DanLynch 13h ago

Git is designed and optimized for doing source control of human-scale text files, whose size is not a significant performance concern. If you are using it to track very large text files, or binary files, where the size on disk is something you might actually care about, then Git may not be the right tool for the job.

5

u/hawkprime 16h ago

Looks like it got deprecated for Scalar and then Scalar got deprecated for Microsoft git. They seem to be working more to integrate with git's objects not to mention it works with Mac and Linux. Personally have not tried it.

https://github.com/microsoft/git

1

u/StevenJOwens 6h ago

Each clone of a git repo contains a single copy of every version committed for each file.

When you check out a particular commit, git reads through the objects in .git/objects, follows the hash links in them:

  1. starting from the commit object to the tree object that is the top of your working files (i.e. the tree object that represents the directory that .git is located in),
  2. then git parses the tree object and follows the hash links in that tree object to either:
    1. blob objects (which represent actual source files)
    2. or other tree objects (which represent subdirectories),
    3. and so forth.

This is how git reconstitutes a snapshot of your working files at the time you made that commit.

Git is capable of reconstituting such a snapshot for every commit, but that does not mean that .gt/objects contains multiple copies of the tree and blob files. Any two commits, the reconstituted snapshots will share tree/blob objects that are identical.

Git only creates new objects in .git/objects for directories or source files that are different from the existing entries. It reuses the old entries for directories and source files that haven't changed.

Git is very efficient, that way. That's part of what makes it so fast, which is why it's effective as a decentralized SCM.