在常规Git下移动Git LFS跟踪的文件


74

我有一个项目,使用Git LFS存储视频文件。现在,我的构建服务器还不支持Git LFS,遇到了一些麻烦。由于它是一项外部服务,因此我无法真正影响构建过程,因此希望将文件从Git LFS下移回“常规” Git。我设法取消跟踪文件类型,git lfs untrack '<file-type>'git lfs ls-files仍然提供了以前添加的文件的列表。

我想我可以删除文件,推送更改,然后手动重新添加它们,但这真的是推荐的处理方式吗?

Answers:


96

我最近遇到了一个问题,在这个问题上,资产被意外地添加到了一个不应该添加到一个分支上的git-lfs中。我的解决方案是:

git lfs untrack '<file-type>'
git rm --cached '<file-type>'
git add '<file-type>'
git commit -m "restore '<file-type>' to git from lfs"

结果是用标准文件内容重写了git-lfs oid sha256指针。


(编辑2019-03):更改了可接受的答案,为更简单的情况提供了简单的解决方案。如果您手头有一个更复杂的案例,另请参阅VonC答案中编辑以获取替代解决方案。


4
通过.gitattributes正确设置以跟踪我想要的文件,此解决方案效果很好。比发布的其他一些解决方案简单得多。
Josh Rickert

这很棒。应该被列为真实答案。
阿迪亚

1
在18年为我工作。其他提示:“文件类型”为“ **。jpg”
oligofren

2
@OlliNiskanen很高兴被标记为已接受的答案,但我感到很重要的一点是要注意,尽管这是对所询问的特定问题的一种很好而简单的解决方案,但对于更复杂的情况,读者应咨询编辑建议的配料方法。 tstephens619和ttaylorr对VonC的回答。
mred

1
@mred,同意。我建议进行修改,以链接到先前接受的答案。这个答案被掩盖了,人们发现它很有帮助,所以我觉得这应该是访问者看到的第一件事。
Olli Niskanen

32

问题641提到了同一问题。

我试图停止使用Git LFS,但是找不到使用以下方法还原我以前跟踪的指针文件的方法 git lfs uninitgit lfs untrackgit rm...在我移动这些文件备份它仍然列出了与跟踪的Git的LFS git lfs ls-files,我怎么能退出整个LFS的Git回购中的内容?

答案是:

  1. 使用删除所有filter.lfs。* git config条目git lfs uninit
  2. .gitattributes通过git lfs untrack为每种文件类型运行来清除所有使用lfs过滤器的属性,或者.gitattributes如果您使用过LFS,则删除所有属性。

之后,所有添加的文件将直接转到git。

但这不是那么简单:

稍后,我将LFS指针文件保存在工作目录中,并且必须.git/lfs手动使用存储在这些指针中的sha1哈希来恢复所有图片。


2016年3月更新,问题957说明了一种可能的解决方案tstephens619以下方式:

我犯了同样的错误,在git lfs跟踪列表中包含了几种小型图形格式。
我可以通过执行以下操作将此文件移回git:

  • 创建当前被跟踪的所有文件的列表git-lfs,过滤出*.gz*.rpm(我仍然想使用跟踪这些扩展名git-lfs

    git lfs ls-files | grep -vE "\.gz|\.rpm$" | cut -d ' ' -f 3 > ~/temp/lfs-files.txt
    
  • 停止跟踪小图形文件

    git lfs untrack "*.tts"
    git lfs untrack "*.bfx"
    git lfs untrack "*.ttf"
    git lfs untrack "*.xcf"
    git lfs untrack "*.pkm"
    git lfs untrack "*.png"
    
  • 暂时取消初始化 git-lfs

    git lfs uninit
    # Git LFS 2.x+
    git lfs uninstall
    
  • 使用文件列表触摸每个文件:

    cat ~/temp/lfs-files.txt | xargs touch
    

git status 现在将显示每个已修改的文件

  • 将更改添加到git index(我通过这样做git gui

  • 提交更改,然后重新初始化git-lfs

    git commit
    git lfs init
    

维护者ttaylorr补充说:

一种方法是:

for file in $FILES_TO_REVERT; do
  git lfs untrack "$file";
  git rm --cached "$file";
  git add --force "$file";
done

git commit -m "..."

我倾向于不要向Git LFS添加命令以达到上述效果,因为Git和Git LFS提供的瓷器命令可能以多种不同的方式


3
感谢您从项目中找到正确的问题。尽管如此,即使此解决方案也需要手动移动文件。从Git到Git LFS的工作流程基本上是git rm --cached <file>-> git add <file>-> git commit,只要您正确设置了跟踪,似乎有点奇怪。
Olli Niskanen

@Klipi我同意:似乎未完成的方案仍然是完美的。
VonC

@Klipi很好。我会监视它。
VonC

2
我的LFS(2.0.2)版本没有uninit命令。而不是git lfs uninit我不得不使用git lfs uninstall
endavid

29

从Git 2.16(2018年1月17日发布)开始,您可以使用以下--renormalize标志轻松完成此操作git add

git lfs untrack '<pattern>'
git add --renormalize .
git commit -m 'Restore file contents that were previously in LFS'

Git的文档中

--renormalize:对所有跟踪的文件重新进行“干净”处理,以将其再次强制添加到索引中。更改core.autocrlf配置或text属性后,此功能很有用,以便更正添加了错误CRLF / LF行尾的文件。此选项暗示-u

这里的关键部分是“所有跟踪的文件”。通常,仅当Git操作更改工作树中的文件时才运行过滤器。更改LFS白名单.gitattributes不是Git操作,因此在您运行后,索引最终会处于不一致状态git lfs untrack。运行git add --renormalize .告诉Git对存储库中的每个文件重新运行过滤器,以确保应该在LFS中的所有文件都存在,并且应该不应该。


1
这种方法的好处是,如果您从过去或另一个分支结帐,则旧的lfs内容仍然存在。但是,展望未来,它不再使用lfs。我要添加的一件事是现在从.gitattributes中删除lfs内容(或者在我的情况下删除整个文件)并进行检查。
大卫·卡斯珀

1
应当注意,这不会更改历史记录,这意味着如果签出较旧的提交,则可能会得到指向LFS的指针,而不是实际文件。而且,如果此后移动了存储库或删除了LFS,则不会以这种方式恢复那些旧的大文件。
Thomas Tempelmann

2

我在Windows中执行步骤时遇到问题。要删除所有git lfs跟踪的文件并恢复原始文件,我在git bash中执行了以下操作:

  1. 删除了.gitattributes

  2. git lfs ls-files | cut -d ' ' -f 3 > lfs-files.txt

  3. 执行以下代码段:

片段:

while read file; do
  git lfs untrack "$file";
  git rm --cached "$file";
  git add --force "$file";
done <lfs-files.txt

-3

您无法真正从GIT LFS中删除任何内容,尽管此处介绍的解决方案可能有效(经过修改),但它们需要大量的工作,并且可能会对存储库产生副作用。

如果您到达这里,是时候问问自己是否要使用GIF LFS管理大型文件,以及GIT本身(由于它是分布式版本控制系统,对管理大型文件而言本质上很差)是否是一个不错的选择。

如果您有许多大文件,并且您是一个仅从事项目工作的组织,那么Subversion之类的方法可能对您更好。


2
@ericfrazer每次访问此问题都证明了我的观点,就像遵循GIT LFS的官方文档一样,从LFS中删除文件应该很容易。除非它不是,因为它不起作用。人们很挣扎,因为以下两种情况的结合:a)很难微调要添加的文件,以及b)在Windows上添加许多小文件存在性能问题,因为GIT LFS作为子进程运行,并且如果没有子进程就启动子进程很昂贵叉子()。底线:为了您自己的理智,在所有这些问题都解决之前,请不要使用LFS。多年没有发生过……
弗洛里安(Florian Winter)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.