【问题标题】:What to do instead of squashing commits in Mercurial在 Mercurial 中做什么而不是压缩提交
【发布时间】:2012-10-16 06:17:36
【问题描述】:

我已将 IDE 设置为每次保存任何内容时在本地提交。理想情况下,我希望保留一份未经审查的记录,以备不时之需,以备不时之需。但大多数时候它让我的历史变得详细。

我想知道一个很好的策略来保留该历史记录,但大多数时候可以忽略它。每次保存时,我的 IDE 都会运行我自己的脚本,所以我可以控制它。

我对 Mercurial 还很陌生,所以在这里我可能只需要一个基本的答案。但是,在提交、合并和报告时我应该执行哪些步骤才能在很大程度上忽略这些自动提交,但实际上不会压缩它们?还是我最好放弃并只是压扁?

Related question about how to squash with highly rated comment suggesting it might be better to keep that history

编辑 - 我的意思是,如果 Mercurial 想要保留您的所有历史记录(我同意),它应该让您过滤该历史记录以避免看到您可能想要压缩的内容。我宁愿 not 压扁,我只是寻求一种策略的帮助(在常规使用中,尽管并非总是如此)使它看起来尽可能像我压扁我的历史一样。

【问题讨论】:

  • @Ry4an - 您在相关问题中的评论建议保留历史记录,因此我正在联系您以防您愿意回答。
  • 我认为您无法 ping 尚未在您的答案中发布的人。
  • 为什么要在保存时自动提交?这不会导致非编译提交吗?如果是这样,那么如果您有需要,那将使 hg bisect 很难使用。
  • @SteveKaye - 关于二分的好点。我不太关心非工作(技术上我使用的是解释语言)提交,但这是关心的一个很好的理由。这正是我想提前在这里讨论的问题,所以谢谢。

标签: mercurial push changeset


【解决方案1】:

如果您确实想保留回购历史中每个Ctrl-S 的所有微小更改,并且只让log 显示重要更改集的子集,您可以始终tag“重要”更改集,然后别名 loglog -r tagged()。或者您可以对其他一些revset descriptor 使用相同的原则,例如在自动提交的消息中包含文本“autosave”并使用log -r keyword(autosave),这将显示所有非自动保存的提交。


为了实现您的目标,至少在我接近它的时候,我会使用mq extension 并在每次保存时自动提交补丁队列存储库。然后当你完成你的“白痴摸索”后,你可以hg qfinish将补丁作为一个可以推送的单一变更集。您应该(一如既往!)将更改集中在一个概念或步骤上(例如“修复保存按钮”),但这将包含为实现目标所采取的所有小步骤。

你需要

  • hg qinit --mq 一次用于初始化补丁队列​​ repo(仅供参考:存储在 \.hg\patches\
  • hg qnew fixing-the-save-btn 创建补丁

然后每次保存在 IDE 中

  • hg qrefresh更新补丁
  • hg commit --mq 在补丁队列 repo 中进行小改动

当你完成时

  • hg qfinish fixing-the-save-btn 将补丁转换为要推送的变更集

这会使您的 repo 本地化与每次保存时更改的内容保持一致,但仅在完成时推送变更集。您也可以qpopqpush 更改您正在处理的项目。

如果您尝试使用 squash 方法,那么当您压缩变更集时,您会丢失摸索的历史记录。要么这样,要么你会被困在试图将工作迁移到“真实”存储库/从“真实”存储库中迁移,我可以从经验告诉你,你不想这样做。 :)

【讨论】:

  • 谢谢,但我实际上是在尝试避免污染历史。我只是想以一种不会让我大部分时间看到历史的方式使用 Mercurial。
  • 这种(糟糕的)方式会让你得到巨大的非原子补丁,它可以组合单独的逻辑上不相关的任务。我认为,这比一长串最短提交更糟糕(无论如何,这两种类型都需要稍后重新组织)
  • 自动提交到补丁队列存储库需要qnewqrefresh,然后hg commit --mq 才能执行任何操作。
【解决方案2】:

它应该让您过滤该历史记录,以避免看到您可能想要压缩的内容

Mercurial 有这方面的工具。如果您只是不想看到(我想在 hg log 中) - 使用 revsets 过滤这些变更集:

hg log -r "not desc('autosave')"

或者如果您使用 TortoiseHg,只需转到查看 -> 过滤器工具栏,然后在工具栏中输入“not desc('autosave')”。瞧,您的自动保存条目已从主列表中隐藏。

【讨论】:

    【解决方案3】:

    您希望在您的存储库中保留详细的历史记录,但您希望拥有(并能够导出)仅包含“合理”修订集的理想化历史记录,对吗?我可以同情。

    解决方案一: 使用标签来标记历史中的有趣点,并学会忽略它们之间的所有混乱点。

    解决方案 2: 使用两个分支并合并。在分支default 中进行开发,并保持并行分支release。 (你可以称之为clean,但实际上你是在管理发布)。每当default 处于您想要检查点的稳定状态时,切换到分支release 并将default 的当前状态合并到其中--如果您愿意,可以分批进行。如果您从不直接向release 提交任何内容,则永远不会发生合并冲突。

     (original branch) --o--o--o--o--o--o--o    (default)
              \              \        \
               r   ... ...  --r--------r        (release)
    

    结果:您可以更新到 release 的任何修订版,并期望处于正常运行状态。你可以运行hg log -r release,你只会看到选择的检查点。您可以检查完整的日志以了解一切是如何发生的。缺点:因为release 分支依赖于default,所以如果不带default 就无法将其推送到另一个repo。由于重复合并,hg glog -r release 也会看起来很奇怪。

    解决方案 3: 使用上述命名分支,但使用 rebase 扩展名而不是合并。它可以选择复制而不是直接移动重新设置的变更集;它有一个选项--collapse,可以将一组修订转换为一个修订。每当您想要完成一组修订r1:tip 时,复制它们从defaultrelease,如下所示:

    hg rebase --source r1 --dest release --keep --collapse
    

    这会将一个修订版推送到 release 的头部,这相当于从 r1 到 default 头部的整个变更集。 --keep 选项使其成为副本,而不是破坏性重写。优点是release 分支看起来就像你想要的那样:漂亮而干净,你可以推送它而不用拖拽默认分支。缺点是您无法将其阶段与default 中的修订相关联,因此我推荐方法2,除非您真的必须隐藏中间修订。 (另外:分批压缩你的历史并不容易,因为 rebase 会移动/复制“源”修订的所有后代。)

    所有这些都需要你做一些额外的工作。这是不可避免的,因为 mercurial 无法知道您想要压缩哪些修订集。

    【讨论】:

      【解决方案4】:

      我建议你使用分支。当您开始一个新功能时,您会创建一个新分支。您可以在该分支中尽可能多地提交。完成后,将功能分支合并到主干中。这样,您基本上将历史分为两类:一类是细粒度的(特征分支中的历史),另一类是粗粒度的(主干中的历史)。您可以使用以下命令轻松查看其中任何一个:hg log --branch <branch-name>

      【讨论】:

        猜你喜欢
        • 2010-12-16
        • 2016-06-12
        • 1970-01-01
        • 2011-11-29
        • 2019-10-29
        • 2022-07-21
        • 1970-01-01
        • 2011-03-09
        • 2011-12-18
        相关资源
        最近更新 更多