如何在Mercurial中避免压缩提交

4
我把我的IDE设置为在我保存任何东西时都本地提交。理想情况下,我希望能保留我犯的错误记录,以备不时之需。但大多数时候,这会让我的历史记录过于详细。
我想知道一个好的策略来保留历史记录,但大多数时候可以忽略它。我的IDE在每次保存时运行我的脚本,所以我有控制权。
我对Mercurial还比较新,所以基本答案可能就够了。但是,在提交、合并和报告时,我应该采取哪些步骤才能大多数忽略这些自动提交,而不必实际压缩它们呢?还是我最好放弃,直接压缩?
相关问题:如何压缩一系列变更集。高评价评论建议保留历史记录可能更好。
编辑 - 我的观点是,如果Mercurial想要保留所有历史记录(我同意这一点),它应该让你过滤掉你可能想要压缩的内容。我宁愿不压缩,只是在使用时(虽然不总是)尽可能让它看起来像我压缩了历史记录。

@Ry4an - 在相关问题中,您的评论建议保留历史记录,因此我在这里提醒您回答。 - psr
1
我认为你不能ping一个还没有在你的回答中发帖的人。 - Laf
1
你为什么想在保存时自动提交?这样做不会导致无法编译的提交吗?如果是这样,那么如果你曾经需要使用hg bisect,这将使其变得非常困难。 - Steve Kaye
@SteveKaye - bisect 的观点很好。 我不太关心不起作用的(技术上我正在使用解释型语言)提交,但这是一个很好的关注点。 这正是我想要提前了解的问题类型,所以谢谢你。 - psr
4个回答

4
您希望在存储库中保留详细的历史记录,但您希望拥有(并能够导出)仅包含“合理”修订集的理想化历史记录,对吗?我可以理解。 解决方案1:使用标记标记历史记录中的有趣点,并学会忽略它们之间的所有混乱部分。 解决方案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。此外,hg glog -r release将因重复合并而显得奇怪。

解决方案3:像上面一样使用命名分支,但使用rebase扩展而不是合并。它有一个选项可以复制而不是直接移动重新基础化的变更集;它还有一个选项--collapse,可以将一组修订转换为单个修订。每当您有一组修订r1:tip需要完成时,可以按以下方式将它们从default复制到release

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

这将把一个等同于从r1到default末尾的整个更改集合推送到release的头部。 --keep选项使其成为副本,而不是破坏性重写。好处是release分支看起来就像你想要的一样:漂亮而干净,并且你可以将其推送而不会拖累默认分支。缺点是你无法将其阶段与default中的修订关联起来,因此除非你真的需要隐藏中间修订版,否则我建议使用第二种方法。 (还有:批量压缩您的历史记录不那么容易,因为rebase将移动/复制“源”修订版的所有后代。)

所有这些都需要你做一些额外的工作。 这是不可避免的,因为mercurial没有办法知道你想压缩的revset。


3

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

Mercurial有相应的工具。如果你不想看到某些变更集(我猜是在hg log中),可以使用revsets来过滤这些变更集:

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

如果您使用TortoiseHg,只需进入“查看”->“过滤器工具栏”,在工具栏中键入“not desc('autosave')”,即可隐藏主列表中的自动保存条目。


2
如果您确实想要保留每个“Ctrl-S”所做的微小更改,并且仅让“log”显示重要更改的子集,则可以始终将“标记”重要变更集,然后将别名“log”设置为“log -r tagged()”。或者您可以使用相同的原理与一些其他revset descriptor,例如在自动提交的消息中包含文本“autosave”,并使用“log -r keyword(autosave)”来显示所有非自动保存的提交。
为了实现你的目标,至少按照我的方法,我会使用 mq 扩展 并在每次保存时自动提交 补丁队列仓库。然后当你完成了"白痴式地摸索"之后,可以将补丁作为一个单一的变更集合 hg qfinish,并进行推送。你应该(像往常一样!)围绕一个单一的概念或步骤(例如:"修复保存按钮")来保持修改,但这将捕获所有小的步骤以便达到你的目标。

你需要执行以下操作:

  • hg qinit --mq 一次性初始化补丁队列仓库(存储在 \.hg\patches\
  • hg qnew fixing-the-save-btn 创建一个补丁

然后每次在你的 IDE 中保存时:

  • hg qrefresh 更新补丁
  • hg commit --mq 在补丁队列仓库中制作小的变更集

最后,当你完成时:

"hg qfinish fixing-the-save-btn" 将补丁转换为变更集以进行推送。这样可以使你在本地存储所有的修改记录,每次保存时都能看到修改了哪些内容,但只有在完成时才会推送变更集。你还可以使用 qpopqpush 命令来更改正在处理的项目。
如果你尝试压缩方法,当你压缩变更集时就会丢失修改历史记录。要么如此,要么你将被困在尝试迁移工作到 / 从“真实”存储库中的境地中,从我的经验来看,这是不想做的事情。:)

谢谢,但我实际上正试图避免污染历史记录。我只是想以一种不需要大部分时间查看历史记录的方式使用Mercurial。 - psr
这种(糟糕)方式会产生巨大的非原子补丁,可能会组合不相关逻辑任务。我认为,这比最短提交列表更差(两种类型无论如何都需要后续重新组织)。 - Lazy Badger
在提交补丁队列存储库之前,需要执行 qnewqrefresh,然后 hg commit --mq 才能执行任何操作。 - Steve Kaye

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接