合并后标记删除后不一致

时间:2015-03-02 17:10:34

标签: git merge git-tag

我在DEV分支上创建了一个标签。我将这个标签合并到我的主分支中。 我意识到标签在主分支中更有意义,我删除了标签。

DEV分支仍然与主分支合并,但令我惊讶的是,主分支不包含DEV的任何更改。

此屏幕截图是在我重新创建并再次推送标记之后拍摄的,仍然没有更改主分支。我也尝试了,但未能恢复合并......

Screenshot of git history

对于Git来说,合并是成功的,所以我不能将DEV重新合并为主人。 我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

[注意:这不是一个很好的答案,但它不适合作为评论。]

你的问题始于一个基本的误解:标签根本不附加到分支机构;他们只指向一个提交。

标记只是一个特定提交的永久 1 名称(一个提交的SHA-1)。请记住,git在内部通过SHA-1标识所有内容,并且引用名称 - 分支和标记,主要是,尽管还有其他形式 - 部分是 2 用于让我们puny humans处理SHA-1。

Git命令 - 在这种情况下为git merge - 采用分支和标记名称通常将名称转换为SHA-1并使用SHA-1执行大多数操作。在git merge的特定情况下,保留您传入的原始名称的唯一部分是最终提交消息("合并标记' 20150302-3.2.2015.10'&#34 ;, 在这种情况下)。其他所有东西都使用底层的SHA-1。这意味着如果你以后标签从一个SHA-1移动到另一个SHA-1,那根本不会影响合并,它只会让下一个微不足道的人混淆。

混淆的部分原因是标签应该是永久性的。在git中,你有两种常用的名称,分支和标签,它们都只是SHA-1的名字;但他们有不同的属性。分支名称具有移动的属性,因此它引用最新的提交。事实上,这非常有用,git会自动为你移动(在正确但非常常见的条件下)。也就是说,如果您在分支master""或者其他什么,正如git status所说的那样,并且你做了一个新的提交,然后调整分支master,使它指向你刚才做的新提交。这就是分支增长的方式。

相比之下,标签意味着不会改变,而且git不会自己改变它们。您当然可以强制进行更改,或者完全删除标记(然后根据需要重新标记或不重新标记)。但是,如果其他任何人 - 我们的repo的另一个git克隆,或者甚至是你自己的明天或下周或者其他 - 已经将标记记录为指向提交1234567,并且现在遇到指向提交6789abc的标记,那可能是相当的混乱。预计分支会移动,所以如果一个分支用于指向1234567并且现在指向6789abc,那么这似乎是正常的;但标签不是,所以这是一个惊喜。

简而言之,移动标签有点粗鲁:对读者来说有点震惊。无论如何它有时是合适的,但通常最好避免使用它。

这些都与您当前的问题无关,简而言之,这就是:

  

主分支机构不包含DEV的任何更改。

Commenter Dropped.on.Caprica pointed out the reason,您随后还原了合并。您的注释回答表明您尝试通过重复git merge命令恢复还原。这不会起作用git merge使用提交图来决定需要完成哪些工作,并且根据,毕竟不需要做任何工作。有关详细信息,请参阅linked answer

要恢复合并,您只需还原恢复;或者,如果您想重复合并(并且可能以不同方式执行),您可以使用相同的git图节点(或不同但附近的节点)。例如,您可以将新分支名称附加到图表中第三个提交的第一个父级。我无法看到此提交的提交消息或SHA-1,但我可以给你一个相对名称(只有在当前提交发生变化时才有效):

git checkout -b newbranch HEAD~3

然后从那里合并当前DEV分支的提示提交:

git merge DEV

如果您喜欢结果树,但希望将其作为"快速前进的树"在分支master上提交,有几种方法可以获得它。例如,请参阅How to create copy of a snapshot (commit) in a branch onto another branch in git?


1 好吧,意味着是永久性的。见后续段落。

2 它们还用于廉价的安全性,因为一些出口商只能通过引用名称访问SHA-1。但是,其他导出机制通常会违反这一规定:例如,如果您为他们提供正确的SHA-1,许多Web服务器都会咳出一个git对象。

也许最重要的是,引用是什么使提交 - 所有git对象,真正可达。 可以访问的对象 - 可以通过SHA-1 找到 ,而不是从名称到ID映射开始,然后从那里跟随其他ID符合"垃圾收集"并最终从存储库中删除。