我正在寻找git提交的对应部分——在Mercurial中修改,即一种方法来修改我的工作副本链接到的提交。我只对最后一次提交感兴趣,而不是任意更早的提交。

修订程序的要求如下:

if possible, it should not require any extensions. It must not require non-default extensions, i.e. extensions which do not come with an official Mercurial installation. if the commit to amend is one head of my current branch, no new head should be created. If the commit is not head, a new head may be created. the procedure should be safe in a way that if for whatever reasons the amending fails, I want to have the same working copy and repository state restored as before the amending. With other words, if the amending itself can fail, there should be a fail-safe procedure to restore the working copy and repository state. I'm referring to "failures" which lie in the nature of the amend-procedure (like e.g. conflicts), not to file-system-related problems (like access restrictions, not being able to lock a file for writing, ...)

更新(1):

该过程必须是可自动化的,因此它可以由GUI客户端执行,而不需要任何用户交互。

更新(2):

工作目录中的文件不能被触摸(某些被修改的文件上可能存在文件系统锁)。这特别意味着,可能的方法在任何时候都不需要干净的工作目录。


你有3个选项来编辑提交在Mercurial:

Hg strip——keep——rev -1撤销最后(1)提交(s),所以你可以再做一次(更多信息请参阅这个答案)。 使用随Mercurial附带的MQ扩展 即使它没有随Mercurial一起发布,Histedit扩展也值得一提

您也可以在Mercurial wiki的编辑历史页面上查看。

简而言之,编辑历史真的很难,而且令人沮丧。如果你已经推动了你的改变,你几乎没有什么可以做的,除非你完全控制所有其他克隆。

我不是很熟悉git的commit - modify命令,但是AFAIK, Histedit似乎是最接近的方法,但遗憾的是它没有随Mercurial一起发布。MQ使用起来非常复杂,但是您几乎可以用它做任何事情。


我正在收听克泰克写的东西。更具体的解决方案1:

假设:

您已经提交了一个(!)变更集,但还没有推送它 你想修改这个变更集(例如,添加,删除或更改文件和/或提交消息)

解决方案:

使用hg rollback命令撤销上次提交 使用新的更改再次提交

回滚实际上撤消了上一个操作。它的工作方式非常简单:在HG中的正常操作只会追加到文件中;这包括提交。Mercurial会跟踪上一个事务的文件长度,因此可以通过将文件截短到原来的长度来完全撤销一个步骤。


假设您还没有传播您的更改,下面是您可以做的事情。

添加到你的.hgrc: (扩展) mq = 在你的存储库中: Hg qimport -r0:tip Hg qpop -a 当然你不需要从零版本或者弹出所有补丁开始,因为最后一个弹出(hg qpop)就足够了(见下文)。 删除.hg/patches/series文件中的最后一个条目,或者删除您不喜欢的补丁。重新排序也是可能的。 Hg qpush -a;Hg qfinish a 删除仍然在.hg/patches中的.diff文件(未应用的补丁)(在你的情况下应该是一个)。

如果你不想收回所有的补丁,你可以使用hg qimport -r0:tip(或类似的方法)编辑它,然后编辑东西并使用hg qrefresh将更改合并到堆栈的最上面的补丁中。阅读hg帮助qrefresh。

通过编辑.hg/patches/series,您甚至可以删除几个补丁,或重新排序一些补丁。如果你的最新版本是99,你可以使用hg qimport -r98:tip;hg qpop;[编辑系列文件];Hg qpush -a;Hg qfinish -a。

当然,这个过程是非常不鼓励和有风险的。在你这么做之前,把所有东西都备份一下!

作为旁注,我已经在仅私有存储库上做过无数次了。


在Mercurial 2.2版本中,您可以使用——amend选项和hg commit一起使用当前工作目录更新最后一次提交

从命令行引用:

The --amend flag can be used to amend the parent of the working directory with a new commit that contains the changes in the parent in addition to those currently reported by hg status, if there are any. The old commit is stored in a backup bundle in .hg/strip-backup (see hg help bundle and hg help unbundle on how to restore it). Message, user and date are taken from the amended commit unless specified. When a message isn't specified on the command line, the editor will open with the message of the amended commit.

最重要的是,这种机制是“安全的”,因为它依赖于相对较新的“阶段”特性,以防止更新会改变本地存储库之外已经可用的历史。


GUI等效hg提交—修改:

这也适用于TortoiseHG的GUI(我使用v2.5):

切换到‘Commit’视图,或者在工作台视图中,选择‘working directory’条目。 “提交”按钮有一个名为“修改当前修订”的选项(单击按钮的下拉箭头可以找到它)。

          ||
          ||
          \/

购者自慎:

这个额外的选项只会在mercurial版本至少为时启用 2.2.0,如果当前的修订不是公开的,不是一个补丁,没有 的孩子。[…] 单击该按钮将调用 'commit——amend'用于'修正'修订。

更多的信息在THG开发频道


Mercurial的最新版本包括了提供hg修正命令的evolve扩展。这允许修改提交而不丢失版本控制中的修改前历史。

hg amend [OPTION]... [FILE]... aliases: refresh combine a changeset with updates and replace it with a new one Commits a new changeset incorporating both the changes to the given files and all the changes from the current parent changeset into the repository. See 'hg commit' for details about committing changes. If you don't specify -m, the parent's message will be reused. Behind the scenes, Mercurial first commits the update as a regular child of the current parent. Then it creates a new commit on the parent's parents with the updated contents. Then it changes the working copy parent to this new combined changeset. Finally, the old changeset and its update are hidden from 'hg log' (unless you use --hidden with log).

有关evolve扩展的完整描述,请参阅https://www.mercurial-scm.org/doc/evolution/user-guide.html#example-3-amend-a-changeset-with-evolve。


可能不能解决最初问题中的所有问题,但由于这似乎是关于mercurial如何修改以前提交的事实上的帖子,我将添加我的2美分信息。

如果你像我一样,只希望修改之前的提交消息(修复拼写错误等)而不添加任何文件,这将工作

hg commit -X 'glob:**' --amend

如果没有包含或排除模式,hg提交将默认包括工作目录中的所有文件。应用pattern -X 'glob:**'将排除所有可能的文件,只允许修改提交消息。

从功能上讲,当index/stage中没有文件时,它与git commit——modify是一样的。


另一个解决方案是使用uncommit命令来排除当前提交的特定文件。

Hg uncommit[文件/目录]

当您想要保持当前提交并取消从提交中选择某些文件时,这是非常有用的(特别是对于已删除的文件/目录)。