【问题标题】:How to mirror a git repository safely?如何安全地镜像 git 存储库?
【发布时间】:2013-04-06 20:24:57
【问题描述】:

我想用后台作业镜像一些 git 存储库。 git clone --mirrorgit remote update 不会保留未通过强制推送引用的对象,但我也想保留这些对象以防万一。是否有任何工具可以执行安全的 git 镜像?

【问题讨论】:

  • 正如我在问题中所说,git 会删除未被git push --force 引用的提交,不是吗? git remote updategit fetch在这方面的行为有区别吗?
  • 如果您关心未引用的对象,公共git API 很可能不会为您解决问题。在这种情况下,为什么不只是 rsync 回购?
  • 因为对于大多数存储库,例如在 GitHub 上,您没有 rsync 访问权限。
  • 对于公共存储库,您将无法获得您定义的“安全”备份。如果是专门做 github 之类的公共托管服务,可以结合使用 hooks 和自己的备份服务器来保持增量备份

标签: git


【解决方案1】:

这几乎是一个安全问题。如果您不小心推送了密码或其他内容,则可以修改您的提交并强制推送新的提交。之后 git 将不允许对第一次提交进行任何访问。

如果你真的需要这些提交,你需要访问文件系统并使用类似rsync 的东西来获取所有内容。 - 但请注意,git 有时会进行一些垃圾收集,因此旧的未引用提交实际上会丢失。

【讨论】:

  • 什么? git 会很高兴地让您访问原始提交;它现在可能被称为@{1}
  • 仅当该提交位于本地存储库中时。它不会让您访问远程存储库中任何未引用的提交。
  • 哦,我明白你的意思了。不过,我不认为这意味着 security 措施。如果它不能通过分支或标签访问,它就会被认为是垃圾。
【解决方案2】:

虽然缺少 shell 脚本会很乏味,但如果您可以访问远程存储库,那么您可以执行:

git fsck --lost-found

这将列出未引用的提交,然后您可以为每个提交创建一个分支:

git branch <branch-for-commit> <commit>

此时没有任何东西是未引用的,并且克隆不会 gc/丢失任何东西。之后,如果您选择,您可以删除分支,如Delete Branches

像这样:

git fsck --lost-found | \
  grep dangling | \
  awk '{ system ("git branch" " br-" $3 " " $3); }'

保留悬空提交和 blob。然后,在克隆之后,

git branch -a | grep "br-" | xargs git branch -D

【讨论】:

  • 这仅适用于本地存储库。无法在 github 等远程存储库上运行 git fsck
  • 是的,这就是为什么我说'如果你可以访问远程存储库'。
【解决方案3】:

我认为您可以采用两阶段备份:

  1. git fetch &lt;remote&gt; +refs/*:refs/* 更新裸镜像存储库。

    git gc 可能“规范化”其内容。

  2. rdiff-backup 将结果保存到另一个目录,该目录将包含最后备份的版本以及可用于重建任何先前备份的二进制差异文件集合。

通过这种方式,您可以获得备份快照的版本化历史记录。由于rdiff-backups 允许丢弃旧快照,因此您可以只记录您认为合适的快照数量。

缺点是浪费磁盘空间:

  • rdiff-backup 将制作源目录的真实副本;不会共享任何文件。
  • AFAIK,处理包文件的 Git 内部不支持gzip 程序的--rsyncable 命令行选项,因此rdiff-backup 生成的增量可能很大。另一方面,在一个典型的 Git 存储库中,任何包文件都应该只被附加,而不是重写,所以我可能在这里找错了树。

【讨论】:

    【解决方案4】:

    在重新阅读问题和提供的答案后,我确定我误解了发帖者的意图。

    现在我认为需要在目标存储库中启用 the reflog,方法是将其中的 core.logAllRefUpdates 设置为 true,并可能调整控制 reflog 过期策略的相关参数(grep git-config manual page世界“reflog”)。这将记录所有允许回滚强制推送等的“剧烈”参考重新定位。

    请注意,对于您所说的“黑客攻击”或任何其他类型的损失,唯一真正的保护仍然是获得安全的异地备份,所以我认为我在第一个答案中提出的建议,仍然成立。

    【讨论】:

      【解决方案5】:

      如果您要提取到您控制的存储库,gc config items 可以控制删除内容和时间的各个方面; git remote update(以及其他所有内容)保留未引用的对象,只要您愿意。任何具有管理权限的人都可以通过标记未引用的对象来发布它们。

      因此,为了安全地镜像存储库,如果您对它具有管理控制权,只需设置一个挂钩即可将传入的推送转发到永不过期的备份存储库。否则,关闭提交通知的接收将确保您记住您曾经可能看到的所有内容。

      【讨论】:

        【解决方案6】:

        我认为其中一位评论者说得对:rsync 或等效项是您唯一的朋友,尽管它不是例如的选项。 Github。

        看到这个(诚然旧的)线程:

        http://kerneltrap.org/mailarchive/git/2007/8/28/256180/thread

        引用其中一条消息:

        这与 Linux 开发实践无关。有 我们不获取钩子的根本原因:

        • 它们不是存储库的一部分;看看 .gitattributes-in-the-index-but-not-worktree 问题找出原因,

        • 它是 私有 数据,就像配置一样。客户有没有 业务阅读它们,更不用说获取它们了,

        • 如果你在不同的机器上有钩子,你很可能需要一个 更新钩子的机制......这自然建议将 挂钩到他们自己的分支。

        可能还有更多的理由不允许进行抓取之类的事情 钩子。

        所以...如果您想将钩子部署在多个位置,那么将钩子放在他们自己的仓库中是一个很好的解决方案,但除此之外,就我所知,对于各种对象,您无能为力在回购中...

        (该链接的致谢:https://stackoverflow.com/a/6154010/417194

        特别是对于 github,可能有 github-services 或 web hooks 的变通方法。

        【讨论】:

          猜你喜欢
          • 2013-08-01
          • 2013-01-29
          • 2021-01-17
          • 2015-07-16
          • 2012-08-14
          • 2021-09-18
          • 2011-02-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多