假设我有一个本地和一个远程 Mercurial 存储库。现在,我开始研究一个功能。我处理它,当我认为它完成时,我提交变更集。对其进行更多测试,我发现我可以通过调整代码中的某些内容来进一步改进此功能。我做出改变并承诺。20 分钟后,我发现这个新功能有一个错误,所以我修复它并提交。
例如,我现在有 3 个变更集,我真的很想将它们作为一个变更集推送到远程存储库,并带有消息“实施功能 X”。
我怎样才能轻松做到这一点?我相信我可以通过补丁来做到这一点,但这似乎需要做很多工作。
假设我有一个本地和一个远程 Mercurial 存储库。现在,我开始研究一个功能。我处理它,当我认为它完成时,我提交变更集。对其进行更多测试,我发现我可以通过调整代码中的某些内容来进一步改进此功能。我做出改变并承诺。20 分钟后,我发现这个新功能有一个错误,所以我修复它并提交。
例如,我现在有 3 个变更集,我真的很想将它们作为一个变更集推送到远程存储库,并带有消息“实施功能 X”。
我怎样才能轻松做到这一点?我相信我可以通过补丁来做到这一点,但这似乎需要做很多工作。
histedit扩展正是您正在寻找的。
hg histedit -o
或者
hg histedit --outgoing
将调出传出变更集的列表。从列表中您可以
histedit 将提示您输入折叠变更集的新提交消息,它默认为两条消息,用“\n***\n”分隔它们。
您也可以使用 mq 扩展获得类似的结果,但要困难得多。
您也可以使用折叠扩展来进行折叠,但它没有提供很好的 UI,也没有提供编辑生成的提交消息的方法。编辑生成的提交消息还允许清理最终消息,这是我最终经常使用的东西。
折叠扩展怎么样?
是的,您可以使用补丁来做到这一点:假设您的工作位于变更集 100 到 110 中,包括 100 到 110
创建补丁:
% hg export -o mypatch 100:110 --git
更新到 99:
% hg update 99
使用 --no-commit 应用补丁(否则您将获得所有变更集):
% hg import --no-commit mypatch
一次提交所有更改:
% hg commit
您现在有两个头(110 和 111),就它们在您的工作目录中生成的文件而言,它们应该是等效的——也许在去除旧的之前对它们进行比较:
% hg strip 100
好的,现在我已经把它全部拼写出来了,它看起来确实很长,但是我自己做了很多次,我觉得它并没有太多的苦差事......
如果您使用的是 TortoiseHg,使用可以只选择两个版本(使用 CTRL 选择非后续版本),右键单击并选择“压缩历史”。
之后,您将从您之前选择的第一个更改开始在新的头中获得一个新的更改列表,它将包含您选择的那些之间的所有后代更改列表。
如果不再需要旧的更改列表,您可以简单地删除它们:使用MQ扩展。同样,在 TortoiseHg 中:右键单击第一个需要删除所有后代的更改列表,“Modify History -> Strip”。
我首选的使用 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 做各种其他的事情,这些事情都非常方便!
hg collapse
并且hg histedit
是最好的方法。或者,如果它们可靠地工作,这将是最好的方法......我histedit
在三分钟内因堆栈转储而崩溃。Collapse
也好不到哪里去。
我想我可能会分享另外两个 BKM:
hg rebase --collapse
此扩展随 Mercurial 一起分发。我还没有遇到问题。您可能必须玩一些游戏来解决hg rebase
限制 - 基本上,它不喜欢重新定位到同一分支上的祖先,命名或默认,尽管如果在(命名)分支之间重新定位它确实允许它。
将存储库 ( 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
树)独立于工作目录及其文件,这就会起作用。
如果他们不独立...
我从未使用过 Mercurial,但这听起来很像 Martin Fowler 不久前在他的博客上所说的:
HistEdit 会做你想做的事,但它可能是矫枉过正。如果您唯一需要的是将一些变更集折叠在一起,则折叠扩展将完成这项工作。
为什么不只是hg strip --keep
指挥?
然后,您可以将所有更改作为一次提交提交。
假设您在 Mercurial 中有两个未发布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 中的两个提交。
是的,strip --keep
适用于作者的问题。但它与其他略有不同,例如,如果您有 1 到 30 的版本,但只想折叠 12-15 版本。其他解决方案有效但无效strip --keep
。