我可以在Mercurial中压击犯规吗?


109

我有一对提交,实际上应该只是一个。如果我使用的是git,则可以使用:

git rebase -i <some-commit-before>

然后压扁它们。

我可以做一下吗?如果是这样,怎么办?

Answers:


88

是的,您可以使用Mercurial进行此操作,而无需通过扩展Changeset进行任何扩展。

或者,如果您想使用扩展名,则可以使用:


是的,我是在我对一般性问题的评论中喜欢的重复问题中剔除掉那个答案的。我认为这就是您的答案。
Ry4an Brase 09年

4
一点说明:Histedit扩展随Mercurial 2.3及更高版本一起分发。您只需要启用它。
Paidhi 2015年

1
在“级联变更集”文档中,使用了“回购”的抽象概念,我该如何引用那些概念?例如:hg -R oldrepo export ...产生“中止:未找到存储库oldrepo!
Aleksandr Levchuk 2015年

13
只是试图压缩2次提交。我真的需要一个包含10多个命令或其他扩展名的Wiki页面吗?
Aleksandr Levchuk

3
查看评论。Histedit现在是内置的,您只需启用它即可(因为没有默认命令会修改历史记录)
Ry4an Brase

43

我最喜欢的是hg strip --keep命令。然后我一次提交所有更改。

这对我来说是最快,最舒适的方式,因为我喜欢在日常工作中做很多小的事情;)


注意1:strip需要mq启用内置扩展。
注意2:我最喜欢的Git / Mercurial客户端(SmartGit / Hg)--keep在期间默认添加参数strip。更方便的是:它提供了称为join commits:]的选项


4
hg strip的完整命令是: 您要与最后一个hg strip --keep --rev [rev]rev
压缩

3
@NicolasForney不完全--rev是可选的,完整命令是hg strip --keep [rev]
G. Demecki 2014年

在3.3.3中,对我来说,修订是强制性的:hg help striphg strip [-k] [-f] [-n] [-B bookmark] [-r] REV...,而省略修订会给我abort: empty revision set
罗曼·斯塔科夫

3
使用hg strip不是最好的主意。这并不完全安全。试试看hg histedit,甚至尝试使用Evolution扩展。
马丁·汤姆森

对于git人来说似乎是最自然的方式;)
foo

32

衍合延长工作就像一个魅力。要压榨2次提交:

$ hg rebase --dest .~2 --base . --collapse

点是当前版本的快捷方式。

当您在一个分支上有几个提交并且想要将它们全部折叠成一个提交时,这甚至会更加容易:

$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse

工作原理:

在此处输入图片说明

(来自http://mercurial-scm.org/wiki/RebaseExtension#Collapsing


1
您在哪里找到两次提交的“〜2”?
米拉

1
在revsets主题中对此进行了说明,请参见hg help revsets。
markand 16/09/12

13

如果您正在阅读此答案,则可以忘记此答案中提到的所有其他选项,并使用Evolution扩展中fold命令。

evolve是Mercurial的扩展,可帮助我们拥有安全的可变历史,但仍处于实验阶段。您可以通过从存储库中克隆它并将其添加到您的.hgrc中来使用它。

[extensions]
evolve = ~/evolve/hgext/evolve.py

假设您在主目录中克隆了进化仓库。现在你很好。您也可以通过寻找帮助hg help fold

折叠命令

您告诉fold要压缩/折叠线性的提交链,但不会中断。折叠的作用是,它创建一个新的变更集,其中包含来自所有变更集的变更,并将所有那些提交标记为过时。您可以在docs上对此有更深入的了解。

现在假设您具有以下历史记录。

a -> b -> c -> d -> e -> f -> g

您想壁球efg。你可以做

hg up g
hg fold -r e

结果将是

a -> b -> c -> d -> h

h变更集在哪里,其中包含所有三个提交的变更ef以及g

您还可以从历史记录的中间折叠变更集,即不一定必须选择包含提示的链。假设您要折叠bc并且d。你可以做

hg up d
hg fold -r b
hg evolve --all

这将导致

a -> i -> j

其中i是的折叠变更bcdj是相同的修改集hEvolve用户指南是必读的。


似乎rebase涵盖了该扩展程序的大多数(也许是全部?)用例,当然也涉及该问题的一个用例。该扩展程序的杀手级功能是隐藏(而不是删除)您替换的修订版,但是--keeprebase选项可以解决此问题(随后将修订版标记为秘密,或者在检查结果后在其上使用Strip)。使用两个变基命令序列,甚至可以在其他版本之间移动版本。
亚瑟塔卡

...另外,如果您执行的操作非常复杂,则始终可以先克隆本地存储库以用作备份。考虑到这是多么稀有(希望如此!),与学习如何使用全新的扩展相比,它花费的精力更少。
亚瑟塔卡

“ NameError:未定义名称'execfile'”-这意味着Evolution是用Python 2编写的,这基本上是石器时代。
尼尔·G

1
@NeilG mercurial还不支持Python 3。
Pulkit Goyal,

2
@NeilG是的,Mercurial社区正在努力争取尽快获得py3支持。
Pulkit Goyal '18

1

使用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失败时,可以避免合并冲突。


0

我认为chistedit(自Mercurial 2.3起内置)最接近于rebase -i纯Mercurial(chistedit是的交互式版本histedit)。一旦进入histedit,fold命令将映射到rebase squashroll命令将映射到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 =

0

假设您要压缩(合并)2个最新提交。

  1. 查找修订号

    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
    
  2. 软重置分支

    hg strip --keep -r 155
    
  3. 再次提交更改

    hg commit -m "new commit message"
    

笔记

strip需要启用内置扩展。创建/编辑~/.hgrc具有以下内容的配置文件:

[extensions]
strip = 

-1

我用:

hg phase --draft --force -r 267
...
hg rebase --dest 282 --source 267 --collapse
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.