Git-重新附加到主分支机构

时间:2018-10-15 10:45:19

标签: git branch git-branch

我从branch-1创建了一个分支master,然后在上面进行了一堆提交,然后面对从那里分支出来的两个选项,并在原始分支{{1 }},其中一些在新分支branch-1上。

原始分支branch-2上的提交被证明是一个死胡同(第二个分支之后的提交),但分支branch-1上的提交却被保留了。

是否有办法摆脱第一个分支branch-2并仅保留具有完整历史记录的第二个分支?

1 个答案:

答案 0 :(得分:1)

重要的是要意识到,在Git中,分支机构并非历史。 提交是历史。 (并且没有文件历史记录,只有提交。)请注意,每个提交都有一个“真实名称”,即其哈希ID,即丑陋的字符串,包含40个十六进制字符,例如f84b9b09d40408cf91bbc500d9f190a7866c3e0f

每个提交都存储源树的完整快照以及一些元数据。在这里,元数据是更有趣的部分。提交中的元数据包括:

  • 您的姓名和电子邮件地址以及时间戳;
  • 您的日志消息;和
  • 其前身或 parent 提交的哈希ID。

在特定情况下,最后一项是最重要的。如果我们使用一个大写字母作为大型丑陋哈希ID的替代,我们可以绘制如下提交:

... <-F  <-G  <-H

其中H最后提交。提交H会记住G的哈希ID,因此我们说H 指向 G。同时G记住其父项F,因此G指向F,它指向E,依此类推。

存储库中的历史记录。进行 new 提交包括让Git冻结源代码树,添加日志消息等,并提供新的哈希ID I。新的提交I将存储H的哈希ID:

... <-H  <-I

现在,历史记录的提交时间更长。

但是:我们怎么知道链中的 last 哪个提交?在这个简化的示例中,使用大写字母很明显,但是使用真正的哈希ID(似乎是随机的)却不是。实际上,只有蛮力地“列出每一次提交,看看哪一个是最后一次”才能发现。因此,Git为我们提供了分支名称,这可以帮助弱小的人(以及Git本身,因为它也不那么聪明)找到 last 提交:

...--F--G--H   <-- master

变为:

...--G--H--I   <-- master

我们进行新的提交之后。

尽可能简单地放置一个分支名称仅指向我们和Git应该将其视为 last 提交的(包含其哈希ID)那个分支。

这意味着当您创建一个新分支时,您会选择一些现有的提交,并告诉Git在其上添加另一个名称:

...--F--G--H   <-- master, branch1

现在,Git需要一种方法来知道要使用哪个分支名称,因此我们让Git将特殊名称HEAD附加到以下两个名称之一:

...--F--G--H   <-- master, branch1 (HEAD)

当我们进行新的提交时,Git会更新附加了HEAD名称 ,如下所示:

...--F--G--H   <-- master
            \
             I   <-- branch1 (HEAD)

请注意,提交H是主站的提示,也是 在分支branch1上。

如果您创建其他名称,只需在其指向的任何地方绘制即可。如果它指向H,则将其指向H。如果它指向I,例如branch1,则指向I。然后添加一些提交,更新附加到名称HEAD的那个

             J--K   <-- branch2 (HEAD)
            /
...--F--G--H   <-- master
            \
             I   <-- branch1

或:

...--F--G--H   <-- master
            \
             I   <-- branch1
              \
               J--K   <-- branch2 (HEAD)

或其他。

让我们说,我们现在有:

...--F--G--H   <-- master
            \
             I--L--M--N   <-- branch1 (HEAD)
              \
               J--K   <-- branch2

删除一个分支(名称)仅表示删除该名称 commits 保持不受干扰-进行一次提交,没有任何可以更改它。如果您不再能够在图中找到提交,则该提交现在很容易被删除。但是,如果您可以从某个现有名称开始,然后再返回以进行提交,则提交本身是引用安全的。因此,如果我们git checkout master(以便我们可以删除branch1),我们将得到:

...--F--G--H   <-- master (HEAD)
            \
             I--L--M--N   [abandoned]
              \
               J--K   <-- branch2
通过从I的{​​{1}}开始并向后工作,提交K仍可实现可达 :提交branch2在两个{{ 1}} I。现在branch1已经消失了,branch2仅在branch1上,但是仍然可以通过Git的“从所有分支名称后退”技巧来达到,

提交I不受保护。经过一段时间后(通常有至少30天的宽限期),通过Git称为 reflogs 的机制,Git的“垃圾收集器”最终将运行并清理无法访问对象(提交和其他对象)。这些承诺最终将完全消失,而您却没有得到:

branch2

这使得L-M-N似乎不存在。