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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35011366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 03:53:32  来源:igfitidea点击:

Move Git LFS tracked files under regular Git

gitgit-lfs

提问by Olli Niskanen

I have a project where I stored video files with Git LFS. Now I ran into some complications with my build server that doesn't yet support Git LFS. As it's an external service, I can't really affect the build process, and thus would want to move the files from under Git LFS back to "regular" Git. I managed to untrack the file types with git lfs untrack '<file-type>'but git lfs ls-filesstill gives a list of the files previously added.

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

I imagine I could remove the files, push the changes and then manually re-add them, but is this really the recommended way of doing things?

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

回答by mred

I have just recently run into this problem where assets were accidentally added to git-lfs on one branch that shouldn't have been. My solution was:

我最近遇到了这个问题,其中资产被意外添加到一个不应该添加的分支上的 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"

The result is a rewrite of the git-lfs oid sha256 pointers with the standard file contents.

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



(Edit 2019-03): The accepted answer was changed to provide an easy solution for simpler cases. See also the edits in the answer by VonCfor alternate solutions in case you have a more complex case on hand.

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

回答by VonC

Issue 641mentions the same issue.

问题 641提到了同样的问题。

I tried to stop using Git LFS, but found no way to revert my previous tracked pointer files using git lfs uninit, git lfs untrack, git rm... after I move those files back it still lists as tracked by Git LFS with git lfs ls-files, how can I opt out the whole Git LFS stuff from my repo?

我试图停止使用 Git LFS,但发现无法使用git lfs uninit,恢复我以前跟踪的指针文件git lfs untrackgit rm...在我将这些文件移回后,它仍然列出由 Git LFS 跟踪的文件git lfs ls-files,我如何选择退出整个 Git LFS我的回购中的东西?

The answer was:

答案是:

  1. Remove all filter.lfs.* git config entries with git lfs uninit.
  2. Clear any any attributes that use the lfs filter in .gitattributesby running git lfs untrackfor each file type, or deleting .gitattributesif LFS is all you ever used it for.
  1. 删除所有 filter.lfs.* git 配置条目git lfs uninit
  2. .gitattributes通过git lfs untrack为每种文件类型运行来清除使用 lfs 过滤器的任何属性,或者.gitattributes如果 LFS 是您曾经使用过的全部,则删除它。

After this, any added files will go straight to git.

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

But this was not so simple:

但这并不是那么简单:

I later end up LFS pointer files in my working directory and have to recover all my pictures from .git/lfsusing the sha1 hash stored in those pointers manually.

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



Update March 2016, the issue 957illustrates a possible solution by tstephens619:

2016 年 3 月更新,问题 957说明了一个可能的解决方案tstephens619

I made the same mistake of including several small graphics formats into my git lfstracking list.
I was able to move this files back into git by doing the following:

  • Create a list of all of the files currently being tracked by git-lfs, filter out *.gzand *.rpm(I want to still track those extensions with git-lfs)

    git lfs ls-files | grep -vE "\.gz|\.rpm$" | cut -d ' ' -f 3 > ~/temp/lfs-files.txt
    
  • Stop tracking the small graphics files

    git lfs untrack "*.tts"
    git lfs untrack "*.bfx"
    git lfs untrack "*.ttf"
    git lfs untrack "*.xcf"
    git lfs untrack "*.pkm"
    git lfs untrack "*.png"
    
  • Temporarily uninit git-lfs

    git lfs uninit
    # Git LFS 2.x+
    git lfs uninstall
    
  • Use the file list to touch each file:

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

git statuswill now show each file as modified

  • Add the changes to git index (I did this via git gui)

  • commit the changes and then re-init git-lfs

    git commit
    git lfs init
    

我犯了同样的错误,将几种小图形格式包含在我的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"
    
  • 暂时uninit 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
    


The maintainer ttaylorradds:

维护者ttaylorr补充说:

One way to do this would be:

一种方法是:

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

git commit -m "..."

My preference would be not to add a command to Git LFS to the above effect, since it is possible in a number of different way with the porcelain commands provided by Git and Git LFS

我的偏好是不向 Git LFS 添加命令以达到上述效果,因为使用 Git 和 Git LFS 提供的瓷器命令可以通过多种不同的方式实现

回答by Tom Hebb

As of Git 2.16(released Jan 17th, 2018), you can do this easily with the --renormalizeflag of git add:

从 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'

From Git's documentation:

Git 的文档中

--renormalize: Apply the "clean" process freshly to all tracked files to forcibly add them again to the index. This is useful after changing core.autocrlfconfiguration or the textattribute in order to correct files added with wrong CRLF/LF line endings. This option implies -u.

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

The key part here is "all tracked files". Normally, filters are only run when a Git operation changes a file in the work tree. Changing the LFS whitelist in .gitattributesisn't a Git operation, and so the index ends up in an inconsistent state after you run git lfs untrack. Running git add --renormalize .tells Git to re-run filters on every file in the repository, which ensures that all files which should be in LFS are—and that all files which shouldn't be aren't.

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

回答by Joker

I had problems doing steps in Windows. To remove all git lfs tracked files and restore original file I did the following in git bash:

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

  1. Removed .gitattributes

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

  3. Execute following snippet:

  1. 删除了 .gitattributes

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

  3. 执行以下代码段:

Snippet:

片段:

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

回答by Florian Winter

You can't really remove anything from GIT LFS, and although the solutions presented here may work (with modifications), they require a lot of effort and may have side effects on your repository.

您无法真正从 GIT LFS 中删除任何内容,尽管此处提供的解决方案可能会起作用(经过修改),但它们需要付出很多努力,并且可能会对您的存储库产生副作用。

If you arrived here, it is time to ask yourself whether you want to manage your large files with GIF LFS and whether GIT itself (which is inherently bad at managing large files, because it is a distributed version control system) was a good choice.

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

If you have many large files and you are a single organization working on your project, something like Subversion may work better for you.

如果您有许多大文件,并且您是一个组织在处理您的项目,那么 Subversion 之类的工具可能更适合您。