Git:主复位后分支会发生什么

fre*_*etz 6 git git-reset

假设我有一个master分支,其中包含一些提交,我希望保留这些提交以供以后的文档和参考,但是将它们从master删除(因为我希望master与上游回购处于相同状态)。

我现在的方法是

  1. 从当前主状态创建一个新分支
  2. 重设(--hard)主机到上游仓库中的状态

现在,我的问题是:

  • 从主服务器删除引用提交后,新分支会发生什么?
  • 还是在理解如何引用分支方面我完全错了。

通常以以下方式显示分支,其中(据我所知)D是新分支的基础。

A - B - C - D    (master)
             \
                 (new branch)
Run Code Online (Sandbox Code Playgroud)

分支是自动“重新设置基础”的,还是您将如何称呼它?然后看起来像这样吗?

A - B         (master)
     \
      C - D   (new branch)
Run Code Online (Sandbox Code Playgroud)

最后也是最普遍的问题:

  • 我将状态保留在新分支和reset --hard主分支中的方法是否正确实现了我的目标,即在B不合并提交(CD)的情况下使派生回到上游状态(commit )的正确方法?

Rom*_*eri 6

分支不会“发生”任何事情,因为 git 中的分支只是一个轻量级的、可移动的、一次性的指针。提交是真实的。

是的,总体计划是好的,创建一个新分支以保留最近的提交,将 master 重置到它应该的位置(我猜origin/master),并且您的 C、D 提交上的这个 ref将允许它们永久保留

如果不创建分支,它们最终会被垃圾回收,即使它们会在reflog 中停留一段时间。

而且不,如果您遵循您宣布的行动方案,您的 C 和 D 提交将不会合并到您的上游master 中。去吧。


Mar*_*ger 5

从 master 删除引用提交时,新分支会发生什么?

没有。

您的问题似乎是基于对分支是什么的误解。分支是一种 ref - 与其他 ref 的不同之处仅在于 git 有一些关于分支指向何处以及它们如何移动的约定。ref 是指向提交 [1] 的指针。

重置时master,您只是更改了作为masterref的指针,使其停止指向D并开始指向B。这不会new branch以任何方式影响作为ref的指针。

提交CD仍然存在并且也不受重置的影响master。只是master不再指向可以“到达”的地方(而之前D可以到达,因为它是master指向的,并且C可以通过D父指针到达)。

但是new branch仍然指向D,所以它仍然可以到达CD

所以new branch不是重新定位或任何东西。变基是重写和替换提交,因为您希望相对于不同的起点进行相同的更改。这不会发生在这里。它是重新定位的提交,并且通常在重新定位提交时,引用会随之而来;但是当我们说“rebase 一个分支”时,这是“rebase 当前可从分支访问的一些提交,然后移动分支以指向新提交”的简写。但在这里我们不需要任何这些;我们仍然有我们的原始提交。

“分支的另一面只是一个指针”——提交不是任何分支的“一部分”。它们独立于任何可能引用它们的分支而存在(尽管git gc如果它认为没有人知道如何再找到它们,最终会尝试处理它们)。分支指向的提交,以及可以通过父指针从那里到达的提交,被认为构成了分支的历史......但就关系而言,仅此而已。

所以重申和总结 - 重置master 只会移动一个指针。它不会更改提交,也不会影响其他分支。


[1] 一些引用偶尔会指向提交以外的其他内容,但这对本次讨论来说并不重要;tl;dr - 分支是指向提交的指针,仅此而已