【问题标题】:How to get rid of some changeset in Hg?如何摆脱汞的一些变化?
【发布时间】:2010-11-13 13:34:18
【问题描述】:

嘿,我想恢复 Hg 中的一些变更集,但我很难做到。

我无意中进行了一些更改,所以我想撤消它。在尝试了一点之后,我能够hg backout,但它创建了一个新的提交。现在,我希望我的 repo 进入初始状态(没有最后 2 次提交并且我在工作目录中进行了更改)。显然没有办法做到这一点(类似于git reset --soft)。有吗?

我尝试的另一件事是删除最新的提交(恢复原始提交的那个)。这将类似于git reset --hard,但同样没有办法做到这一点。我可以hg update -C,但这更像是git checkout,因为提交仍然存在。

而且,hg update -C -r X 将我恢复到修订版 X,但是当我检查 hg log 时,我无法知道我现在处于哪个修订版。唯一的方法是检查我的 bash 历史记录,对吗?一定有办法知道这一点。

无论如何,我一直在尝试解决这个问题,但找不到任何可以解决它的方法。我发现比较 git 和 hg 命令的参考资料并不准确,因为这些命令的行为并不完全相同。

我想我只是想知道git reset --hard git reset --soft...

谢谢。

【问题讨论】:

  • 这不是您的主要问题的答案,但要查看您所在的修订版,请执行hg summary。如果您想查看修订版,请给它一个安静的标志:hg summary -q

标签: git mercurial


【解决方案1】:

Mercurial 故意不让这件事变得简单。 Mercurial 的理念是提交的代码应该继续存在——记录没有解决的问题几乎与记录执行的记录一样重要。最好对你的工作进行否定(这是backout 所做的)并且仍然拥有记录而不是实际丢弃它。

但是,如果您无法保留该更改(好的原因:它包含一个您无法更改的密码,坏的原因:它只是没有成功)您有几个选择:

  • strip:我不喜欢 strip 它会修改存储库并且不会将内容放回工作目录中。出于某种原因,Strip 默认被禁用。
  • 克隆:只需执行hg clone -r LASTCHANGESETYOULIKE oldrepo newrepo,现在 newrepo 就拥有了包括 LASTCHANGESETYOULIKE 在内的所有内容。归档 oldrepo 并将 newrepo 重命名为 oldrepo。
  • rollback:这是 mercurial 世界的一级撤销。它会在你完成后立即撤消你的提交,但如果你已经完成了任何其他拉取或提交,它就不起作用了。

【讨论】:

  • 酷。非常感谢您的回答。它澄清了很多事情。最后一个问题:是否有任何命令可以撤消对工作目录的提交? (比如 git reset --soft)——这样做的原因是为了更容易使用我最喜欢的 diff 软件来检查提交的内容。
  • hg rollback 就像git reset --soft HEAD^
  • 是的,就像 wRAR 说的,rollback 是一级撤消,所以它会撤消一次提交(前提是你从那以后没有拉过)。但是,请查看 extdiff 扩展——它应该让您可以轻松地将最后一次提交与工作目录进行比较,而无需提交只是为了做到这一点。
  • @wRAR hg rollback 不像 git reset --soft HEAD^。如果出现问题,您将无法撤消 hg rollback
  • @JohnGietzen,我猜你当前首选的编程语言不会直接写入任意内存地址,并不是因为它们没用,而是因为它们“非常锋利”。它甚至可能不会使它们成为可能。 Mercurial 将“不变性”作为设计决策不是因为他们不信任您,而是因为当您接受不变性时,其他一些非常困难的事情会变得更容易。正如 lisp/ml/haskell/clojure 的人一样。他们不会避免可变性,因为它是“尖锐的”。另请参阅:mercurial.selenic.com/wiki/Phases。我使用 git 和 hg,它们都很棒。
【解决方案2】:

这里是如何做git reset --soft。让我们假设您有这样的图表:

... --- [A] --- [B] --- [X] --- [-X]

其中X 是错误提交,-X 是您所做的退出。您现在想要摆脱X-X,同时让工作副本看起来像您提交X 时所做的那样。你会的

$ hg update B
$ hg revert --all --rev X # working copy now looks just like in X
$ hg strip --force X      # get rid of X and -X

如果需要,您可以使用 Mercurial 1.7 为其创建别名:

[alias]
softreset = !hg update 'p1($1)' &&
             hg revert --all --rev $1 &&
             hg strip --force $1

hg revert 之后的脏工作副本使得必须使用hg strip --force。您将这个新命令用作

$ hg softreset 10

这将删除 10 和任何后代,同时将 10 中的更改保留在工作副本中。您当然可以更进一步并实现hg reset 命令:

[alias]
reset = !test "$1" = "--hard" && hg strip $2 || hg softreset $2

这些别名的最大问题是糟糕的错误处理。用 Python 编写的扩展会更加健壮和可维护——也许您可以制作这样一个“重置”扩展并将其发布到 Bitbucket 上:)

【讨论】:

    【解决方案3】:

    mq 扩展中查看hg strip

    【讨论】:

    • 酷,hg strip 完成了重置 --hard 工作。
    • 无法让它像 git reset --soft tho 一样工作...(将更改保留在工作目录中)
    【解决方案4】:

    您已经得到了一些很好的答案,但还有几点需要注意:

    • 如果您有未提交的本地更改,shelve 会将它们放在一边供您稍后检索
    • 如果您的变更集已被推送到另一个存储库,那么没有编辑两个存储库,您唯一的选择是回退
    • 回退允许您创建与原始变更集相反的新变更集,在不更改存储库历史记录的情况下摆脱不需要的变更
    • 如果您尚未推送到远程存储库,回滚通常是您的最佳选择,因为它会消除变更集,同时保持您的工作副本完好无损
    • Strip 将删除整个更改分支,但与回滚一样,只有在您没有将更改推送到其他任何地方时,它才会消失
    • 将存储库克隆到以前的版本也是如此 - 无论如何,其他工具更容易

    【讨论】:

      【解决方案5】:

      不确定 git 的东西,但是如果你还没有推送,可以使用hg rollback。如果你已经推动了,那么你真的无能为力。

      关于当前版本,请参阅hg id

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-22
        相关资源
        最近更新 更多