借助Mercurial,在推送之前如何“压缩”一系列变更集合?

比方说,我有一个本地和远程Mercurial存储库。 现在,我开始研究一个function。 我工作,当我认为完成时,我提交变更集。 再testing一下,我发现我可以通过在代码中调整一些东西来进一步改进这个function。 我做了改变和承诺。 20分钟后,我发现这个新function存在一个错误,所以我修复了这个错误,并提交了这个错误。

我现在有3个变更集,我真的想推送到远程存储库作为一个变更集,例如消息“实现functionX”。

我怎样才能做到这一点,没有太多的麻烦? 我相信我可以用补丁来做,但是看起来好像很多工作。

如何折叠扩展 ?

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

 hg histedit -o 

要么

 hg histedit --outgoing 

将列出即将离任的变更集。 从列表中你可以

  • 折叠2个或多个变更集创build一个变更集
  • 删除变更集将其从历史logging中删除
  • 不pipe你喜欢重新排列变更集。

histedit会提示你input折叠变更集的新提交信息,默认情况下这两个信息用“\ n *** \ n”分隔。

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

您也可以使用折叠扩展来进行折叠,但是它不提供良好的UI,也不提供编辑结果提交消息的方法。 编辑生成的提交消息也允许清理最终的消息,这是我总是最终使用的东西。

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

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

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

是的,你可以用补丁来做:让我们假设你的工作在100到110之间

  1. 创build一个补丁:

    % 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

好吧,现在我已经拼出来了,看起来很长,但是自己做了很多次,我觉得这不是太麻烦了。

我的首选使用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 

(可能有一个更好的方法来做重复步骤,但我不知道,因为我通常使用TortoiseHg进行该操作。)

起初看起来有些复杂,但是一旦你开始使用mq,它就非常简单和自然 – 再加上你可以用mq来做各种其他的事情,可以很方便!

hg collapsehg histedit是最好的方法。 或者说,如果他们的工作可靠的话,那将是最好的方法……我在三分钟之内histedit自己的堆栈转储histedit了。 Collapse并不是那么好。

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

  1. hg rebase --collapse

    这个扩展名与Mercurial分发。 我还没有遇到问题。 你可能不得不玩一些游戏来解决hg rebase限制 – 基本上,它不喜欢重新绑定到同一个分支上的祖先(named或default),尽pipe如果在(named)分支之间重新绑定它也是允许的。

  2. 将存储库( foo/.hg )移动到工作目录( bar )及其文件。 而不是相反。

有人谈过创build两个克隆树,并在它们之间复制文件。 或者在他们之间修补。 相反,它更容易移动.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树,独立于工作目录及其文件,就可以工作。

如果他们不是独立的…

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

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

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

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

HistEdit会做你想做的,但它可能是矫枉过正。 如果您唯一需要的是将一些更改集合在一起, Collapse Extension将完成这项工作。

假设你有两个未发布的THIS并且在Mercurial中提交,并且像这样在THIS点上join单个提交::

 ... --> 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 ... 

joinTHAT ::

 $ hg qfold $THATNAME 

注意要find名称THATNAME使用::

 $ hg qseries 

应用所有的修补程序并将其移动到存储库历史

 $ hg qpush -a $ hg qfinish -a 

我的博客主题是在Mercurial中join两个提交 。