Matthew van Boheemen
Matthew van Boheemen

Reputation: 1335

Adding missing LFS files that causes: Encountered X file(s) that should have been pointers, but weren't

I've got a git repository that had existing files in it. I then setup git-lfs to handle files of particular types (e.g. pdf, tif etc). This works fine for new files and they are stored in LFS as expected. However, files that were already in the repo but should have been stored in LFS aren't. This leads to the error below when cloning the repo:

Encountered 361 file(s) that should have been pointers, but weren't:

How can I convert these files over so that they are stored in LFS rather than in git? I don't care about rewriting history, just need to tidy this up for moving forward.

Upvotes: 4

Views: 14046

Answers (3)

LyrePyre
LyrePyre

Reputation: 461

For the problem of having many many paths to fix this for, it was suggested under derekhh's answer to use git lfs migrate import --no-rewrite **/*; however—even IF everyone had extended wildcard support in their shell–this quickly fails as soon as it reaches a file in Git that doesn't match the lfs patterns in the .gitattributes file.

Here's two ways that worked for me:

Way 1

  • assumes I know some pattern(s) that all problem paths fall under (i.e. they're all jpegs)
git lfs migrate import --no-rewrite $(find . -type f -iname '*.jpg')

Way 2

  • if I don't care if (or actually want) a separate new commit for each fixed file
  • again, assumes I know ahead of time a path pattern
find . -type f -iname '*.jpg' | while read jpg; do
  git lfs migrate import --no-rewrite "$jpg"
done

Edit 1: side note about find

Above I utilize the bash find command to list files, but I could've also used git ls-files -- '*.jpg' to the same effect. (note: the case-insensitive pathspec would be ':(icase)*.jpg'.)

It might interest you to know that git ls-files is typically faster than the find command—significantly faster on certain operating/file systems (Windows NTFS 👀)—which might be desirable if you're dealing with a ton of files. Of course there is the general caveat that git ls-files (by default) only lists files that are tracked by the current Git repo, but in the context of this post that might actually be a good thing! I.e. It would prevent matching files in, say, submodules from getting mixed into LFS; find would not be able to differentiate.

Edit 2

More of a note, but git ls-files only lists files on the current index. These days I've been preferring git ls-tree -r --name-only $REV | grep '\.jpg$', where REV is a branch/tag/commit ref. It's longer, but much closer to what I was jimmy-rigging ls-files to be. (and yes, the pipe-to-grep is unfortunately necessary, as ls-tree does not support pathspec.)

For some reason, git ls-files still works and won't warn you if you pass a commit-ish argument, which misled me until I noticed and confirmed that it is indeed an ignored argument.

Upvotes: 1

derekhh
derekhh

Reputation: 5542

How I solved it:

git lfs migrate import --no-rewrite path

See: https://tech-notes.maxmasnick.com/fixing-files-that-should-have-been-pointers-in-lfs-but-werent

Upvotes: 4

Matthew van Boheemen
Matthew van Boheemen

Reputation: 1335

How I solved it:

  • Created a new branch
  • Took a copy of all the files
  • Deleted the ones listed that should have been pointers. Committed this change
  • Copied over the files to re-add them
  • Committed the new files to git (this then added them into LFS rather than the git repository)
  • Pushed the changes

Upvotes: 1

Related Questions