git - 将分支移动到历史上的另一个点

标签 git branch

我们有以下历史

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/

相关文章:

git - 任何使用浏览器内代码编辑器(如 Google Code)托管的项目?

git - 与其他版本控制系统相比,git checkout 有多贵?

git - 我所在的文件夹在 git 中有什么意义吗?

git - 可视化 git 分支依赖

database - 有没有支持分支的数据库?

git - 找不到 Composer 包

git - 显示差异包含特定字符串的所有提交

python - Ubuntu 上的 Django、Pyenv 和 Git 文件结构

哈希上的 Ruby case 语句?

assembly - 为什么 ASM 6502 中的条件分支有 128 字节的限制