如何禁用 git-lfs?

问题描述 投票:0回答:6

我在 bitbucket 上有一个使用 LFS 的存储库。由于使用了一段时间,我决定将存储库移回我控制的空间。我首先使用 LFS 的唯一原因是有效地将我的存储库大小限制加倍(因为 LFS 中的文件位于单独的存储桶中),但现在我正在移动它,我不再需要这样做。

我需要一种方法来遍历整个 git 历史记录,删除 git LFS 所做工作的所有痕迹(以便所有文件都“正常”提交)。完成此操作后,我打算强制推送到新存储库。

我做了相当多的搜索,并遇到了建议的解决方案,但我不明白如何实现/运行它们,因为它们是高级的。

如何告别 git LFS?

git git-lfs
6个回答
60
投票

仅更新当前提交

如果你想移除 LFS,但不太担心修复整个 git 历史记录,你可以执行以下操作;

git lfs uninstall
touch **/*
git commit -a

这将卸载 LFS 支持,触摸每个文件(以便 git 识别出文件已更改),然后将它们全部提交。如果您愿意,可以更具体(例如,

**/*.png
)。请注意,使用
**
需要启用扩展的 glob 支持(bash 上的
shopt -s globstar

更新整个历史记录

这对我有用 - 但它会引发很多错误(我认为对于文件尚未添加到 LFS 的每个提交,我都会收到一个错误)并且需要很长时间(每个提交大约 2-3 秒)提交)。

git lfs uninstall
git filter-branch -f --prune-empty --tree-filter '
  git lfs checkout
  git lfs ls-files | cut -d " " -f 3 | xargs touch
  git rm -f .gitattributes
  git lfs ls-files | cut -d " " -f 3 | git add
' --tag-name-filter cat -- --all

它会卸载 git LFS 支持(理论上可以防止 LFS 弄乱索引),然后对于每次提交,它都会确保正确检出 LFS 文件,然后触及所有文件(因此 git 意识到它们已更改),删除找到的 LFS 设置在

.gitattributes
中,这样克隆时就不会一直尝试使用 LFS,然后将真实文件添加到索引中。

完成上述操作后,您需要用力推动。当然,这会让处理您的存储库的其他人陷入分离的状态 - 因此在代码冻结期间这样做是明智的。之后,让每个人都进行新的克隆可能是最简单的。


48
投票

git lfs migrate export

来自

git lfs migrate help

导出

export模式将 Git 历史记录中存在的 Git LFS 指针文件迁移出来 Git LFS,将它们转换成相应的目标文件。

工作流程示例

  1. 使用
    git lfs ls-files
    验证您确实拥有 LFS 文件。
  2. 从存储库中的所有
    filter=lfs
    文件中删除所有
    .gitattributes
    行。
    .gitattributes
    可以生活在任何地方,因此请确保找到所有它们,否则这可能会导致以后出现迁移问题。
  3. 提交您对
    .gitattributes
    所做的任何更改。
  4. 使用
    git status
    确保您没有任何更改。
  5. 运行迁移:
    git lfs migrate export --everything --include .
  6. 运行
    git status
    以确保您没有任何更改。如果您将
    .gitattributes
    保留为
    filter=lfs
    ,您现在可能会错误地进行更改。
  7. 使用
    git lfs ls-files
    验证之前列出的所有 LFS 文件均不再存在。
  8. 检查文件(例如,打开以前的 LFS 文件以确保它们没有损坏)并运行您的构建以确保一切正常。

小贴士

  • 在区分大小写的文件系统上运行,以防在某些时候发生文件系统冲突(例如 ./LICENSE 和 ./License)。
  • 从所有
    filter=lfs
    中删除所有
    .gitattributes
    行。
  • 您可能还想删除
    .git/hooks
    目录中的 LFS 保留:预提交、提交后、签出后、合并后。
  • 有了
    $GIT_TRACE=1
    就应该没有
    ...trace git-lfs: filepathfilter: accepting...
  • 的迹象

3
投票

对于特定文件

  1. .gitattributes
  2. 删除文件/模式
  3. 转到文件目录并运行
    touch myfile.bin
  4. 提交并推送更改

1
投票

根据Shadow的回答,我稍微修改了整个历史更新。 对于那些不想保留 LFS 文件的人(就我而言,我没有保留,因为它们会很大)。

用途:

GIT_LFS_SKIP_SMUDGE=1 git filter-branch -f --prune-empty --tree-filter '
  git lfs checkout
  git lfs ls-files | cut -d " " -f 3 | xargs rm -f
  git rm -f --ignore-unmatch .gitattributes
' --tag-name-filter cat -- --all

当提交中不存在 .gitattributes 时,它也不会失败,在我的情况下,这对于所有提交来说都是不正确的。

此外,存储库没有将原始 LFS 文件存储在远程,因此使用 GIT_LFS_SKIP_SMUDGE=1

这样,存储库不包含任何 LFS 引用和文件,这使得克隆存储库更快、更轻——这就是我的目标。无论如何,大文件用于测试,但由于代码已经改进了很多,运行那些旧的测试是无关紧要的。


1
投票

我编写了一个脚本,可以从 git 存储库中完全删除 lfs。警告 - 它会重写您的历史。

#!/bin/zsh

git lfs install
git lfs fetch --all
git lfs checkout

lfs_dirs=()

echo "finding lfs files"
for lfs_file in $(git lfs ls-files | sed -r 's/^.{13}//'); do lfs_dirs+=($(dirname "$lfs_file")); done;

echo "found all lfs files"

unique_dirs=()
for unique_dir in ${(u)lfs_dirs}; do unique_dirs+=("$unique_dir/*"); done;

count=${#unique_dirs[@]}

if (($count == 0))
then
echo "No lfs dirs"
exit 0
fi

echo "There are $count unique lfs dirs"

printf -v migrate_paths ',%s' "${unique_dirs[@]}"
migrate_paths=${migrate_paths:1}

echo "performing: git lfs migrate export --include='$migrate_paths' --yes --verbose --everything"
git lfs migrate export --include="$migrate_paths" --yes --verbose --everything
git lfs uninstall

0
投票

我想在@Doug Richardson 的回答中添加一条注释。 不知道为什么,但

git lfs migrate export --everything --include .
对我不起作用。

然后,我发现@simon-the-shark在这个git-lfs问题帖子中的答案是有效的。

这是他建议的 git 命令。

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

© www.soinside.com 2019 - 2024. All rights reserved.