GIT-LFS-FAQ(7)

πŸ“¦
version 3.7.1 Β· 4 versions
, in fedora 43, fedora 44

✨ git-lfs-faq(7) ✨

Okay bestie, welcome to the Git LFS FAQ β€” it’s giving manual page but make it group chat. πŸ’–


πŸŽ€ NAME πŸŽ€

git-lfs-faq β€” FAQ for Git LFS. That’s literally the name, periodt. πŸ‘‘


🌈 ENTRIES 🌈

πŸ“ File Size πŸ“

πŸ’… Does Git LFS provide a way to track files by size?

No, it doesn’t. 😭 And the reason is lowkey annoying: Git itself doesn’t specify a way to make .gitattributes patterns apply to files of a certain size, and we rely on the .gitattributes file to say which files are tracked by Git LFS.

You can use the --above option to git lfs migrate import to migrate all files that at the specified time are larger than a certain size. But β€” and this is the catch β€” if your files change to be smaller or larger in the future, or you add more files in the future that are larger than the limit you specified, you will have to track them manually. πŸ™ˆ

For these reasons, we recommend using patterns rather than --above. No cap. ✨

😭 Why doesn’t Git LFS handle files larger than 4 GiB on Windows?

Git LFS itself handles these files just fine. πŸ’… However, Git LFS is usually invoked by Git, and until Git 2.34, Git itself on Windows didn’t handle files using smudge and clean filters (like Git LFS) that are larger than 4 GiB. So you can update Git for Windows to 2.34 to natively support these file sizes. Slay.

On older versions, set GIT_LFS_SKIP_SMUDGE to 1 and run git lfs pull to pull down the LFS files. This bypasses Git’s smudging functionality and therefore avoids its limitations. 🫢


🌸 Working Tree Contents 🌸

πŸ₯Ί Why do I end up with small text files in my working tree instead of my files?

Git LFS stores small text files called pointer files in the repository instead of your large files, which it stores elsewhere. These pointer files usually start with the line version https://git-lfs.github.com/spec/v1. Iconic, honestly. ✨

Normally, if you’ve run git lfs install at least once for your user account on the system, then Git LFS will be automatically invoked by Git when you check out files or clone a repository and this won’t happen. However, if you haven’t, or you’ve explicitly chosen to skip that behaviour by using the --skip-smudge option of git lfs install, then you may need to use git lfs pull to replace the pointer files in your working tree with large files. πŸ’–

πŸ’€ Why do I end up with some of my working tree files constantly showing as modified?

This can happen if someone made a commit to a file that’s tracked by Git LFS but didn’t have Git LFS properly set up on their system. The objects that were checked into the repository are Git objects, not the pointers to Git LFS objects, and when Git checks these files out, it shows them as modified. Not the vibe. 😭

There are also several other possible ways to encounter this problem, such as an incomplete migration of your repository. For example, you should not use git lfs track to track patterns that are already in your repository without running git add --renormalize ., since that can lead to this problem.

Users frequently find that this cannot be changed by doing git reset --hard or other techniques because Git then checks the files out and marks them as modified again. The best way to solve this problem is by fixing the files and the committing the change, which you can do with the following on an otherwise clean tree:

$ git add --renormalize .
$ git commit -m "Fix broken LFS files"

This requires that every branch you want to fix have this done to it.

To prevent this from reoccurring in the future, make sure that everyone working with large files on a project has run git lfs install at least once. The command git lfs fsck --pointers BASE..HEAD (with suitable values of BASE and HEAD) may be used in your CI system to verify that nobody is introducing such problems. πŸ”₯


🚚 Tracking and Migration 🚚

πŸ‘€ How do I track files that are already in a repository?

If you want to track files that already exist in a repository, you need to do two things. First, you need to use git lfs track (or a manual modification of .gitattributes) to mark the files as LFS files. Then, you need to run git add --renormalize . and commit the changes to the repository. Two steps, bestie. Don’t skip. πŸ’…

If you skip this second step, then you’ll end up with files that are marked as LFS files but are stored as Git files, which can lead to files which are always modified, as outlined in the FAQ entry above. Note also that this doesn’t change large files in your history. To do that, use git lfs migrate import --everything instead, as specified in one of the entries below. πŸ¦‹

🧚 How do I convert from using Git LFS to a plain Git repository?

If you’d like to stop using Git LFS and switch back to storing your large files in the plain Git format, you can do so with git lfs migrate export --everything. Note that you will need to provide an appropriate --include option to match all the patterns that you currently have tracked in any ref.

This also rewrites history, so the Git object IDs of many, if not all, of your objects will change. ⚠️ Yes, history go bye-bye. Be aware.

😱 I’m using Git LFS, but I still see GitHub’s large file error. How do I fix this?

GitHub rejects large files anywhere in the history of your repository, not just in the latest commit. If you’re still seeing this message, then you have some large files somewhere in your history, even if in the latest commits you’ve moved them to Git LFS. So rude. πŸ’€

To fix this, you can use git lfs migrate import --everything with an appropriate --include argument. For example, if you wanted to move your .jpg and .png files into Git LFS, you can do that with git lfs migrate import --everything --include="*.jpg,*.png". More complicated patterns are possible: run git help gitattributes for more information on valid patterns. Note that if you’re specifying directories, using slashes is mandatory: backslashes are not allowed as path separators. 🚫


πŸ”§ Configuration πŸ”§

🌐 Can I use a proxy with Git LFS?

Yes, Git LFS supports proxies using the same mechanisms that Git supports, namely the http_proxy environment variable and the configuration of http.proxy (or http.*.proxy for per-URL usage). However, Git LFS only supports proxies which use Basic or no authentication, and it doesn’t currently support Digest or Kerberos authentication. So don’t come at it with Kerberos, okay? πŸ’…

If you’re using a proxy, we recommend that you set the full URL in the proxy value, including a scheme. Thus, http://example.com:3128 is a better choice than example.com:3128. If you need a username and password, they must be percent-encoded in the URL, so a username of foo\bar with a password of abc@123+ using the above proxy would be http://foo%5cbar:abc%40123%2b@example.com:3128. Percent-encoding is the moment. ✨

Note that, just like with Git, proxies must not modify, buffer, tamper with, or change the response to the data in any way, upstream or downstream, and any proxy which does so will break things and is not supported. The Git LFS developers don’t recommend any sort of proxy, including any sort of antivirus, firewall, or monitoring software, which performs TLS interception because these are known to cause breakage and in general have been shown to worsen security. 🚨

Big yikes. TLS interception is not the vibe β€” it breaks things and is not supported.

πŸ” Can I use a custom set of SSL/TLS certificate authorities with Git LFS?

Yes, Git LFS supports configuring trusted certificate authorities and client certificates for HTTPS, using the same configuration as for Git. πŸŽ€

To configure a set of trusted certificate authorities, you can use http.sslCAPath to specify a directory of files, each one containing a PKCS#1 certificate of a trusted certificate authority. If you’d prefer to use a single file with all trusted certificates, you can use http.sslCAInfo to refer to a single file containing PKCS#1 certificates, one following the other.

For example, on Debian, to set this option to provide the default behavior, you could run git config http.sslCAPath /etc/ssl/certs. Note that it’s also possible to set these configuration options on a per-URL basis, like so: git config http.https://example.com/.sslCAPath /etc/ssl/certs. πŸ’–

Note that PKCS#12 files are a Git for Windows extension to Git and are not supported by Git LFS. Additionally, take into account the information about TLS-intercepting proxies above if this configuration is because of a TLS-intercepting proxy. 🫢

πŸͺͺ Can I use an SSL/TLS client certificate with Git LFS?

Yes, Git LFS supports configuring client certificates and keys using the same configuration as for Git. πŸ‘‘

To configure a client certificate, use the http.sslCert configuration option pointing to a file containing a PKCS#1 certificate. To configure the corresponding key, use http.sslKey with a file containing a PEM-encoded key. If it is encrypted, you will be prompted using the credential helper for the passphrase. πŸ”

Usually you will want to specify these values on a per-URL basis, such as the following: git config http.https://example.com/.sslKey /home/user/.certs/mine.key.

Note that PKCS#8 and PKCS#12 files are not supported by Git LFS. πŸ’…


🌈 Working with Git Features 🌈

πŸ” How do I enable git diff to work on LFS files?

You can run git config diff.lfs.textconv cat, which will produce normal diffs if your files are text files. Easy. ✨

🧩 How do I enable git diff to work on LFS files based on extension or path?

If the above solution is too broad, each entry in the .gitattributes file can be customized by creating a custom global converter:

$ git config --global diff.lfstext.textconv cat

Any given .gitattributes entry for large text files can be customized to use this global text converter (e.g., patch files), whereas binary formats can continue to use the conventional lfs diff tool, like so:

$ cat .gitattributes
....
*.bin filter=lfs diff=lfs merge=lfs -text
*.patch filter=lfs diff=lfstext merge=lfs -text
....

Be advised that all developers sharing this repo with such a modified .gitattributes file must have similarly configured the lfstext text converter, whether globally or on a per repository basis. No cap. πŸ”₯

πŸ’­ Why are LFS files not included when I archive a subdirectory?

okay bestie, this one is genuinely not Git LFS being shady, it's just how git archive works, and once you see it you'll be like "oh. OH."

So when you run git archive with only a subdirectory, like git archive HEAD:src, Git resolves that revision (here, HEAD:src) into a tree and then only processes the items inside that tree. And the .gitattributes file? It's typically chillin' in the root of the repository. So Git doesn't even see it. And .gitattributes is literally the thing that says "hey, these files are LFS files." No .gitattributes in sight means Git doesn't treat any file in that directory as an LFS file, which means Git LFS never gets invoked at all. πŸ’€

And because Git LFS doesn't even get invoked in this case, there is no way to change how this works. Periodt. That's not a config you can flip, bestie, it's just the mechanics.

But! There's still stuff you can do. 🌈

  • If you just want to include that single subdirectory without stripping the prefix, you can do this:
git archive -o archive.tar.gz --prefix=archive/ HEAD src
  • If you do want to strip the subdirectory name (src) in this case, one option β€” if you have the libarchive tar (available on Windows and macOS as tar, and usually on Linux as bsdtar) β€” is to do something like this script:
#!/bin/sh

# With trailing slash.
ARCHIVE_PREFIX="archive/"
# Without trailing slash.
SOURCE_PREFIX="src"
# Without directory or file components.
REVISION="HEAD"

temp=$(mktemp -d)

git archive --prefix="$ARCHIVE_PREFIX" "$REVISION" "$SOURCE_PREFIX" | bsdtar -C "$temp" -xf -
bsdtar -s "!^\./!$ARCHIVE_PREFIX!" --format=pax -czf archive.tar.gz -C "$temp/$ARCHIVE_PREFIX$SOURCE_PREFIX" .
rm -fr "$temp"

like, look at her go 🧚 β€” temp dir, pipe in, repack out, clean up. iconic.


πŸ› οΈ Working with Non-Git Tools πŸ› οΈ

😭 I'm using Jenkins and git lfs install fails due to an invalid hook path. What do I do?

oh no, the Jenkins of it all. πŸ™ˆ So here's the tea: recent versions of Jenkins have set core.hooksPath to various values, notably NUL: on Windows, with the goal of disabling hooks. Problem is, that's not a valid path on Windows, and it's not a valid value for this configuration option either. So when git lfs install runs and Git LFS tries to install hooks, the whole operation just… fails. πŸ’€

The easiest way out is to use the --skip-repo option with git lfs install, which skips the installation of the hooks. And despite the name, it can be successfully combined with --local if you need that option. slay. ✨

⚠️ but listen β€” this prevents things like git push from pushing LFS objects, and it prevents locked files from being read only, since those are implemented by hooks. If you need that functionality, you should review the Jenkins documentation about how to properly configure the environment in such a situation so that hooks can be used. fr fr, read the docs. 🫢

πŸ‘€ SEE ALSO πŸ‘€

Part of the git-lfs(1) suite. πŸ’œ


and that's the whole vibe, bestie β€” this was GIT-LFS-FAQ(7), the FAQ page from the git-lfs(1) family, go forth and archive responsibly πŸ’…πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from