我们有以下历史
start master public
| | |
v v v
o---o-- ... --o---o---o
不幸的是,我们向包含一些敏感数据的 master
分支做了一些提交。我们在一个名为 public 的单独分支中对此进行了修改。现在我们想要“切断”public
分支,以便在 public
中获得一个完整和干净的“状态”,但没有通过 仍然包含的妥协历史部分主人
。换句话说,我们想要以下新历史:
start master
| |
v v
o---o-- ... --o---o
\
o <- public
现在检查 public
将导致与原始情况相同的工作树,但没有合理的历史细节。之后我们封存旧的 master
分支:将其重命名为 unsafe
并从新的 public
中创建一个新的 master
分支> 分支机构。通过这种方式,我们可以将旧历史保存在 unsafe
中,并且能够毫无顾虑地将 public
分支推向公众:
start unsafe
| |
v v
o---o-- ... --o---o
\
o---o-- ... --o <-- public
\ /
o-- .. --o-- ... --o <-- master
实现此目标的正确 git 命令是什么?
PS:当然我们可以 checkout start
,创建一个新分支并在那里提交public
分支的整个工作树。但必须有一种不同的、更奇特的 git 方式!
最佳答案
将所有公共(public)提交 merge 为一个提交(即将多个提交 merge 为一个,或完全删除单个提交等)的正确方法是使用 git rebase -i
。所以你要做的是(假设第一个提交有一个标签 start
正如你的图表所示):
git checkout public
git rebase -i start
出现一个编辑器窗口,您可以在其中编辑所有补丁的顺序
只需对所有补丁使用 squash
即可。保存该文件并关闭编辑器后,git
将根据要求重新组合您的补丁历史记录。当然,master分支根本不会改变它的历史。
要将您当前的 master 重命名为不安全的并在公共(public)上开始所有进一步的开发,我会这样做:
git checkout -b unsafe master # <- creates a new branch "unsafe"
git checkout master
git reset --hard public # <- forces master branch to point to public
如果您不创建 unsafe
分支,硬重置将丢失 master 中的所有提交,您将无法(轻松)再访问它们。因此,请确保您确实创建了该分支。
另一种方法是将 master
重命名为 unsafe
然后创建一个新的 master 分支:
git branch -m master unsafe # renames master to unsafe
git checkout -b master public # creates new branch master as a copy of public
两者都应该产生完全相同的分支结构。 (当然,第二个没有失去历史的危险......)
关于git - 将分支移动到历史上的另一个点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7254992/