放弃更改而不删除历史记录


180

有一个提交只是行不通,所以我想放弃它而不将其从历史记录中删除

我已经从较早的修订版进行了更新并做出了承诺,因此创建了一个新的负责人。


我没有分支,我不需要分支,我只想简单地按原样继续使用新的头,没有花哨,没有合并,没有后顾之忧,只是忘记了上一个。

我似乎找不到解决方法,而且我开始相信它无法完成。我所发现的只是关于分支的东西,或是关于合并的东西。


1
它在您的存储库中,因此尚未从历史记录中删除。您已经创建了一个新的主管,因此您可以继续进行修订而不会出错。是什么阻止您继续使用新的头?
ataylor 2010年

您对分支机构的厌恶是什么?
Andres Jaan Tack

@Andres不是完全不喜欢分支。我只需要它就可以工作,而无需愚蠢的额外步骤来创建它来关闭它。
o0'。

任何人都在阅读-请注意,在这种情况下已经创建了一个分支。请注意此答案中给出的说明:stackoverflow.com/a/3692607/3195477
UuDdLrLrSs

Answers:


181

使用您要忘记的修订版本将您的存储库更新到开头,然后使用hg commit --close-branch将该分支(匿名)标记为已关闭。然后更新到您分支的负责人想要的,并继续工作。

如果使用-c选项hg heads,您仍然可以看到封闭的分支,但是默认情况下它不会显示,并且hg merge不会尝试与封闭的头合并。

您将需要使用hg push --force第一次将这个封闭的磁头推到另一个存储库中,因为在您推送时实际上是在远程存储库中创建其他磁头。因此,告诉Mercurial可以--force。拉紧头部的人不会受到任何警告的困扰。


3
@Niall C.仅在将其标记为命名分支时才行吗?我假设他的意思是默认设置
msarchet 2010年

但是...那是不对的,当我打电话时我仍然能列出两个头脑hg heads……我正在使用水银1.4.3,这是一个较新的功能吗?
o0'。

2
@msarchet:AFAIK,今天尝试一下,--close-branch不适用于匿名分支。它应该但不应该。我希望这会在将来的Mercurial版本中有所改变。匿名分支非常好,但是应该与命名分支一样一流。
Krazy Glew'1

4
@KrazyGlew:问题在于,“匿名”分支实际上只是第二个分支,其名称与其所基于的分支相同。您实际上并不是要关闭(命名)分支:您是在尝试放弃所做的更改。换句话说,hg branches仍应显示您所在的分支名称。与其尝试关闭分支,不如将您的匿名分支合并回原始分支,放弃所有更改。
StriplingWarrior 2012年

2
在我的情况下,我有一个名为default的分支(这是标准分支)和另一个名为default / master的分支(我认为由于远程仓库实际上是git)。汞更新默认/主; hg commit --close-branch; 汞更新默认为我工作。
MattD

68

我知道您目前不希望使用分支机构,但这正是您所做的。当您回到较早的版本并提交了有效的命令后,您创建了一个分支-一个未命名的分支,但是一个分支都一样。


保持原样进行并没有担心多头的问题,但没有问题,但是如果您要整理事物,以免一次不小心选错头,则可以杀死旧分支。

Mercurial文档中有一个不错的部分,它带您了解有关修剪死枝的许多选择。

我认为对您来说最好的选择是将旧分支标记为“已关闭”。如果您的老头是修订版“ 123”,则:

hg update -r 123
hg commit --close-branch -m 'Closing old branch'
hg update -C default

3
Blurgh-我进入后刚刚看到@Niall的回答。会支持Niall's的,而我的会在零分池中失败。:)
尼克·皮尔波因特

1
我更喜欢您的答案,它需要减少对merucrial的术语的了解(据我所知,它似乎被选择来混淆git用户)
tacaswell 2012年

8
大声笑是相反的!svn用户选择了mercurial的术语听起来很自然,而git的术语却令人困惑!反正,upvoting这个答案,因为它包含了最后一次更新-C
托比亚

2
为什么你需要-Chg update?似乎没有文件会被修改,因此没有它就可以工作。
最大

1
据我所知,您在任何地方都不需要-C。但是,如果在尝试更新时确实有重大更改,则会中止操作。
伊莱·艾伯特

21

首先,键入:

hg heads

想象一下,您列出了三个负责人:

changeset:   223:d1c3deae6297
user:        Your name  <your@email.com>
date:        Mon Jun 09 02:24:23 2014 +0200
summary:     commit description #3

changeset:   123:91c5402959z3
user:        Your name <your@email.com>
date:        Sat Dec 23 16:05:38 2013 +0200
summary:     commit description #2

changeset:   59:81b9804156a8
user:        Your name <your@email.com>
date:        Sat Sep 14 13:14:40 2013 +0200
summary:     commit description #1

假设您要保持最后一个磁头处于活动状态(223),然后关闭其余的磁头。

然后,您将执行以下操作:

闭头#59

hg up -r 59
hg ci --close-branch -m "clean up heads; approach abandoned"

闭头#123

hg up -r 123
hg ci --close-branch -m "clean up heads; approach abandoned"

提交更改

hg push

不要忘记最后切换到正确的头

hg up -r 223

这样就完成了。


这是一个不错的教程,但是示例提交消息有点元。我将提供更好的示例,以便那些向您学习的人可以提供更好的提交消息。有点像--close-branch -m "Closing branch - technique #2 abandoned in favor of technique #3"
詹森·库姆斯

5
另外,您的排序工作已经结束,除了您的工作副本仍位于刚关闭的头上。承诺另一个变化将发生在封闭的头部,然后重新打开。您需要hg up -r 223先进行任何更改。
杰森·库姆斯

@Jason R. Coombs:对!
Artur Barseghyan,2015年

根据@Niall以及我现在的经验,您将需要hg push --force,而不仅仅是hg push克服关于多头的警告。
craq

1
@Artur我普遍同意。在这种情况下,hg push它本身对我不起作用。如果外部仓库因多个头而拒绝,您如何建议将更改推送到外部仓库?
craq

12

您要使用hg backout。这将从所有子变更集中删除变更集所做的更改。

检查一下,以获得良好的解释。 汞回收


2
这是正确的答案。回退添加变更集的逆函数,取消工作并向您提供提交消息,以提醒您自己为什么不喜欢这个主意。
Ry4an Brase

7
我实际上不同意-放弃工作,从一个好的起点重新开始,这似乎比使用退出更干净。特别是因为您一次不能撤消多个变更集。
Martin Geisler 2010年

1
@马丁·盖斯勒(Martin Geisler),我一般都同意这一点,但是OP表示他想放弃没有分支机构的变更
msarchet 2010年

2
@Martin Geisler是的,我全力以赴,只是有时会
浪费一些

1
有时可能有用,但这并不是我真正想要的。无论如何,谢谢:)
o0'。

2

尼尔和尼克的答案都是直接的。因为我发现自己创建了许多悬垂的头部,所以我最终写了一个别名来更轻松地闭合头部。通过添加到您的.hgrc

[alias]
behead = !REV=$($HG id -i); $HG update $@ -q && $HG ci --close-branch -m "Closing dead head" && $HG update $REV -q

(如果您已有一个[alias]版块,则可以附加到该版块)

现在,您可以在一个命令中关闭头部(而不必手动更新到其他变更集),如下所示:

$ hg behead 123

注意:别名利用了Mercurial别名可以是shell命令的事实。这意味着这可能仅适用于UNIX,不适用于Windows。


2

关闭或剥离不需要的分支的替代方法是将其合并,以完全丢弃其影响,但将其保留在历史中。这种方法将允许那些不需要的更改在推送中传播-因此,只有在达到预期效果时才使用此方法。

假设变更集的历史记录如下所示:

1-2-3-4-5-6    
       \    
        7-8-*

现在是56不再需要。

你可以这样做:

hg up 8
hg merge -r 6 -t :local
hg commit ...

这将创建以下内容:

1-2-3-4-5-6    
       \   \
        7-8-9-*

此更新可8确保您在想要保留的历史记录中处于所需的位置。

-t :local指令指示hg使用称为本地的合并“工具” ,该工具告诉它忽略来自另一个分支的更改,即,当前工作文件夹状态所表示的NOT。更多信息

因此,在不需要的变化5,并6保留在历史,但不影响任何东西更近一些。


2

这是Evolve扩展的用例。目前尚未与Mercurial捆绑在一起,因此从技术上讲它是第三方扩展。但是,包括Mercurial开发人员在内的许多人都在大量使用它,并且正在非常积极地开发它,并且它不会一事无成。

使用Evolve扩展程序,您只需

hg prune -r revname

并继续生活。cset仍将在那里,但已过时。除非您通过--hidden选项给Mercurial命令,,并且默认情况下不会将其推送到远程存储库。虽然我认为您可以强制执行此操作。

如果要修剪的cset具有要保留的祖先,则必须运行hg evolve以重新设置这些变更集的基准。hg evolve将自动执行此操作。否则,您无需执行任何操作。


1

您可以将损坏的存储库克隆到一个新的存储库中,而无需克隆那个不需要的头。然后删除旧存储库,将新创建的克隆移动到原始位置,然后继续使用它。这将花费一些时间,但是您将获得一个完全干净的存储库,而没有任何不必要的修订迹象。

hg clone --rev myGoodResition myDirtyRepo myCleanRepo

1
对不起,这完全不是我问的。
o0'。

4
@Kristof:这是个玩笑吗?重新阅读我的帖子的第一行“放弃它而不将其从历史记录中删除
o0'。

-1

当我要斩首一个错误创建的头部时,我已经多次遇到此问题。我一直想看到它从地球表面消失。

在本地副本上,获取最新版本,然后:

  1. 找到要剥离的头的起点(新的脖子开始分支),获取修订号

  2. 剥离它。


资料来源:TipsAndTricks

来源:PruningDeadBranches#Using_strip

hg --config extensions.hgext.mq= strip -n <rev>
  1. 进行简单的文件更新(在文件中添加空格),提交并推送。

现在,您的仓库已经剥了头。最后一步很重要,因为剥离不会创建任何可推送到中央存储库的更改。如果没有最后一步,您只能在本地剥离头部。


1
但是,推送永远不会从远程存储库中删除任何内容。它只会添加信息。如果变更集已经在中央存储库中,则您需要使用Evolution扩展,或者以某种方式在中央服务器本身上剥离它。如果更改集尚未在中央存储库中,则在本地进行剥离就足够了,而无需任何推送。
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.