git lfs pointer 报错解决
1. 问题说明
在git管理中,有时候会遇到下面的报错:
1 | Encountered 1 file that should have been a pointer, but wasn't: |
或像下面这样:
1 | Encountered <n> files that should have been pointers, but weren't: |
调查一番后发现,这种报错的核心原因是本应该用Git LFS管理的文件,直接被git来管理了。报错中提到的pointer ,实际上指的就是Git LFS 格式的文件,它不包含完整的数据,而只是一个指向完整数据的指针。
知道这个原因后,解决方法也很简单,而且git lfs v2.2.1 及以后版本提供了git lfs migrate 命令,专门来处理这种情况,也就是将Git管理的文件迁移到用Git LFS来管理,例如,如果已经有一个可以track *.mp4
二进制文件的.gitattributes
配置,使用下面的命令可以将所有mp4文件转换为用Git LFS来管理:
1 | git lfs migrate import --include="*.mp4" |
执行完这个命令后,还需要用下面的命令清理.git 目录,将缓存的object数据去掉:
1 | git reflog expire --expire-unreachable=now --all |
2. 为什么会出现这种错误
我自己的经验中,最常出现这种情况的原因是,Xcode中添加文件到工程,Xcode自动添加文件到Git管理中,但没有遵循.gitattributes
文件中的规则,将本来应该用Git LFS管理的文件格式直接提交到Git了,所以出现冲突。
另外一种情况是git lfs 配置项被临时禁用,导致添加某些文件的过程中lfs 机制没有生效,下面是这种情况的一个完整复现例子,实际中出现的可能性不大:
1 |
|
这个脚本中,git config --local filter.lfs.process
和git config --local filter.lfs.required false
就是关掉LFS作用的两条命令。
3. git lfs 的调试命令
在调查问题的过程中,也发现了更多的git lfs的命令,这里也列出来,调试问题的时候时有用的。
git lfs status
会列出当前lfs文件的修改,包括已经git commit
提交的,已经git add stage
但没git commit
提交的,和没有git add
处于unstaged
的所有lfs 文件。
git lfs pull
会拉取原始的文件,这条命令可以重新拉取git clone
时没有拉取的文件。
git lfs ls-files
会列出所有用git LFS 管理的文件,调试很有用。
git lfs fsck
命令会检查用Git LFS管理的文件是否正常,像上面遇到的问题,用这个命令就能很容易测试出来。--objects
选项只检查对应的object对象,而--pointers
只检查对应的pointer文件。
4. 参考资料
除了上面提供的解决方案外,还有一些解决方法,但可能会需要--hard
提交,有危险性,这里就不列出来了 ,具体可以在下面的参考资料中找到。