使用 Mercurial,如何在推送之前将一系列变更集“压缩”为一个变更集?
-
05-07-2019 - |
题
假设我有一个本地和一个远程 Mercurial 存储库。现在,我开始开发一个功能。我致力于它,当我认为它已经完成时,我提交变更集。多测试一下,我发现我可以通过调整代码中的某些内容来进一步改进此功能。我做出改变并承诺。20 分钟后,我发现这个新功能有一个 bug,所以我修复了它并提交了它。
例如,我现在有 3 个变更集,我真的很想将它们作为一个带有消息“实现功能 X”的变更集推送到远程存储库。
我怎样才能轻松地做到这一点?我相信我可以通过补丁来做到这一点,但这似乎需要很多工作。
解决方案
折叠扩展程序怎么样?
其他提示
这 历史编辑 扩展正是您正在寻找的。
hg histedit -o
或者
hg histedit --outgoing
将显示传出变更集的列表。从列表中您可以
- 折叠 2 个或多个变更集,创建一个变更集
- 删除变更集,将其从历史记录中删除
- 根据您的喜好重新排序变更集。
histedit 将提示您输入折叠变更集的新提交消息,默认为两条消息,并用“ *** ”分隔它们。
您也可以使用 mq 扩展获得类似的结果,但要困难得多。
您还可以使用折叠扩展来进行折叠,但它没有提供很好的 UI,也没有提供编辑生成的提交消息的方法。编辑生成的提交消息还可以清理最终消息,这是我最终经常使用的东西。
是的,你可以用补丁做到这一点: 假设您的工作在变更集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选择非后续版本),右键单击并选择" Compress History" 。
之后,您将从之前选择的第一个更改开始,在新头中获得一个新的更改列表,它将包含您选择的更改列表之间的所有后续更改列表。
如果您不再需要旧的更改列表,则可以简单地删除旧的更改列表:使用 MQ 扩展名。再次,在TortoiseHg中:右键单击第一个需要使用所有后代删除的更改列表,"修改历史记录 - >线条" 强>
我使用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不久前在他的博客上谈论的内容:
为什么不只是 hg strip --keep
命令?
然后,您可以将所有更改作为一次提交提交。
HistEdit会做你想要的,但它可能有点过分。如果您唯一需要的是将一些变更集折叠在一起,那么折叠扩展将完成这项工作。
假设您在Mercurial中有两个未发布的 THIS
和 THAT
提交,并希望它们在 THIS
point :: 加入单个提交p>
... --> THIS --> ... --> THAT --> ... --> LAST
检查您的提交是否未发布::
$ hg glog -r "draft() & ($THIS | $THAT)"
更新到 LAST
commit ::
$ 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
。