Search code examples
gitremote-accessrefspec

GIT: remote reposity, difference between hard link and file://


I'm currently reading the book Version Control with Git, by Jon Loeliger.

It talks about the 2 subtle differences between hardlinks and the file://:

As you have seen, the simplest form of Git URL refers to a repository on a local file- system, be it a true physical filesystem or a virtual filesystem mounted locally via the Network File System (NFS). There are two permutations:

/path/to/repo.git

file:///path/to/repo.git

Although these two formats are essentially identical, there is a subtle but important distinction between the two. The former uses hard links within the filesystem to directly share exactly the same objects between the current and remote repository; the latter copies the objects instead of sharing them directly. To avoid issues associated with shared repositories, the file:// form is recommended.

At first, I did think that my cloned repo ./git/object folder was a link to the remote .git/object, but I guess it's not.

Can someone explain this?


Solution

  • git clone in both cases creates a new copy (identical clone) of the target repository, with the old one added as a remote. They are two separate repos.

    The difference lies in that if you use the syntax

    git clone /path/to/repo.git
    

    git will try to save space by using hard links in the file system for files that are 1. identical to both repos and 2. not expected to change. The only files that are expected to be identical and not change (except in case of repacking objects) are the files in .git/objects at the time of creating the clone.

    This saves spaces since hard links mean that you are referring to a file's content multiple times in different places, but only storing the actual content once. (Git itself actually uses a similar mechanism in its object database, it will not store a unique file's content more than once.)

    If you want to force git to create a new copy also of the files in .git/objects, using the syntax

    git clone file:///path/to/repo.git
    

    will accomplish that.