【问题标题】:Converting git repository to shallow?将 git 存储库转换为浅层?
【发布时间】:2011-01-15 08:57:39
【问题描述】:

如何将已克隆的 git 存储库转换为浅存储库?

git 存储库是通过我无法控制的脚本下载的,因此我无法进行浅层克隆。

这样做的原因是为了节省磁盘空间。 (是的,我的磁盘空间真的很短缺,所以即使浅存储库不能节省太多,但还是需要的。)

我已经试过了

git repack -a -d -f -depth=1

但这实际上使存储库变大了。

【问题讨论】:

  • stackoverflow.com/questions/1398919/… 可以提供帮助。重新打包后,git gc 是什么?
  • huitseeker:感谢您提出这个问题。我知道这些限制,我可以接受。我需要访问最新的提交,或者最好是几个提交,仅此而已。
  • VonC:我现在正在做 gc --aggressive。我应该从中获得一些好处,但如果可能的话,我也想丢弃我不需要的对象。
  • 我刚刚遇到了progit.org/2010/03/17/replace.html,它提出了一个可能更简单的替代过程,涉及git commit-tree
  • git repack 中的--depth 参数与shallowing 无关:它是deltification 算法中的深度:--depth=1 表示我们希望deltification 为1,小于默认值50,因此压缩较少。

标签: git


【解决方案1】:

这对我有用:

git pull --depth 1
git gc --prune=all

这会留下标签和 reflog,每个标签和引用日志都会引用额外的提交,这些提交会占用空间。请注意,除非非常需要,否则我不会删除 reflog:它包含用于从错误中恢复的本地更改历史记录。

在下面的 cmets 中有关于如何擦除标签甚至是 reflog 的命令,以及指向具有更长答案的类似问题的链接。

如果您仍有大量空间使用,您可能需要删除标签,您应该在删除 reflog 之前先尝试。

【讨论】:

  • 嗯,对我来说,这给出了“致命的:git fetch-pack:预期的浅列表”。
  • @BenFarmer 那不好!由于浅层支持一直在缓慢发展,这可能仅适用于最新版本的 git。你有什么版本?
  • 我已经运行了上面的命令。回购现在确实很浅(git log 只显示一个提交,git branch 只显示一个分支)。但.git 文件夹仍占用 2.5 GB。使用--depth 1 克隆的相同存储库占用大约 1 GB。有什么建议可以减少磁盘使用吗?
  • 根据我的实验,git pull --depth=1 保留了非 HEAD 标签,git gc --prune=all 不会删除这些标签。我必须使用git tag -d $(git tag -l) 正确地垃圾收集这些参考。
  • 我发现上面的命令还不够,我也必须这样做:git reflog expire --expire=all --all 推荐在stackoverflow.com/questions/38171899/… 另外,上面的 git tag 命令也需要。跨度>
【解决方案2】:

您可以按照以下思路将 git repo 转换为浅层:

git show-ref -s HEAD > .git/shallow
git reflog expire --expire=0
git prune
git prune-packed

请务必进行备份,因为这是破坏性操作,还请记住,不支持克隆或从浅回购中获取!要真正删除所有历史记录,您还需要在修剪之前删除对先前提交的所有引用。

【讨论】:

  • 其实这个好像没什么作用。
  • hendry:很可能您没有删除指向 HEAD 历史的其他引用。在尝试执行此步骤之前,请尝试删除所有其他分支和标签。
  • 对于子模块,您可能需要将 .git 文件解析为 git 目录 (git rev-parse --git-dir)。此外,您可以使用 git describe --always HEAD~5 而不是 show-ref -s HEAD 来保留最新的提交。然后还有git fetch --unshallow同时取消克隆。
  • 为了删除所有引用,请在 reflog 命令中添加 --all: git reflog expire --expire=now --all
  • 请注意git prune 已经执行git prune-packed。另请注意,如果您希望存储所有分支,则它们都必须在.git/shallow 中列出它们的提示。这个命令对我有用,但我不知道它是否会一直有效:find .git/refs -type f | xargs cat | sort -u > .git/shallow
【解决方案3】:

从特定日期开始转换为浅:

git pull --shallow-since=YYYY-mm-dd
git gc --prune=all

同样有效:

git fetch --shallow-since=YYYY-mm-dd
git gc --prune=all

【讨论】:

    【解决方案4】:

    创建本地仓库的浅克隆:

    git clone --depth 1 file:///full/path/to/original/dir destination
    

    请注意,第一个“地址”应该是file://,这很重要。此外,git 将假定您的原始本地 file:// 地址是“远程”(“来源”),因此您需要更新新的存储库,指定正确的 git remote

    【讨论】:

    • 这对我有用。在我们的 CI 设置中,我想克隆出完整的 repo,以便从另一个分支应用补丁,然后尽可能缩小目录,因为它会被 TAR 化并存储。
    【解决方案5】:

    将@fuzzyTew 的答案与该答案的cmets 结合起来:

    git pull --depth 1
    git tag -d $(git tag -l)
    git reflog expire --expire=all --all
    git gc --prune=all
    

    想通过在整个磁盘上运行来节省空间吗? - 然后运行这个fd 命令:

    fd -HIFt d '.git' -x bash -c 'pushd "$0" && ( git pull --depth 1; git tag -d $(git tag -l); git reflog expire --expire=all --all; git gc --prune=all ) && popd' {//}
    

    或者只是普通的find:

    find -type d -name '.git' -exec bash -c 'pushd "${0%/*}" && ( git pull --depth 1; git tag -d $(git tag -l); git reflog expire --expire=all --all; git gc --prune=all ) && popd' {} \;
    

    【讨论】:

    • 这对我来说仍然无法使用 git 2.28.0 在我的 .git 中节省空间。
    【解决方案6】:

    请注意,浅存储库(例如使用 git clone --depth 1 将现有存储库转换为浅存储库的方法)可能会在 git repack 上失败。

    参见Johannes Schindelin (dscho)commit 5dcfbf5commit 2588f6ecommit 328a435(2018 年 10 月 24 日)。
    (由 Junio C Hamano -- gitster -- 合并于 commit ea100b6,2018 年 11 月 6 日)

    repack -ad: 修剪浅提交列表

    git repack 可以在没有进一步警告的情况下丢弃无法访问的提交, 使.git/shallow 中的相应条目无效,导致 加深分支时出现严重问题。

    git repack 丢弃无法访问的提交的一种情况是 当 git fetch --prune (甚至是 git fetch 时 同时强制推送)可以使提交无法访问 之前可以到达。

    因此,假设 git repack -adlf 将单独保留无法访问的提交是不安全的(假设它们一开始没有被打包,这是至少一些 Git 代码似乎做出的假设)。

    在查看 .git/shallow 文件:如果该文件中列出的任何提交变为 无法到达,这不是问题,但如果它们丢失,它 问题。
    这个问题的一个症状是,现在可能会加深获取 失败:

    fatal: error in object: unshallow <commit-hash>
    

    为了避免这个问题,当-d 选项被传递时,让我们修剪git repack 中的浅表列表,除非-A 也被传递(这将迫使现在无法访问的对象变成松散的对象被删除)。
    另外,我们还需要考虑--keep-reachable--unpack-unreachable=&lt;date&gt;

    注意:在审查此补丁期间讨论的替代解决方案 是教git fetch 简单地忽略.git/shallow 中的条目,如果 本地不存在相应的提交。
    然而,快速测试显示.git/shallow 文件是在浅clone 期间写入的,在这种情况下,提交也不存在,而是“浅”行 确实需要发送。
    因此,这种方法会比 this 补丁提供的方法更加挑剔。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-03
      • 2011-01-13
      相关资源
      最近更新 更多