【问题标题】:Delete or remove all history, commits, and branches from a remote Git repo?从远程 Git 存储库中删除或移除所有历史记录、提交和分支?
【发布时间】:2013-08-09 09:28:54
【问题描述】:

我已经阅读并尝试了很多 Git 命令建议和讨论,现在已经持续了几天。似乎真的没有简单、全面的方法来让远程 Git 存储库完全清空——没有分支、没有引用、没有对象、没有文件、没有任何东西

是的,我知道可以删除并重新创建存储库——如果有人对源具有这种权限(我没有),但这不是重点。它是如何完成的? Git 命令的哪种组合实际上会做到这一点,让 repo 处于原始状态准备好接收我们希望推入其中的任何内容,并且 基本上没有大小(或处女回购)

不要告诉我不应该这样做,或者我们必须通知所有用户等。我知道这一切。 我只想重新开始

【问题讨论】:

  • 你可以删除并重新创建它吗?
  • 可以使用更多上下文。为什么不能强制将更改推送到远程仓库?你为什么还要这样做?另外,您到底尝试过什么?为什么您没有管理远程仓库的权限?远程仓库托管在哪里?请详细说明!
  • @Stabledog 你能从远程仓库中删除分支吗?你用什么命令来克隆它?您使用什么确切命令来强制推送。再次,请详细说明!
  • @Stabledog 悬空提交可以被垃圾收集,但如果你不控制远程仓库,那么垃圾收集可能取决于你的远程主机。此外,您可以删除标签。你是如何在历史中“寻找标签”的?你使用什么命令?此外,当您从远程克隆时,我怀疑是否获取了悬空提交,应该获取的唯一提交是那些可以从引用/分支访问的提交。另外,您是否收到任何错误消息

标签: git


【解决方案1】:

您可能想尝试使用 --mirror flag(强调我的)推送一个空的本地存储库:

--mirror

不命名要推送的每个 ref,而是指定将 refs/ 下的所有 ref(包括但不限于 refs/heads/refs/remotes/refs/tags/)镜像到远程存储库。新创建的本地 refs 将被推送到远端,本地更新的 refs 将在远端强制更新,已删除的 refs 将从远端移除。如果设置了配置选项remote.<remote>.mirror,这是默认设置。

如果您的 repo 在 GitHub 上,如果在尝试推送时将 master 设置为默认分支,您将收到此错误:

$ mkdir practice; cd practice;
$ git init; git remote add origin git@github.com:user/practice.git;

$ git push origin --mirror
remote: error: refusing to delete the current branch: refs/heads/master
To git@github.com:user/practice.git
 ! [remote rejected] master (deletion of the current branch prohibited)
error: failed to push some refs to 'git@github.com:user/practice.git'

我通过进行初始提交然后推送来解决这个问题。

强制警告:当然,这会彻底清除远程仓库中的所有历史记录和提交——所有引用、所有分支、所有标签等。确保这确实是你想做。当然,您始终可以在执行此操作之前对远程存储库进行备份克隆,以防您出于任何原因想要保留它。

还请注意,实际上不会立即删除任何提交。它们只会变成 dangling 提交,这意味着它们无法从分支访问。最终它们会被 Git 存储库收集垃圾,但如果您可以访问远程存储库,则可以使用 git gc 手动启动垃圾收集。

【讨论】:

  • 太棒了...成功了,并且具有正确解决方案的优雅简单性! (我还必须添加一个简单的提交)。谢谢!
  • 来自 (stackoverflow.com/a/18116141/237059) 的后续跟进。我在本地进行了实验,发现使用 --mirror 推送实际上并没有缩小原始存储库:磁盘使用情况相同,但不再可访问历史记录,并且当重新克隆该存储库时,克隆很小。所以效果产生了我实际需要的东西......我真的不在乎一个原本无法访问的来源正在消耗更多的磁盘空间。但这仍然是一个令人惊讶的结果。
  • @Stabledog 管理远程仓库(例如,您的仓库托管服务提供商)的人很可能最终会运行 git gc(垃圾收集),这将删除所有悬空提交(提交'无法从分支/引用访问),因此远程上的磁盘使用量最终将缩小到类似于本地克隆的磁盘使用量。这是我在this comment 中提到的。
  • 是的,对不起……我对这个问题的挫败感导致了阅读障碍。我现在正在康复中。
  • 这似乎是一个错误的答案,因为在这样做之后,历史中会有一个实际的提交。有没有办法在真正没有提交的情况下做到这一点? (没有提交我的意思是在服务器端没有提交,因此具有历史记录的推送不会由于单个不匹配且没有内容的初始提交而被拒绝)
【解决方案2】:

你不能这样做。您可以做的最好的事情是删除所有 refs 并希望服务器运行 git gc 并为没有任何 refs 的 prune 对象设置设置。这取决于服务器配置。

通常需要 14 天才能被 git gc 删除对象。但是,如果您尝试克隆存储库,则不会克隆这些对象。

您已经很好地回答了如何“破解”以删除所有引用。它可以工作,并且您的回购将出现在您面前,因为它是“新鲜的”。然而事实并非如此。

【讨论】:

  • 其实是可以做到的,而且比我根据提示尝试的所有复杂过程都要简单得多:只需创建一个空仓库,指定来源,然后做一个“git push --mirror”。砰……遥控器是一个新的、空的、很小的仓库。
  • 正如我想说的,它不是空的,它仍然有对象。但是,当您克隆该存储库时,您只会获得对其具有引用的对象。因此,您的 repo 克隆将不包含任何旧对象,但在服务器端它们仍然存在。
  • 这意味着什么?我已经克隆了新的服务器存储库,它现在确实很小而且很空。我尝试过的任何其他方法都没有做到这一点。我已经尽我所能查看服务器存储库,它似乎没有任何内容。那么那里怎么会有东西呢?据我所知, --mirror 选项的行为似乎与 .git 树的二进制副本完全一样——正是我想要的。
  • 你的克隆很小,你的服务器仓库不是空的,它仍然包含对象。克隆只为您提供可从 ref 访问的对象。如果您使用例如du -sh .git 检查服务器存储库,您会发现它比您克隆的存储库大。 --mirror 同步你的引用,而不是你的对象。
  • 好的。作为一名 Subversion 专家,某些 git 概念似乎很奇怪……就像人们会使用与垃圾收集相关的引用超时的概念。它动摇了整个“混凝土和钢的源代码控制”美学!
猜你喜欢
  • 1970-01-01
  • 2014-11-20
  • 2016-03-13
  • 2012-12-14
  • 2013-05-06
  • 2014-05-05
  • 2015-06-04
  • 1970-01-01
  • 2019-03-17
相关资源
最近更新 更多