繁体   English   中英

将git repo的分支推送到新的远程(github),隐藏其历史记录

[英]Push a branch of a git repo to a new remote (github), hiding its history

我的组织正准备使用github发布我们软件的开源版本,但是我不确定解决这个问题的最佳方法:

我们有两个分支masterreleasemaster包含一些我们决定不发布的专有组件, release包含我们想要分发的清理版本。 问题是,如果我们只是将发布分支推送到github,可以通过查看修订历史来检索专有组件。

我正在考虑创建一个单独的存储库,将HEAD of relase复制到其中,执行git init ,并将该存储库推送到github。 但是,我们希望保留能够在未来从主服务器中挑选某些补丁到发布的能力,并将这些更改推送到github。

有没有办法在不维护两个separte存储库的情况下执行此操作?

谢谢!

更新:

更具体一点,这就是我们的提交历史目前的样子:

--- o - o - o - o - f - o - o - f - master
             \
              c - c - c - c - c - c - c - REL - f - f

'o'是master ,专有分支中的提交,'c'是提交,删除不应发布的内容(通常不会删除整个文件,但重新处理现有文件不依赖于专有组件),'f'是修复了适用于发布的 大师 ,因此被挑选出来。 REL是我们认为可以安全发布的代码的标记版本,没有任何历史记录(甚至以前版本的发布分支,因为并非所有专有材料都在REL标记之前被删除)。

本杰克逊的答案已经涵盖了一般的想法,但我想在这里添加一些关于最终目标的笔记(不仅仅是评论的价值)。

您可以很容易地拥有两个分支,一个具有完全干净(无私有文件)历史记录,一个完整(具有私有文件),并且可以适当地共享内容。 关键是你要如何合并。 过度简化的历史记录可能如下所示:

o - o - o - o - o - o - o (public)
 \       \           \   \
  x ----- x ----x---- x - x (private)

o提交是“干净的”, x是包含一些私人信息的提交。 只要您从公共合并到私有,它们都可以拥有所有所需的共享内容,而不会泄漏任何内容。 正如Ben所说,你需要小心这一点 - 你不可能以其他方式合并。 尽管如此,它仍然可以避免 - 而且你不必限制自己采摘樱桃。 您可以使用正常的所需合并工作流程。

实际上,当然,您的工作流程最终会变得复杂一些。 您可以在自己的分支上开发主题(feature / bugfix),然后将其合并到公共版本和私有版本中。 你甚至可以偶尔选择樱桃。 真的,任何事情都有,除了将私人合并到公众之外的关键例外。

过滤分支

所以,你现在的问题只是让你的存储库进入这种状态。 不幸的是,这可能非常棘手。 假设存在一些涉及私有和公共文件的提交,我认为最简单的方法是使用filter-branch来创建公共(干净)版本:

git branch public master   # create the public branch from current master
git filter-branch --tree-filter ... -- public    # filter it (remove private files with a tree filter)

然后创建一个临时的仅限私有分支,仅包含私有内容:

git branch private-temp master
git filter-branch --tree-filter ... -- private-temp    # remove public files

最后,创建私有分支。 如果您只有一个完整版本,那么您可以简单地合并一次:

git branch private private-temp
git merge public

那将只给你一个只有一个合并的历史:

o - o - o - o - o - o - o - o - o - o (public)
                                     \
  x -- x -- x -- x -- x -- x -- x --- x (private)

注意:这里有两个单独的root提交。 这有点奇怪; 如果你想避免它,你可以使用git rebase --root --onto <SHA1>将整个私有临时分支移植到公共分支的某个祖先。

如果您想要一些中间完整版本,您可以做同样的事情,只需在此处停止合并和变基:

git checkout -b private <private-SHA1>  # use the SHA1 of the first ancestor of private-temp
                                        # you want to merge something from public into
git merge <public-SHA1>           # merge a corresponding commit of the public branch
git rebase private private-temp   # rebase private-temp to include the merge
git checkout private
git merge <private-SHA1>          # use the next SHA1 on private-temp you want to merge into
                                  # this is a fast-forward merge
git merge <public-SHA1>           # merge something from public
git rebase private private-temp   # and so on and so on...

这会给你一个像这样的历史:

o - o - o - o - o - o - o - o - o - o (public)
      \              \               \
  x -- x -- x -- x -- x -- x -- x --- x (private)

同样,如果你想让他们有一个共同的祖先,你可以做一个初始的git rebase --root --onto ...来开始。

注意:如果您已在历史记录中进行合并,则需要在任何rebase上使用-p选项来保留合并。

假装

编辑:如果重新编写历史记录真的是难以处理的话,你总是可以完全捏造它:将整个历史记录压缩到一个提交,在你已经拥有的相同根提交之上。 像这样的东西:

git checkout public
git reset --soft <root SHA1>
git commit

所以你最终会得到这个:

o - A' (public)
 \
  o - x - o - x - X - A (public@{1}, the previous position of public)
               \
                x - x (private)

其中AA'包含完全相同的内容, X是您从公共分支中删除所有私有内容的提交。

此时,您可以将公共单独合并为私有,从那时起,按照我在答案顶部描述的工作流程:

git checkout private
git merge -s ours public

-s ours告诉git使用“我们的”合并策略。 这意味着它将所有内容保留在私有分支中,并简单地记录合并提交,显示您将公共分支合并到其中。 这可以防止git将提交X中的“删除私有”更改应用到私有分支。

如果根提交中包含私有信息,那么您可能希望创建一个新的根提交,而不是在当前提交之前提交一次。

提交的SHA基于提交blob,其中包括父SHA,提交文本和文件树的SHA。 树包含树中每个blob的SHA。 因此,任何给定的提交都依赖于该修订中的所有内容以及每个父修订版返回到空的存储库。 如果您从包含您不想发布的文件的版本(无论多么间接)派生​​提交,那么您不希望发布该分支。

git filter-branch第一个例子讨论了从存储库中删除机密文件的问题。 它通过创建备用历史记录(重写所有树和提交)来完成此操作。 如果你理解我的答案的第一部分,你可以看出为什么这一定是真的。

您应该能够运行filter-branch命令以从“干净”提交创建新提交。 历史将有些奇怪(旧版本可能无法构建,因为它们现在已不完整或以其他方式破坏)。 这不会破坏存储库中的任何现有分支或blob。 它将创建所有共享文件blob但不共享树或提交的新(并行)文件。 您应该能够安全地推送该分支而不暴露任何它不引用的对象(当您推送分支时,只有该分支命名的SHA及其依赖项被推送)。 但是,这会有一点风险,因为一个git merge到“干净”分支中,你最终可能会拖入“私有”分支和对象。 您可能希望使用钩子(提交或推送触发器)来仔细检查私有文件是否未转义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM