我有一对提交,实际上应该只是一个。如果我使用的是git,则可以使用:
git rebase -i <some-commit-before>
然后压扁它们。
我可以做一下吗?如果是这样,怎么办?
我有一对提交,实际上应该只是一个。如果我使用的是git,则可以使用:
git rebase -i <some-commit-before>
然后压扁它们。
我可以做一下吗?如果是这样,怎么办?
Answers:
我最喜欢的是hg strip --keep
命令。然后我一次提交所有更改。
这对我来说是最快,最舒适的方式,因为我喜欢在日常工作中做很多小的事情;)
注意1:strip
需要mq
启用内置扩展。
注意2:我最喜欢的Git / Mercurial客户端(SmartGit / Hg)--keep
在期间默认添加参数strip
。更方便的是:它提供了称为join commits
:]的选项
hg strip --keep --rev [rev]
rev
--rev
是可选的,完整命令是hg strip --keep [rev]
hg help strip
给hg strip [-k] [-f] [-n] [-B bookmark] [-r] REV...
,而省略修订会给我abort: empty revision set
。
hg strip
不是最好的主意。这并不完全安全。试试看hg histedit
,甚至尝试使用Evolution扩展。
该衍合延长工作就像一个魅力。要压榨2次提交:
$ hg rebase --dest .~2 --base . --collapse
点是当前版本的快捷方式。
当您在一个分支上有几个提交并且想要将它们全部折叠成一个提交时,这甚至会更加容易:
$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse
工作原理:
(来自http://mercurial-scm.org/wiki/RebaseExtension#Collapsing)
如果您正在阅读此答案,则可以忘记此答案中提到的所有其他选项,并使用Evolution扩展中的
fold
命令。
evolve
是Mercurial的扩展,可帮助我们拥有安全的可变历史,但仍处于实验阶段。您可以通过从存储库中克隆它并将其添加到您的.hgrc中来使用它。
[extensions]
evolve = ~/evolve/hgext/evolve.py
假设您在主目录中克隆了进化仓库。现在你很好。您也可以通过寻找帮助hg help fold
。
您告诉fold
要压缩/折叠线性的提交链,但不会中断。折叠的作用是,它创建一个新的变更集,其中包含来自所有变更集的变更,并将所有那些提交标记为过时。您可以在docs上对此有更深入的了解。
现在假设您具有以下历史记录。
a -> b -> c -> d -> e -> f -> g
您想壁球e
,f
和g
。你可以做
hg up g
hg fold -r e
结果将是
a -> b -> c -> d -> h
h
变更集在哪里,其中包含所有三个提交的变更e
,f
以及g
。
您还可以从历史记录的中间折叠变更集,即不一定必须选择包含提示的链。假设您要折叠b
,c
并且d
。你可以做
hg up d
hg fold -r b
hg evolve --all
这将导致
a -> i -> j
其中i
是的折叠变更b
,c
,d
和j
是相同的修改集h
。
Evolve用户指南是必读的。
--keep
rebase选项可以解决此问题(随后将修订版标记为秘密,或者在检查结果后在其上使用Strip)。使用两个变基命令序列,甚至可以在其他版本之间移动版本。
使用Mercurial 4.8(2018年11月,9年后),您可以考虑使用新命令hg absorb
(以前是实验功能)。
请参阅“ 吸收Mercurial 4.8中的提交更改 ”
吸收扩展将在您的工作目录中进行每次更改,找出系列中的哪些提交修改了该行,并自动将更改修改为该提交。
如果有任何歧义(即在同一行上修改了多个提交),那么absorb将简单地忽略该更改,并将其保留在您的工作目录中以手动解决。在技术层面上,
hg absorb
查找所有未提交的更改,并尝试将每个更改的行映射到明确的先前提交。
对于可以清晰映射的每个更改,未提交的更改将吸收到适当的先前提交中。受操作影响的提交将自动重新设置基础。
如果更改无法映射到明确的先前提交,则将其保留为未提交,并且用户可以使用现有工作流程(例如使用hg histedit
)。的自动重写逻辑
hg absorb
是通过遵循以下行的历史记录来实现的:与hg histedit
或所采用的方法根本不同git rebase
,后者倾向于依赖基于三向合并的合并策略来在给定多个输入的情况下得出文件的新版本。版本。这种方法与hg Absorb跳过具有模糊应用程序提交的更改的事实相结合,意味着hg Absorb将永远不会遇到合并冲突!
现在,您可能会想,如果您忽略具有不明确应用目标的行,则该修补程序将始终使用经典的三路合并干净地应用。从逻辑上说,这句话是正确的。但是事实并非如此:
hg absorb
当合并执行失败hg histedit
或合并git rebase -i
失败时,可以避免合并冲突。
我认为chistedit
(自Mercurial 2.3起内置)最接近于rebase -i
纯Mercurial(chistedit
是的交互式版本histedit
)。一旦进入histedit,fold
命令将映射到rebase squash
,roll
命令将映射到rebase fixup
。有关更多信息,请参见histedit文档。
这是一个简单的例子。假设您具有以下内容,并且想要将所有1e21c4b1的更改都移至先前的修订版本中,而仅保留先前修订的消息。
@ 1e21c4b1 drees tip
| A commit you want to squash
o b4a738a4 drees
| A commit
o 788aa028 drees
| Older stuff
您可以运行hg chistedit -r b4a738a4
将历史记录编辑回b4a738a4。然后,在chistedit中,将光标向下移至1e21c4b1并单击r
以指示您要滚动该修订版。请注意,histedit(从最旧到最新)的顺序是从hg log
(最新到最旧)。
#0 pick 160:b4a738a49916 A commit
#1 ^roll 161:1e21c4b1500c
选择更改后,然后选择c
提交更改。结果如下:
@ bfa4a3be drees小贴士| 提交788aa028 drees | 较旧的东西
如果您不熟悉它们,那histedit
可能是一个更好的选择,chistedit
因为它在histedit文件中提供了命令描述以供参考。使用普通的文本编辑(就像普通的变基一样)来设置命令只需要更多的编辑。
请注意,要使用其中一个,histedit
或者chistedit
需要histedit
在〜/ .hgrc中添加扩展名:
[extensions]
histedit =
我建议,chistedit
因为它最接近rebase -i
历史并且可以在历史上的任何地方使用。如果您真的只想将当前修订包含/调整到以前的修订中,则@G。Demecki的strip
建议可能很好,因为正在发生的事情很明显。自Mercuria 2.8起内置。要获得与上述相同的结果,您可以执行以下操作:
hg strip .
hg add
hg commit --amend
注意strip
,像histedit一样,需要在〜/ .hgrc中启用:
[extensions]
strip =
假设您要压缩(合并)2个最新提交。
查找修订号
hg log -G -l 3
可能的输出:
@ changeset: 156:a922d923cf6f
| branch: default
| tag: tip
| user: naXa!
| date: Thu Dec 13 15:45:58 2018 +0300
| summary: commit message 3
|
o changeset: 155:5feb73422486
| branch: default
| user: naXa!
| date: Thu Dec 13 15:22:15 2018 +0300
| summary: commit message 2
|
o changeset: 154:2e490482bd75
| branch: default
~ user: naXa!
date: Thu Dec 13 03:28:27 2018 +0300
summary: commit message 1
软重置分支
hg strip --keep -r 155
再次提交更改
hg commit -m "new commit message"
strip
需要启用内置扩展。创建/编辑~/.hgrc
具有以下内容的配置文件:
[extensions]
strip =