使用Mercurial,如何在推入之前将一系列变更集“压缩”为一个?


96

假设我有一个本地和远程Mercurial存储库。现在,我开始研究功能。我正在处理它,当我认为完成后,便提交变更集。经过更多测试,我发现可以通过调整代码中的某些内容来进一步改进此功能。我进行更改并提交。20分钟后,我发现此新功能存在一个错误,因此我将其修复并提交。

例如,我现在有3个变更集,我真的希望将其作为一个变更集推送到远程存储库,并带有消息“实施功能X”。

我怎么能没有太多麻烦呢?我相信我可以用补丁来做到这一点,但这似乎是很多工作。


40
显然,这不是我不让您尝试压缩变更集的地方,但是您可能要考虑,版本控制的价值的一半是在“为什么”之后几个月而不是几年后才回答。准确表示功能的产生方式以及在哪个阶段中可能具有未来价值。扔掉它似乎是如此……不受控制。
Ry4an Brase 09年

这的确引起了另一个问题……“ histedit”和“ collapse”之间有什么区别
sylvanaar

1
崩溃提供了histedit功能的子集,而histedit具有更直观的UX。
Stefan Rusek 09年

1
它还提供了一种编辑合并变更集消息的机制。
Stefan Rusek 09年

1
@ Ry4an:实际上,在某些情况下,压缩/折叠增加了与版本控制的相关性。如果不进行压缩,我每天都会进行两次与功能或错误修复无关的提交,但是它们只是用于将代码从便携式计算机移动到台式机,反之亦然。它们只会给版本历史添加噪音。
约翰·雷诺兹

Answers:


39

如何在折叠扩展


20
未来的问候!我只是在Google上搜索了相同的功能,而如今,hg显然已使用来支持此功能hg rebase --collapse在rebase命令中查看hg Wiki。由于这个问题是第3个整体搜索结果,也是第一个关于stackoverflow的搜索结果,因此我认为信息可能有用。
a.peganz 2015年

1
将来的问候!!rebase扩展似乎只针对将变更集从一个分支移动到另一个分支。是的,有一个--collapse选项,但似乎仅在跨分支移动一组变更集时才适用。参见< mercurial-scm.org/wiki/… >
Brad Oestreicher

3
您可以在单个分支内使用hg rebasewith --collapse
UuDdLrLrSs '16

52

histedit扩展正是你所期待的。

hg histedit -o

要么

hg histedit --outgoing

将显示即将发布的变更集的列表。从列表中可以

  • 折叠2个或更多变更集,以创建一个变更集
  • 删除变更集,将其从历史记录中删除
  • 根据您的喜好对变更集重新排序。

histedit会提示您输入折叠变更集的新提交消息,它默认为两条消息,用“ \ n *** \ n”分隔。

您还可以使用mq扩展名获得类似的结果,但这要困难得多。

您也可以使用折叠扩展名进行折叠,但是它不能提供出色的UI,也不能提供编辑结果提交消息的方法。编辑生成的提交消息还可以清理最终消息,这是我总是最终要利用的东西。


谢谢,这正是我所需要的。如果您可以在TortoiseHg中进行操作,那就太好了-但是命令行非常简单。
sylvanaar's

21

是的,您可以使用补丁来实现:假设您的工作在100到110的变更集中,包括

  1. 创建补丁:

    % hg export -o mypatch 100:110 --git

  2. 更新至99:

    % hg update 99

  3. 使用--no-commit应用补丁(否则,您将获得所有更改集):

    % hg import --no-commit mypatch

  4. 一次提交所有更改:

    % hg commit

  5. 现在,您有两个头(110和111),它们在您的工作目录中生成的文件应该相等–也许在删除旧文件之前先比较它们的合理性:

    % hg strip 100

好吧,既然我已经把所有内容都拼出来了,它的确看起来很长,但是我自己做了很多次,我觉得它并不太繁琐...


1
很好的答案,但是有一个先决条件:必须启用MQ扩展
克里斯·凯利

要同时在二进制文件中包含更改,请确保使用--git选项:例如:“ hg export -o mypatch 100:110 --git”有关更多信息,请参见:stackoverflow.com/a/12537738/ 367663 我已自由修改了答案。
Kharlos Dominguez

1
似乎太复杂了,为什么不hg strip --keep然后一次提交所有内容呢?
G. Demecki 2014年

@ G.Demecki因为这可能是非常有损的操作..?尽管MQ过于严格(甚至不建议使用),但在需要这种工作流程时除外。
user2864740

@ user2864740您可能是对的,因为我不是Mercurial专家。但是默认情况下,hg strip会将备份放在.hg/strip-backup/目录中。我想这还不算安全,git reflog但仍然可以提供某种救援。
G. Demecki 2015年

19

如果您使用的是TortoiseHg,使用只需选择两个修订(使用CTRL选择不后续的修订),右键单击并选择“压缩历史记录”

之后,您将从之前选择的第一个更改开始,以新的标题获得新的更改列表,它将包含您选择的所有更改列表。

如果您不再需要旧的更改列表,则可以简单地删除它们:使用MQ扩展。再次,在TortoiseHg中:右键单击需要删除的所有后代的所有更改列表“修改历史记录->删除”


18

我首选的使用mq进行折叠的方法是使用TortoiseHg ,如此处所述。但是,可以从命令行轻松完成,如下所示:

hg qimport -r <first>:<last> 
    -- where <first> and <last> are the first and last changesets 
    -- in the range of revisions you want to collapse

hg qpop <first>.diff
    -- remove all except for the first patch from the queue
    -- note: mq names patches <#>.diff when it imports them, so we're using that here

hg qfold <next>.diff
    -- where <next> is <first>+1, then <first>+2, until you've reached <last>

hg qfinish -a
    -- apply the folded changeset back into the repository

(执行qfold步骤可能有更好的方法,但我不知道,因为我通常对该操作使用TortoiseHg。)

乍一看似乎有些复杂,但是一旦您开始使用mq,它就非常简单自然,而且您还可以使用mq进行其他各种操作,非常方便!


4

hg collapse并且hg histedit是最好的方法。或者,如果它们可靠地工作,那将是最好的方法……我histedit在三分钟之内就因堆栈转储而崩溃。Collapse没有那么好。

以为我可能还会分享另外两个BKM:

  1. hg rebase --collapse

    此扩展与Mercurial一起分发。我还没有遇到任何问题。您可能需要玩一些游戏来解决hg rebase局限性-基本上,它不喜欢在同一分支(命名分支或默认分支)上迁移到祖先,尽管如果在(命名)分支之间迁移也可以这样做。

  2. 将存储库(foo/.hg)移至工作目录(bar)及其文件。并非相反。

有人谈论过创建两个克隆树,并在它们之间复制文件。或在它们之间打补丁。相反,它更容易移动.hg目录。

hg clone project work
... lots of edits
... hg pull, merge, resolve
hg clone project, clean
mv work/.hg .hg.work
mv clean/.hg work/.hg
cd work
... if necessary, pull, nerge, reconcile - but that would only happen because of a race
hg push

只要真正的存储库(.hg树)独立于工作目录及其文件,此方法就起作用。

如果他们不是独立的...


在2015年,这histedit是一个很好的选择。我仍然不信任它,因为我执行了git rebase -i,但是它不会崩溃..至少有些新版本会在出现严重错误的情况下将您留在temp分支上,因此只有一次删除变更集是在提交新分支之后。
user2864740


0

为什么不只是hg strip --keep命令?

然后,您可以一次提交所有更改。


@草莓没有提供答案??它认为它完美地回答了作者的问题。您能否阐明您的观点?
G. Demecki 2015年

这是古老的历史,因此我将撤回该言论-但批准的答案似乎是更权威的参考。
草莓2015年

1
@草莓确实是古老的线程。但是公认的答案已经过时了,因为Mercurial不再需要单独的第三方扩展来完成这项工作。
G. Demecki 2015年

0

HistEdit可以完成您想要的操作,但是可能太过分了。如果您唯一需要的是将一些变更集折叠在一起,那么Collapse Extension将完成这项工作。


1
尽管它确实提供了更易于使用和理解的UI,这足以使用它,但它还提供了一种机制来编辑合并的变更集消息,这是我经常想做的另一件事合并变更集。
Stefan Rusek 09年

而且,仅了解UI的问题确实是无法理解的。无论如何,过去,histedit允许更改“消息”的年龄,以及在“折叠”时更改的消息。histedit非常完美;如果有的话,合拢扩展没有用。
user2864740

0

假设你有两个未公布THIS,并THAT在水银提交和他们一样加入到单在提交THIS点::

... --> THIS --> ... --> THAT --> ... --> LAST

检查您的提交未发布::

$ hg glog -r "draft() & ($THIS | $THAT)"

更新LAST提交::

$ hg up

并将导入提交THIS到MQ ::

$ hg qimport $THIS::.

取消应用所有补丁,仅先应用THIS::

$ hg qpop -a
$ hg qpush
$ hg qapplied
... THIS ...

加入THAT::

$ hg qfold $THATNAME

注意要查找名称,请THATNAME使用:

$ hg qseries

应用所有补丁并将其移至存储库历史记录::

$ hg qpush -a
$ hg qfinish -a

我关于主题的博客文章是Mercurial中的两次提交


0

是的,strip --keep适用于作者的问题。但这与其他版本略有不同,例如,如果您的版本是1到30,但只想折叠12-15版本。其他解决方案有效,但无效strip --keep

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.