是否有一种规范的方法可以追溯地将 git 回购拆分为 public 和私有变体?

Is there a canonical way to retroactively split a git repo into a public and private variant?

我有一个 git 存储库,其中包含一些敏感数据可能被硬编码或正式硬编码并且现在位于 git 历史记录中的某些点的文件。

为了使该项目 public 可用,以便具有相似兴趣的程序员可以从中受益并贡献更改,我想分叉它并清理有问题的文件。

我考虑的程序如下:

  1. Shallow/Shared 将 repo 本地克隆到新的本地位置,此文件夹将成为 public 变体。后续步骤在新的 repo 中。
  2. 将master分支成一个分支public-master
  3. 删除所有其他分支引用。
  4. 消毒 public-master
  5. 壁球 public-master
  6. git reflog expire --expire-unreachable=now --all && git gc --prune=all --agressive 删除所有无法访问的引用,现在是任何不在 public 分支中的对象
  7. git push 将 public master 添加到私有存储库的上游。
  8. 将 origin remote 设置为 public repo url,分支到 master。推送到原点。

这是否足以清理我的存储库,或者在此之后是否有可能恢复敏感数据。有没有更明智和通用的方法来解决这个问题?是否有任何步骤是多余的?

例如,我可以在一个存储库中完成这一切吗,或者 git-packs 的性质是否意味着我可能仍会推送包含敏感信息的 obj

The only problem is I want to be able to pull from the private repo, and then they would have unshared history.

这似乎是不可避免的,因为您已经更改了分支历史并将其压缩。

我不会从新的 public 回购中提取,而是简单地考虑对新回购克隆所做的更改,然后决定我要将哪个添加到旧私有回购的本地克隆中:

# update local content of new repo
cd /path/to/public/repo 
git pull

# check what needs to be added
cd /path/to/clone/of/old/repo
git --work-tree=/path/to/public/repo add -p .

您会看到新旧之间的差异,来自 public 存储库中可能发生的新演变。

结合@VonC 和@b-fg 的回答我认为最明智的解决方案如下。 观察到很容易用可能包含敏感日期的 objs 污染新的 public 存储库,而是构建一个新的 public 存储库。

  1. 将私有存储库分支到 public
  2. 消毒public
  3. 为 public 初始化新的回购协议。
  4. git --work-tree=/path/to/private add -p . 使用 public 索引导致 git 到 运行 但经过私有清理的工作树。 public 存储库现在已上演所有经过清理的分支的工作树,因此 git commit.
  5. 本地存储库在索引中有来自清理分支的工作树,但没有工作树,换句话说,它看起来 git 当前工作树中的所有内容都已从指数。使用git reset --hard
  6. 恢复”文件到新仓库的工作树
  7. 切换回私有存储库并将 public 存储库添加为远程。 git remote add public file://path/to/public/repo
  8. 历史 private/publicpublic/master 现在不相交。所以我们需要将它们嫁接在一起。使用 git branch -u public master 设置 private/public 的上游现在拉取允许不相交的历史 git pull --allow-unrelated-histories
  9. 将 public 分支设置为只能读取,但不能写入更改,以防止意外污染 public repo git remote set-url public --push "This Branch is Read-Only"

现在只在 public 存储库中添加新功能,并根据需要将它们拉回私有存储库。