Mercurial:如何修改最后一次提交?

发布于 2024-12-17 02:42:19 字数 680 浏览 0 评论 0原文

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

此修改程序的要求是:

  • 如果可能,不应要求任何扩展。它不能不需要非默认扩展,即不随官方 Mercurial 安装一起提供的扩展。

  • 如果要修改的提交是我当前分支的一个头,则不应创建新头。如果提交不是头,则可能会创建一个新头。

  • 该过程应该安全,如果由于某种原因修改失败,我希望恢复与修改之前相同的工作副本和存储库状态。换句话说,如果修改本身可能失败,则应该有一个故障安全程序来恢复工作副本和存储库状态。我指的是修改过程本质上的“失败”(例如冲突),而不是与文件系统相关的问题(例如访问限制、无法锁定文件进行写入等) )

更新 (1):

  • 该过程必须可自动化,因此可以由 GUI 客户端执行,无需任何用户交互。

更新(2):

  • 工作目录中的文件不得被触及(某些修改的文件可能存在文件系统锁定)。这尤其意味着,可能的方法可能根本不需要干净的工作目录。

I'm looking for a counter-part of git commit --amend in Mercurial, i.e. a way to modify the commit which my working copy is linked to. I'm only interested in the last commit, not an arbitrary earlier commit.

The requirements for this amend-procedure are:

  • 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, ...)

Update (1):

  • the procedure must be automatable, so it can be performed by a GUI client without any user interaction required.

Update (2):

  • files in the working directory must not be touched (there may be file system locks on certain modified files). This especially means, that a possible approach may at no point require a clean working directory.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

撞了怀 2024-12-24 02:42:19

现在,您可以使用 --amend 选项和 hg commit 来更新当前工作目录中的最后一次提交,自 Mercurial 2.2

来自命令行参考

--amend 标志可用于使用新提交修改工作目录的父目录,其中包含父目录中的更改以及 hg status 当前报告的更改(如果有)。旧的提交存储在 .hg/strip-backup 的备份包中(有关如何恢复它的信息,请参阅 hg help bundle 和 hg help unbundle)。

除非另有说明,消息、用户和日期均取自修改后的提交。当命令行上未指定消息时,编辑器将打开并显示修改后的提交的消息。

最棒的是,这种机制是“安全的”,因为它依赖于“Phases”功能 防止更新会更改已在本地存储库之外提供的历史记录。

You can now use the --amend option with hg commit to update the last commit with the current working directory, since the release of Mercurial 2.2.

From the command line reference:

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.

The great thing is that this mechanism is "safe", because it relies on the "Phases" feature to prevent updates that would change history that's already been made available outside of the local repository.

岁月静好 2024-12-24 02:42:19

您有 3 个选项可以在 Mercurial 中编辑提交:

  1. hg strip --keep --rev -1 撤消最后 (1) 次提交,以便您可以再次执行此操作(请参阅< a href="https://stackoverflow.com/a/31277388/264675">此答案了解更多信息)。

  2. Mercurial 附带的 MQ 扩展

  3. 即使未随 Mercurial 一起提供Mercurial,Histedit 扩展值得一提

您还可以查看Mercurial wiki 的编辑历史记录页面。

简而言之,编辑历史确实很困难并且令人沮丧。如果您已经推送了更改,那么您几乎无能为力,除非您完全控制所有其他克隆。

我不太熟悉 git commit --amend 命令,但据我所知,Histedit 似乎是最接近的方法,但遗憾的是它没有随 Mercurial 一起提供。 MQ 使用起来确实很复杂,但您几乎可以用它做任何事情。

You have 3 options to edit commits in Mercurial:

  1. hg strip --keep --rev -1 undo the last (1) commit(s), so you can do it again (see this answer for more information).

  2. Using the MQ extension, which is shipped with Mercurial

  3. Even if it isn't shipped with Mercurial, the Histedit extension is worth mentioning

You can also have a look on the Editing History page of the Mercurial wiki.

In short, editing history is really hard and discouraged. And if you've already pushed your changes, there's barely nothing you can do, except if you have total control of all the other clones.

I'm not really familiar with the git commit --amend command, but AFAIK, Histedit is what seems to be the closest approach, but sadly it isn't shipped with Mercurial. MQ is really complicated to use, but you can do nearly anything with it.

栩栩如生 2024-12-24 02:42:19

GUI 相当于 hg commit --amend

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

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

在此处输入图像描述

          ||
          ||
          \/

在此处输入图片描述

买者自负

仅当 Mercurial 版本至少为
2.2.0,如果当前修订版不是公开的,则不是补丁并且没有
孩子们。 [...]

点击按钮会调用
'commit --amend' 来“修改”修订版。

有关此内容的更多信息请访问 THG 开发频道

GUI equivalent for hg commit --amend:

This also works from TortoiseHG's GUI (I'm using v2.5):

Swich to the 'Commit' view or, in the workbench view, select the 'working directory' entry.
The 'Commit' button has an option named 'Amend current revision' (click the button's drop-down arrow to find it).

enter image description here

          ||
          ||
          \/

enter image description here

Caveat emptor:

This extra option will only be enabled if the mercurial version is at least
2.2.0, and if the current revision is not public, is not a patch and has no
children. [...]

Clicking the button will call
'commit --amend' to 'amend' the revision.

More info about this on the THG dev channel

画尸师 2024-12-24 02:42:19

我正在听 krtek 写的内容。更具体地说,解决方案 1:

假设:

  • 您已经提交了一个 (!) 变更集,但尚未推送它,但
  • 您想要修改此变更集(例如添加、删除或更改文件和/或提交消息)

解决方案:

  • 使用hg rollback撤消上次提交,
  • 并在新更改到位的情况下再次提交

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

I'm tuning into what krtek has written. More specifically solution 1:

Assumptions:

  • you've committed one (!) changeset but have not pushed it yet
  • you want to modify this changeset (e.g. add, remove or change files and/or the commit message)

Solution:

  • use hg rollback to undo the last commit
  • commit again with the new changes in place

The rollback really undoes the last operation. Its way of working is quite simple: normal operations in HG will only append to files; this includes a commit. Mercurial keeps track of the file lengths of the last transaction and can therefore completely undo one step by truncating the files back to their old lengths.

雪落纷纷 2024-12-24 02:42:19

假设您尚未传播您的更改,您可以执行以下操作。

  • 添加到您的 .hgrc:

    <前><代码>[扩展名]
    MQ =

  • 在您的存储库中:

    <前><代码>hg qimport -r0:提示
    hg qpop -a

    当然,您不需要从版本零开始或弹出所有补丁,因为最后一个弹出(hg qpop)就足够了(见下文)。

  • 删除 .hg/patches/series 文件中的最后一个条目,或您不喜欢的补丁。也可以重新排序。

  • hg qpush -a; hg qfinish -a
  • 删除仍在 .hg/patches 中的 .diff 文件(未应用的补丁)(您的情况应该是一个)。

如果您不想收回所有补丁,您可以使用hg qimport -r0:tip(或类似的),然后编辑内容并使用 hg qrefresh 将更改合并到堆栈最顶层的补丁中。阅读hg help qrefresh

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

当然,这个过程是非常不鼓励的并且有风险。在执行此操作之前备份所有内容!

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

Assuming that you have not yet propagated your changes, here is what you can do.

  • Add to your .hgrc:

    [extensions]
    mq =
    
  • In your repository:

    hg qimport -r0:tip
    hg qpop -a
    

    Of course you need not start with revision zero or pop all patches, for the last just one pop (hg qpop) suffices (see below).

  • remove the last entry in the .hg/patches/series file, or the patches you do not like. Reordering is possible too.

  • hg qpush -a; hg qfinish -a
  • remove the .diff files (unapplied patches) still in .hg/patches (should be one in your case).

If you don't want to take back all of your patch, you can edit it by using hg qimport -r0:tip (or similar), then edit stuff and use hg qrefresh to merge the changes into the topmost patch on your stack. Read hg help qrefresh.

By editing .hg/patches/series, you can even remove several patches, or reorder some. If your last revision is 99, you may just use hg qimport -r98:tip; hg qpop; [edit series file]; hg qpush -a; hg qfinish -a.

Of course, this procedure is highly discouraged and risky. Make a backup of everything before you do this!

As a sidenote, I've done it zillions of times on private-only repositories.

脸赞 2024-12-24 02:42:19

Mercurial 的最新版本包含 evolve 扩展,它提供了 hg amend 命令。这允许修改提交而不会丢失版本控制中的预修改历史记录。

hg 修改 [选项]...[文件]...

别名:刷新

将变更集与更新合并并用新变更集替换

提交一个新的变更集,其中包含对给定文件的更改
以及当前父变更集到存储库中的所有更改。

有关提交更改的详细信息,请参阅“hg commit”。

如果不指定-m,则将重用父级的消息。

在幕后,Mercurial 首先作为普通子项提交更新
当前父级的。然后它在父级上创建一个新的提交
家长们可以了解最新的内容。然后它更改工作副本父级
到这个新的组合变更集。最后,旧的变更集及其更新
从“hg log”中隐藏(除非您使用 --hidden 和 log)。

请参阅 https://www.mercurial-scm.org/doc/evolution/user-guide.html#example-3-amend-a-changeset-with-evolve 了解 的完整说明>进化扩展。

Recent versions of Mercurial include the evolve extension which provides the hg amend command. This allows amending a commit without losing the pre-amend history in your version control.

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).

See https://www.mercurial-scm.org/doc/evolution/user-guide.html#example-3-amend-a-changeset-with-evolve for a complete description of the evolve extension.

微暖i 2024-12-24 02:42:19

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

如果您像我一样,只想修改以前的提交消息(修复拼写错误等)而不添加任何文件,那么这将起作用

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

没有任何包含或排除模式 hg commit 默认情况下将包含所有文件在工作目录中。应用模式 -X 'glob:**' 将排除所有可能的文件,只允许修改提交消息。

当索引/阶段中没有文件时,它的功能与 git commit --amend 相同。

Might not solve all the problems in the original question, but since this seems to be the de facto post on how mercurial can amend to previous commit, I'll add my 2 cents worth of information.

If you are like me, and only wish to modify the previous commit message (fix a typo etc) without adding any files, this will work

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

Without any include or exclude patterns hg commit will by default include all files in working directory. Applying pattern -X 'glob:**' will exclude all possible files, allowing only to modify the commit message.

Functionally it is same as git commit --amend when there are no files in index/stage.

羁绊已千年 2024-12-24 02:42:19

另一种解决方案是使用 uncommit 命令从当前提交中排除特定文件。

hg uncommit [file/directory]

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

Another solution could be use the uncommit command to exclude specific file from current commit.

hg uncommit [file/directory]

This is very helpful when you want to keep current commit and deselect some files from commit (especially helpful for files/directories have been deleted).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文