【问题标题】:How can I discard the default branch?如何丢弃默认分支?
【发布时间】:2012-12-06 15:47:03
【问题描述】:

在第 24 版,我为新功能创建了一个分支,与此同时,其他人继续使用默认版本(第 26,28 和 29 版),但最终使项目处于糟糕的状态。我一直在分支上开发(最高版本 36),现在应该成为默认分支。我该怎么做?

我尝试回到默认的 24 并与 36 合并,我得到了默认的 37,就像我想要的那样。但现在它抱怨有两个头(37 和 29)。我不想合并,因为 26,28 和 29 都不好。我尝试去 37 并执行 hg merge --tool internal:local -r 29 以丢弃 29,但它没有工作。

这似乎很简单,但我有点卡住了。

提前致谢

【问题讨论】:

  • “它抱怨有两个头”是什么意思?如果这是您想要的,我认为拥有 2 个头没有任何问题,hg 也没有。
  • 嗯,是这样的:“一个 hg glog 会说出超过一百万个单词”
  • 添加分支布局的文本图将有助于尝试回答此问题的人们更好地了解正在发生的事情。

标签: mercurial


【解决方案1】:

解决此问题的一种方法是简单地关闭您不想要的分支:

hg update 29
hg commit --close-branch -m "closing branch"

从技术上讲,您仍然会有两个头,但其中一个会被标记为关闭,因此您不会注意到它在一般使用中(例如,如果您运行 hg heads)。

或者,我猜你在哪里声明善变“抱怨有两个头”,是当你试图推送到另一个存储库时。在这种情况下,您可以指定“是”,您确实知道新头并接受它的存在。如果您在将分支标记为关闭后执行此操作,则不会导致任何问题:

hg push --force

但是,您在进行更新时可能会产生歧义,因此在这种情况下指定修订可能是个好主意。

最后,如果您不想看到尚未合并到自己分支中的变更集,可以在克隆到新存储库时指定自己的最新修订:

hg clone project new_project --rev 37

认为这将创建一个只复制到该修订版所需的变更集。然后,您可以将此作为您工作的基础。缺点是你不会有你可能真正想要的非祖先变更集。

对于其他选项,我会研究一些与 Mercurial 打包的扩展,例如 strip。这个我没用过,所以不能给你任何建议。

您可以查看here 了解更多信息。

【讨论】:

  • push --create-branch 错误,因为 OP 在(默认)分支中有匿名分支案例和 2 个头,而不是新的单头分支
  • +1 用于包含指向 Pruning Dead Branches wiki 页面的链接,这是此类问题的正确参考。不过,如果你让这个参考更加突出,答案可能会好一些。
【解决方案2】:

克劳迪奥,我会尝试将您的问题“翻译”成更简洁的形式(如果需要,请检查翻译和修正)

您在第 24 版的名为 default 的分支中创建了 匿名分支,现在您只想在开发中使用另一棵树中的一些变更集,并且在推送到远程服务器时遇到问题并抱怨创建额外的头部。

我的重构正确吗?

如果“是”和不需要的变更集 26、28、29 在单个连续范围内,您可以在“最后一个好”的外部变更集合并(合并 24 是无用的,没有 glog 的 AFAICS - 它似乎是分支点)并关闭不需要的头: @icabod 对 --close-branch 配方是正确的

另一方面,如果您的存储库是唯一的并且未发布,您可以重写历史记录(MQ:strip,histedit...)并在合并删除错误变更集之前,获取干净的第二个匿名分支,合并,提交,推送

您也可以(虽然不推荐)push -f,并将两个头都推送到远程仓库,您的头将处于活动状态,而您和其他人则使用它

修复被 cmets pic 清除的问题

更正的重建,迭代 2:您在默认分支中有一些变更集,您希望从主线中排除这些变更并将您的分支合并到默认值。

除了建议的早期历史重写(从历史中完全杀死变更集 - 适用于“未发布”存储库),您可以将错误的变更集保留在历史记录中,但以额外变更集为代价撤消它们的变更:hg backout -r REV create changeset, undoing来自 REV 的变化(不记得在这里使用 revrange)。三个(最大)新的默认撤销变更集,您已准备好将您的分支合并到默认值(即使在合并后您也可以撤销)。

【讨论】:

  • 嗨,您的重构几乎是正确的。唯一不同的是它是一个命名分支,而不是一个匿名分支。关闭仍然可以吗? ps:感谢“翻译”
  • @ClaudioCoelho - “有两个头的命名分支”是 匿名分支,正如 Steve Losh 使用的这个术语,它是传统术语。是的,任何分支中的任何头都可以使用--close-branch
  • 我可以关闭默认分支(在 29 处),它可以工作。但是我必须为默认分支使用另一个名称。我想放弃修订版 26,28 和 29,并将我在命名分支中的内容放在默认分支上。有可能吗?
  • @ClaudioCoelho - 好的,现在我明白了。我的重建在 90% 上是错误的。在答案中查看我的编辑
  • 感谢 :) 的反馈。我最终使用了 strip
【解决方案3】:

基本上,您需要 (a) 将 default 恢复到它在修订版 24 时的状态(不破坏任何历史记录),然后 (b) 将您的功能分支合并回默认值。通过默认创建两个头,您使事情变得有点复杂,但没什么大不了的。让我们一步一步来。

(我建议克隆您的整个 repo,以便您可以安心地进行试验。如果您做了不喜欢的事情,只需删除整个目录并重新开始)。

以下是如何扭转错误更改的影响(不使用像 strip 这样破坏性地重写历史的命令):

  1. 更新到默认头部:

    hg update -r 29
    
  2. 在不更改“当前”版本的情况下,将所有文件切换到它们在版本 24 中的内容:

    hg revert -r 24
    
  3. 将此文件状态提交为default的新负责人:

    hg commit -m "Backing out revisions 26,28,29"
    

此时,您可能刚刚将您的功能分支合并到 default 的新头部,因为所有错误的更改都已撤消:

    hg merge feature

这应该是故事的结局。但是您已经将feature 合并到rev 24,得到revset 37。没问题,您仍然可以执行步骤1-3,这将为您提供一个没有任何破坏性更改的默认head。然后,不是合并feature的头部,而是合并37作为最后一步:

    hg merge -r 37

这将统一default 的负责人,而不会产生任何不利影响,因为您已经退出了错误的更改。

【讨论】:

    猜你喜欢
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2021-11-07
    • 1970-01-01
    • 2011-06-17
    • 2014-07-08
    • 1970-01-01
    相关资源
    最近更新 更多