96

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

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

我怎样才能轻松做到这一点?我相信我可以通过补丁来做到这一点,但这似乎需要做很多工作。

4

11 回答 11

52

histedit扩展正是您正在寻找的。

hg histedit -o

或者

hg histedit --outgoing

将调出传出变更集的列表。从列表中您可以

  • 折叠 2 个或更多变更集,创建一个单一变更集
  • 删除变更集,将它们从历史记录中删除
  • 随心所欲地重新排序变更集。

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

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

您也可以使用折叠扩展来进行折叠,但它没有提供很好的 UI,也没有提供编辑生成的提交消息的方法。编辑生成的提交消息还允许清理最终消息,这是我最终经常使用的东西。

于 2009-10-13T12:32:37.960 回答
39

折叠扩展怎么样?

于 2009-07-29T15:39:48.163 回答
21

是的,您可以使用补丁来做到这一点:假设您的工作位于变更集 100 到 110 中,包括 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

好的,现在我已经把它全部拼写出来了,它看起来确实很长,但是我自己做了很多次,我觉得它并没有太多的苦差事......

于 2009-07-30T02:48:07.050 回答
19

如果您使用的是 TortoiseHg,使用可以只选择两个版本(使用 CTRL 选择非后续版本),右键单击并选择“压缩历史”

之后,您将从您之前选择的第一个更改开始在新的头中获得一个新的更改列表,它将包含您选择的那些之间的所有后代更改列表。

如果不再需要旧的更改列表,您可以简单地删除它们:使用MQ扩展。同样,在 TortoiseHg 中:右键单击第一个需要删除所有后代的更改列表,“Modify History -> Strip”

于 2011-05-12T14:34:33.350 回答
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 做各种其他的事情,这些事情都非常方便!

于 2011-03-03T00:30:07.980 回答
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树)独立于工作目录及其文件,这就会起作用。

如果他们不独立​​...

于 2012-01-06T07:23:39.717 回答
2

我从未使用过 Mercurial,但这听起来很像 Martin Fowler 不久前在他的博客上所说的:

http://martinfowler.com/bliki/MercurialSquashCommit.html

于 2009-07-29T14:37:30.667 回答
0

HistEdit 会做你想做的事,但它可能是矫枉过正。如果您唯一需要的是将一些变更集折叠在一起,则折叠扩展将完成这项工作。

于 2009-10-13T14:22:14.917 回答
0

为什么不只是hg strip --keep指挥?

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

于 2014-05-23T06:41:26.777 回答
0

假设您在 Mercurial 中有两个未发布THISTHAT提交,并且希望它们加入单个提交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 中的两个提交

于 2016-11-09T20:54:16.210 回答
0

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

于 2018-10-16T02:31:05.433 回答