Bringing a Git LFS repository across

Why the pointers arrive instead of the bytes, and how to fix it before importing.

Written By Dustin

Last updated About 3 hours ago

TOVIO has no LFS and needs none: content-defined chunking stores large binaries incrementally and deduplicates them, so a multi-gigabyte asset is an ordinary tracked file. Getting an existing LFS repository into that state takes one step on the Git side first.

What goes wrong if you skip it

tovio git import reads Git's object database. In an LFS repository, what is in that database for a tracked asset is not the asset — it is a small pointer file naming an object stored somewhere else. So the import succeeds, and every large file arrives as a few lines of text.

Fetching LFS content into your working tree does not change this, because the working tree is not what import reads.

Fix it in Git, then import

Replace the pointers with real blobs in the Git history before importing. Git's own LFS migration tooling does this; work on a throwaway clone, because it rewrites history.

  1. Clone the repository fresh, and make sure every LFS object is available locally.
  2. Rewrite the history so the pointers become real blobs. This is what git lfs migrate export is for.
  3. Confirm it worked: check out an old commit and look at a large file. If it is the real content and not a pointer stanza, you are ready.
  4. Import that rewritten clone into a fresh TOVIO repository.

Because it is a throwaway clone, a mistake costs you a re-clone rather than your history. Do not run the rewrite against the repository your team is using.

Check the size before you start

The rewritten clone holds every version of every binary as a real object, which is exactly the history LFS was keeping elsewhere. Expect it to be large, and expect the import to take a while — import cost scales with history, not with working-tree size, and this step makes the history honest about what it contains.

Consider --no-repack on the import and a separate tovio gc --repack afterwards, so a long pack step is not sitting inside the import.

Afterwards

  • .gitattributes is a dotfile, so it will not be tracked unless you negate it in .tovioignore. You probably no longer want its LFS filter lines anyway.
  • Nothing needs installing on a colleague's machine to read the binaries. That is the point.
  • If you later export back to Git, the binaries export as ordinary Git blobs — not as LFS pointers.