【问题标题】:Move Git LFS tracked files under regular Git在常规 Git 下移动 Git LFS 跟踪的文件
【发布时间】:2016-05-02 20:52:54
【问题描述】:

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

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

【问题讨论】:

    标签: git git-lfs


    【解决方案1】:

    我最近遇到了这个问题,资产被意外添加到了一个不应该添加的分支上的 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):已接受的答案已更改,以便为更简单的情况提供简单的解决方案。如果您手头有更复杂的案例,另请参阅edits in the answer by VonC 了解替代解决方案。

    【讨论】:

    • .gitattributes 设置正确以跟踪我想要的文件,这个解决方案效果很好。比发布的其他一些解决方案要简单得多。
    • 这非常有效。应列为真实答案。
    • 18 年为我工作。给其他人的提示:“文件类型”是“**.jpg”
    • @OlliNiskanen 虽然很高兴被标记为已接受的答案,但我觉得重要的是要注意,虽然这是针对所提出的具体问题的一个很好且简单的解决方案,但对于更复杂的案例,读者应该咨询tstephens619 和 ttaylorr 在编辑中建议的批处理方法对 VonC 的回答。
    • @mred,同意。我建议进行链接到先前接受的答案的编辑。这个答案很隐蔽,人们发现它很有帮助,所以我觉得这应该是访问者看到的第一件事。
    【解决方案2】:

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

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

    来自Git's documentation

    --重新归一化: 对所有跟踪的文件重新应用“干净”过程以 强制将它们再次添加到索引中。这在之后很有用 更改 core.autocrlf 配置或 text 属性 为了更正添加了错误 CRLF/LF 行结尾的文件。 此选项暗示-u

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

    【讨论】:

    • 这种方法的好处是,如果你从过去或另一个分支结帐,旧的 lfs 东西仍然存在。但展望未来,它不再使用 lfs。我要添加的一件事是现在从 .gitattributes 中删除 lfs 内容(或者在我的情况下删除整个文件)并将其签入。
    • 应该注意的是,这不会改变历史,这意味着如果你检查一个较旧的提交,你可能会得到指向 LFS 而不是实际文件的指针。而且,如果您此后移动了 repo 或删除了 LFS,您将不会以这种方式取回那些旧的大文件。
    • 这种方法的坏处是它会触及所有文件,你最终会大量提交所有文件。
    • 双引号应该用于Windows命令行
    【解决方案3】:

    Issue 641 提到了同样的问题。

    我试图停止使用 Git LFS,但发现无法使用 git lfs uninitgit lfs untrackgit rm 恢复我之前跟踪的指针文件...在我将这些文件移回后,它仍然列为 Git 跟踪的带有git lfs ls-files 的 LFS,我如何从我的 repo 中选择退出整个 Git LFS 内容?

    答案是:

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

    在此之后,任何添加的文件都将直接进入 git。

    但这并不是那么简单:

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


    2016 年 3 月更新,issue 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 索引(我是通过 git gui 完成的)

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

      git commit
      git lfs init
      

    maintainer 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 提供的瓷器命令可以通过多种不同的方式实现

    【讨论】:

    • 感谢您从项目中找到正确的问题。尽管如此,即使这个解决方案也需要手动移动文件。当从 Git 到 Git LFS 的工作流基本上是 git rm --cached &lt;file&gt; -> git add &lt;file&gt; -> git commit 只要您正确设置了跟踪,这似乎有点奇怪。
    • @Klipi 我同意:似乎 untrack 场景仍然可以完善。
    • @Klipi 好电话。我会监控的。
    • 我的 LFS (2.0.2) 版本没有uninit 命令。而不是git lfs uninit,我不得不使用git lfs uninstall
    【解决方案4】:

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

    1. 已删除 .git 属性

    2. git lfs ls-files | cut -d ' ' -f 3 &gt; lfs-files.txt

    3. 执行以下 sn-p:

    片段:

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

    【讨论】:

    • -f 3 序列是什么?
    • @Francisco Maria Calisto 它将 git lfs ls-files 的结果拆分为空格并获取 3. 条目(即文件名)。有关cut -f的更广泛解释,请参阅unix.stackexchange.com/questions/122055/…
    【解决方案5】:

    编辑:在成功使用 GIT LFS 几年后,对该答案进行了多次赞成/反对投票,我认为这个警告仍然适用:GIT LFS 有很多缺陷,例如难以管理哪些文件应该在 LFS 中,在 Windows 上(意外)向 LFS 添加许多小文件时的性能问题,对多个远程和远程 URL 格式的支持有限,从 LFS 中删除文件困难,合并时可能遇到的各种问题等。 GIT LFS 是 GIT 中的一个外部元素,存在于修订树之外。但是,我想将我原来的警告改写如下:

    1. 仅将您通常会放入 GIT 的文件放入 GIT LFS(例如,您拥有并偶尔更改的“源文件”)
    2. 仅将大文件放入 GIT LFS。
    3. 如果您需要一个系统来管理二进制依赖项,请考虑改用包管理器。
    4. 不要使用 Subversion 作为 GIT LFS 的替代品。情况更糟。
    5. 准备好弄乱您的工作目录。在对 LFS 进行任何重大更改之前,请务必备份(推送)有价值的更改。
    6. 合并时,始终先合并.gitattributes

    编辑:这是我原来的答案:

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

    如果你来到这里,是时候问问自己是否想用 GIF LFS 管理你的大文件,以及 GIT 本身(它在管理大文件方面天生就不好,因为它是一个分布式版本控制系统)是否是一个不错的选择。

    如果您有很多大文件,并且您是一个单一的组织来处理您的项目,那么像 Subversion 这样的东西可能更适合您。

    【讨论】:

    • @ericfrazer 每次访问这个问题都证明了我的观点,按照 GIT LFS 的官方文档,从 LFS 中删除文件应该是轻而易举的事。除了,它不是,因为它不起作用。人们正在苦苦挣扎,因为a)很难微调要添加的文件和b)添加许多小文件在Windows上存在性能问题,因为GIT LFS作为子进程运行,并且启动子进程很昂贵叉()。底线:为了您自己的理智,在所有这些都修复之前不要使用 LFS。这已经很多年没有发生了......
    • 这个答案更像是一个vue点而不是一个答案,但是作为在大型二进制文件上使用GIT的问题代表,这看起来更像是一个警告,我投票给不要删除这个答案。
    【解决方案6】:

    我尝试并能够根据他们的官方文档成功使用以下命令将我的 repo 恢复为常规:

    git lfs migrate export --include="*.psd" --everything
    

    希望这对处于相同情况的任何人有用!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 2018-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 1970-01-01
      相关资源
      最近更新 更多