Git and libgit2

Git LFS Server URLs

Published 2025-01-06. Last modified 2025-01-23.
Time to read: 6 minutes.

This page is part of the git collection.

I have published 8 articles about the Git large file system (LFS). They are meant to be read in order.

  1. Git Large File System Overview
  2. Git LFS Scripts
  3. Git LFS Client Installation
  4. Git LFS Server URLs
  5. Git-ls-files, Wildmatch Patterns and Permutation Scripts
  6. Git LFS Tracking, Migration and Un-Migration
  7. Git LFS Client Configuration & Commands
  8. Git LFS SSH Authentication
  9. Working With Git LFS
  10. Evaluation Procedure For Git LFS Servers
  11. Git LFS server tests:
    1. Null Git LFS Server

6 articles are still in process.

Instructions for typing along are given for Ubuntu and WSL/Ubuntu. If you have a Mac, most of this information should be helpful.

This Article Probably Contains Errors

This article is incomplete and may contain errors. It has been published to allow collaboration with fact-checkers. Not all of these scenarios might make sense to attempt to review. Do not rely on this information yet.

Default LFS Server URL

The default LFS server is assumed to be provided by the same organization as your Git server. By default, the LFS remote is derived from the origin remote.

For example, if your Git repository resides on GitHub, the default Git LFS server is also assumed to be provided by GitHub. If the URL for your origin remote is expressed in scp format as:

remote.origin.url
git@github.com:foo/bar.git

then the following will be the default value of lfs.url:

lfs.url
https://github.com/foo/bar.git/info/lfs

The rest of this article, and the remainder of this series of articles about Git LFS, assume that you want to use a different Git LFS server than the default. I explained why here.

Server Discovery

Are the green comments accurate?

I enhanced the following quote with information about some of the Git configuration variables involved and examples of the various flavors of the local protocol.

One of the Git LFS goals is to work with supporting Git remotes with as few required configuration properties as possible. Git LFS will attempt to use your Git remote to determine the LFS server. You can also configure a custom LFS server if your Git remote doesn't support one, or you just want to use a separate one.

Look for the Endpoint properties in git lfs env to see your current LFS servers, or examine the value of lfs.url and compare to the value of remote.origin.url.

Guessing the Server

By default, Git LFS will append /info/lfs or .git/info/lfs to the end of a Git remote URL to build the LFS server URL it will use. However, this is not the case with the local protocol, which comes in three flavors. If remote.origin.url specifies a syntax that is recognized as the local protocol, no Git server is used. Instead, the Git client does all the work. Similarly, if lfs.url specifies a syntax that is recognized as the local protocol, no Git LFS server is used, and again the Git client does all the work.

Git Remote: /foo/bar
LFS Server: none; the Git client directly accesses LFS content in the local directory /foo/bar/lfs


Git Remote: file:///node/bar
LFS Server: none; the Git client directly accesses LFS content at the shared network directory file:///node/bar/lfs


Git Remote: file:////unc_dir/bar
LFS Server: none; the Git client directly accesses LFS content in the Windows UNC path \\unc_dir\bar\lfs
. I do not know if Git can use this variant of the local protocol on Macs or Linux machines.

Git Remote: https://git-server.com/foo/bar
LFS Server: https://git-server.com/foo/bar.git/info/lfs

Git Remote: https://git-server.com/foo/bar.git
LFS Server: https://git-server.com/foo/bar.git/info/lfs

Git Remote: git@git-server.com:foo/bar.git
LFS Server: https://git-server.com/foo/bar.git/info/lfs

Git Remote: ssh://git-server.com/foo/bar.git
LFS Server: https://git-server.com/foo/bar.git/info/lfs

You can, of course, override the guessed value of lfs.url. The next section details how.

.lfsconfig

You probably know about the client-side Git configuration file called .gitignore, which informs the Git client the files and directories that should not be considered for inclusion into the Git repository.

Similarly, the Git LFS extension for the Git command-line client looks for another file at the top of a Git repository: .lfsconfig. Like .gitignore, .lfsconfig must be checked in. This means that Git LFS configuration information is automatically available when cloning a Git repository.

.lfsconfig informs the Git client what the access point of the Git LFS server is. If you want to point the Git client at a different Git LFS server, just change the value for lfs.url stored in this file.

The man page for git-lfs-config describes the content of .lfsconfig:

The .lfsconfig file in a repository is read and interpreted in the same format as the file stored in .git/config. It allows a subset of keys to be used, including and limited to:

  • lfs.allowincompletepush
  • lfs.fetchexclude
  • lfs.fetchinclude
  • lfs.gitprotocol
  • lfs.locksverify
  • lfs.pushurl
  • lfs.skipdownloaderrors
  • lfs.url
  • lfs.\{*}.access
  • remote.{name}.lfsurl

The set of keys allowed in this file is restricted for security reasons.

Querying the Current Git and LFS Servers

As you probably know, you can view the Git server for the current repository with:

Shell
mslinn@bear my_repo $ git config get remote.origin.url
git@github.com:mslinn/www.mslinn.com.git 

You can view the current LFS server for each remote with:

Shell
mslinn@bear my_repo $ git lfs env | grep Endpoint
Endpoint=gojira:test.lfs (auth=none) 

Custom Git LFS Server URL

Each Git LFS server is accessed via a unique URL, known to Git LFS as the lfs.url Git configuration value. We will set that to a unique value for each Git LFS server that is evaluated.

The value should be stored in .lfsconfig; that file should be committed to the Git repository. That file can also hold authentication information.

If any local protocol scenarios can be made to work, then the following needs to discuss exceptions to the following syntax.

The general form of the incantation to establish a value for lfs.url is:

Shell
mslinn@bear my_repo $ git config -f .lfsconfig lfs.url \
http://my_lfs_server/api/my_org/my_repo

Breaking down the above incantation:

  1. git config: This configuration value is local to the current Git repository, so it is not a global setting.
  2. -f .lfsconfig: Write this configuration value to the file .lfsconfig, not the default file (.git/config).
  3. lfs.url: This is the name of a morsel of client-side Git LFS configuration data.
  4. This is the value of the aforementioned morsel of client-side Git LFS configuration data. When stored in .lfsconfig it looks as follows:
    .lfsconfig
    [lfs]
    url = "http://my_lfs_server/api/my_org/my_repo"
                  ───────┬───── ─┬─ ──┬─── ───┬───
                         │       │    │       └ The name of your project
                         │       │    └ Your organization name
                         │       └ See the next section
                         └ The host name and port of your LSF server

The above git config command also adds the following to .git/config:

.git/config fragment
[lfs "http://my_lfs_server/api/my_org/my_repo"]
locksverify = false

About the api/ Portion of the URL

The api/ portion of the URL depends on the Git LFS server. The Git LFS standard states that it must be present as shown. Some Git LFS servers, for example giftless, default to not complying with the standard. The local protocol, discussed next, does not utilize this portion of the URL.

Example

Create .lfsconfig as follows:

Shell
mslinn@bear my_repo $ git config \
  -f .lfsconfig \
  lfs.url http://gojira:9876/mslinn/myrepo

.lfsconfig should now look like this:

.lfsconfig
[lfs]
url = http://gojira:9876/mslinn/myrepo

Now commit the changes:

Shell
mslinn@bear my_repo $ git add .lfsconfig && \
  git commit -m 'Set Git LFS server' && \
  git push -u origin master

The next time this repository is checked out, the Git LFS server will be defined.

The File URI Schema And The Local Protocol

A Git URL can have one of five types of schemas, which invoke a corresponding protocol. The Pro Git book describes most of the protocols. The complete list of protocols for Git URLs are: git, http, https, local, and ssh. Git and Git LFS clients support all of these protocols.

Most of the protocols that Git supports (git, http, https, and ssh) are request-response protocols.

However, the local protocol is different from the other protocols in that it is passive. As you know, the only operations that can be performed with files are reading from them and writing to them. The local protocol does not listen for changes to file systems, so there are no callbacks. This means that Git client hooks are never triggered when using the local protocol. Instead, the Git client does all the work.

The local protocol is available in two flavors. One of those flavors is the file URI schema.

Git’s local protocol implementation is less powerful than the implementation provided by web browsers. The file protocol implementation provided by web browsers is able to traverse local directories (directories on your computer), and directories shared on a network.

However, the Git implementation is only able to traverse local directories and shared directories that are mounted on the local file system. If a shared network directory is not mounted an error Git will terminate with an error.

This means the only usable Git repositories shown in a web browser while using the file schema are those located on the local file system, or mounted on the local file system. See Bare Git Repositories for more information.

Caveats are required for bare git repos with the local protocol.

The following incantation clones a local repository using the local protocol, which means the directory containing the repository being cloned is accessible from the computer. Note the three slashes in the URI:

Shell
mslinn@bear ~ $ git clone file:///my_local_directory

You could also specify the same repository without the file:/// prefix:

Shell
mslinn@bear ~ $ git clone "my_local_directory"

Quotation marks are required if the path to the repository has spaces in it.

You can reference a mounted network path using the local protocol. The following example clones a repository residing on the local file system mount point called gojira_mslinn, with path git_path:

Shell
mslinn@bear ~ $ git clone file:///gojira_mslinn/git_path

UNC Paths

The syntax for a UNC path is similar to the syntax for the network path incantation immediately above. The syntax for a UNC path has four slashes.

The following example clones a repository residing on the machine with UNC address GOJIRA, in a public directory called git_repo:

Shell
mslinn@bear ~ $ git clone file:////GOJIRA/git_repo

I have published 8 articles about the Git large file system (LFS). They are meant to be read in order.

  1. Git Large File System Overview
  2. Git LFS Scripts
  3. Git LFS Client Installation
  4. Git LFS Server URLs
  5. Git-ls-files, Wildmatch Patterns and Permutation Scripts
  6. Git LFS Tracking, Migration and Un-Migration
  7. Git LFS Client Configuration & Commands
  8. Git LFS SSH Authentication
  9. Working With Git LFS
  10. Evaluation Procedure For Git LFS Servers
  11. Git LFS server tests:
    1. Null Git LFS Server

6 articles are still in process.

Instructions for typing along are given for Ubuntu and WSL/Ubuntu. If you have a Mac, most of this information should be helpful.

* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.