【问题标题】:Mercurial cherry picking changes for commit提交的 Mercurial 樱桃采摘更改
【发布时间】:2010-10-25 16:35:51
【问题描述】:

比如说,我对我的代码做了很多更改,只需要提交其中的一些更改。有没有办法在 mercurial 中做到这一点?我知道darcs 有这样一个功能。

我知道hg transplant 可以在分支之间执行此操作,但我需要这样的东西来在当前分支中提交代码,而不是在从其他分支添加更改集时。

【问题讨论】:

  • 我最近问过这个问题。我不知道这个术语,所以我在搜索时没有找到这个。请参阅我的问题的已接受答案,该问题涉及汞移植,Mercurial 2.0 中的新功能。 stackoverflow.com/questions/10288482/…

标签: mercurial change-management


【解决方案1】:

如果您在 Windows 上使用 TortoiseHg 1.xthis feature is implemented beautifully 开箱即用(无需扩展)。

  1. 运行 TortoiseHg 提交工具。
  2. 选择一个您只为 想要提交它的一个子集 变化。
  3. 点击大块头 预览窗格中的选择选项卡。
  4. 双击或使用空格键 切换应该是哪些变化 包含在提交中。

对于 TortoiseHg 2.x,Hunk Selection 选项卡现已消失。取而代之的是Shelve tool。它比旧的大块选择具有更多功能。这些新功能是以增加一些复杂性为代价的。

请注意,使用此功能时无需显式启用 Mercurial Shelve 扩展。根据 response to a different TortoiseHg question 中的 Steve Borho(TortoiseHg 首席开发人员)的说法:“我们有一个搁置扩展的本地副本,可以直接调用它。”


对于 TortoiseHg 2.7+,此功能已得到改进并重新引入。它现在直接内置到 Commit 工具中:

注意在左边的文件列表中,顶部的文件被选中表示将被包含,第二个文件未被选中,因为它不会被包含,第三个文件 Sample.txt 被填充(Null复选框指示器),因为只有从该文件中选择的更改才会包含在提交中。

将包含的对 Sample.txt 的更改在图像的右下角更改选择部分进行检查。将被排除的更改未选中,差异视图显示为灰色。另请注意,搁置工具的图标仍然可用。

【讨论】:

  • 啊哈,这就是为什么我不明白为什么这是一个问题。如果您不使用 TortoiseHg,这并不容易。我不知道。
  • 我们这些使用版本 2 的人呢? tortoisehg.bitbucket.org/manual/2.0/commit.html 没有我可以看到的大块选择选项卡。
  • @alsuren 和其他人:从 TortoiseHg 2.7 开始,重新引入了 TortoiseHg 1.x 的旧工作流程。有关详细信息,请参阅更新的答案。
  • 有没有人看到大块选择未能显示具有大量更改的文件的大块?提交和搁置差异显示出一个很大的差异,而不是多个大块头。外部差异应用程序可以很好地显示各个差异。这只是在过去一个月才开始发生的。
  • 有点复活,但我注意到在 THG 3.3 中这现在已从提交中删除并重新搁置。出于好奇,有人知道这是什么原因吗?
【解决方案2】:

我相信 Mercurial Queues 担任 Mercurial 的这个角色。那里有a pretty good tutorial 链接。

【讨论】:

  • 这似乎可以满足我的要求,但是如果该过程像 hg 移植命令那样更具交互性,那就太好了。
【解决方案3】:

Chad 提到的 MQ 是一种方法。还有更轻量级的解决方案:

  • Record extension 的工作方式与 darcs 记录大致相同。它与 mercurial 一起分发。
  • Shelve extension 允许您“搁置”某些更改,允许您仅提交更改的子集(未搁置的更改)

【讨论】:

【解决方案4】:

已经过了一段时间。现在看来最好的选择是hg commit --interactive

【讨论】:

    【解决方案5】:

    您可以使用随 Mercurial 分发的 record extension

    您需要先在~/.hgrc 文件中启用它,方法是将其添加到[extensions] 部分:

    [extensions]
    record=
    

    然后,只需输入hg record 而不是hg commit,您就可以选择要提交哪些更改到哪些文件。

    您还可以使用crecord extension,它提供了一个更好的界面来查看和选择更改。 (不过,它并没有随 Mercurial 一起分发,而且我看到它偶尔会弄乱提交,所以它不是完全没有错误的。)

    【讨论】:

    • crecord 相对于记录的优势在于您可以选择 parts 块。而且界面也更好:D
    • 记录扩展页面显示此扩展已弃用,该功能现在作为 hg commit --interactive 成为 Mercurial 核心的一部分。见this answer
    【解决方案6】:

    首先你必须忘记你曾经知道的关于 GUI 的一切并返回到命令行。接下来从命令行执行此操作:

    hg stat > filelist.txt

    这会将您修改的所有文件通过管道传输到一个名为 filelist.txt 的文本文件中

    接下来编辑您的文件列表以仅包含您希望提交的文件。

    最后使用文件集 sytnax 提交:

    hg commit "set: 'listfile:test.txt'"

    【讨论】:

      【解决方案7】:

      我觉得我错过了一些东西,因为已经没有人提出这个建议了。

      普通的“hg commit”命令可用于选择性地选择要提交的内容(您不必提交本地工作目录中的所有未决更改)。

      如果您有一组这样的更改:

      M ext-web/docroot/WEB-INF/liferay-display.xml
      M ext-web/docroot/WEB-INF/liferay-portlet-ext.xml
      M ext-web/docroot/WEB-INF/portlet-ext.xml
      

      您可以只提交其中两个更改...

      hg commit -m "partial commit of working dir changes" ext-web/docroot/WEB-INF/liferay-display.xml ext-web/docroot/WEB-INF/liferay-portlet-ext.xml
      

      从命令行不是很方便,因为您必须手动键入文件才能有选择地提交(相对于像乌龟这样的 GUI 复选框过程),但它几乎一样简单,不需要扩展。并且文件通配可能有助于减少打字(就像上面那样,两个提交的文件在其路径名中唯一地共享“liferay”。

      【讨论】:

      • 许多其他答案仅处理每个文件中的选择更改(尽管尚不清楚问题是否需要这样做,因此请点赞)
      【解决方案8】:

      我使用commit-patch。这是一个脚本,可让您在提交之前编辑差异。 Emacs 的 diff-mode 和 vc-mode 真的很棒。

      以前我用过crecord,但是有unicode相关的bug(其实record extension有bug,crecord依赖)。

      【讨论】:

        【解决方案9】:

        试试 qct(Qt 提交工具)。它有一个“选择更改”功能,可以启动一个 3 向合并工具,让您撤消单个更改。提交后,您“撤消”的更改会回来。

        【讨论】:

          【解决方案10】:

          Mercurial Queues 教程对于这个用例来说太糟糕了。我看到的所有示例都假设您尚未提交并且正在刷新单个补丁。大多数时候情况并非如此,您有 2 或 3 个提交要压缩在一起或以其他方式更改。

          假设你有这样的历史:

          ---O---O---A---B---C
          

          第一个示例是压缩提交 A、B 和 C。首先 init mq:

          $ hg qinit
          

          现在我们需要将提交 A、B 和 C “导入”到补丁队列中。让我们假设它们是最后 3 次提交。我们可以使用“-N”修订语法来导入它们,如下所示:

          $ hg qimport -r -3:-1
          

          这意味着作为补丁从 3 个补丁导入到最后一次提交。您可以使用hg qseries 检查这些补丁的状态。它应该显示如下内容:

          $ hg qseries
          101.diff
          102.diff
          103.diff
          

          其中数字 101、102 和 103 对应于提交 A、B 和 C 的本地修订号。现在这些补丁已应用,这意味着它们描述的更改已经在工作副本。您可以使用hg qpop 摆脱工作副本的更改并将它们从提交历史中删除,仅以补丁形式保存它们。您可以说hg qpop; hg qpop 将更改C 和B 从堆栈中弹出,或者指定一个补丁来“弹出”。在这种情况下,它会是这样的:

          $ hg qpop 101.diff
          now at: 101.diff
          

          您现在在补丁队列中拥有提交 B 和 C 的补丁,但它们并未应用(它们的更改已“丢失” - 它们仅存在于补丁队列区域中)。现在您可以将这些补丁合并到最后一个中,即我们创建一个新的提交,相当于更改 A+B+C 的总和。

          $ hg qfold -e 102.diff 103.diff
          

          这将显示您的编辑器,以便您更改提交消息。默认情况下,消息将是更改 A、B 和 C 的提交消息的串联,由星号分隔。这里的好处是hg qfold 将在您使用 bash 并获取 hg-completion 脚本的情况下完成补丁。这留下了这样的历史,其中 A+B+C 是一个单一的提交,它是我们感兴趣的 3 个补丁的组合:

          ---O---O---A+B+C
          

          另一个用例是如果我们有与以前相同的历史记录,但我们想删除补丁 B 并合并 A+C。这实际上与上面非常相似。当您进入 qfold 步骤时,您只需折叠最后一次提交而不是最后 2 次提交:

          $ hg qfold -e 103.diff
          

          这会将 B 的更改留在补丁队列中,但它不会应用于工作副本,并且它的提交不在历史记录中。你可以通过运行看到这一点:

          $ hg qunapplied
          102.diff
          

          历史现在看起来像这样,其中 A+C 是一个合并了更改 A 和 C 的单个提交:

          ---O---O---A+C
          

          最后一个用例可能是您只需要应用提交 C。您可以通过运行上面的 qimport 来做到这一点,并且您会弹出所有您不想要的补丁:

          $ hg qpop -a
          

          -a 标志意味着弹出所有补丁。现在您可以只申请您想要的:

          $ hg qpush 103.diff
          

          这会给你留下这段历史:

          ---O---O---C
          

          完成所有这些后,您需要完成队列摆弄。这可以通过以下方式完成:

          $ hg qfinish -a
          

          所以我们到了。您现在可以运行 hg push 并仅提交您想要的内容,或者 hg email 向邮件列表发送一个连贯的补丁。

          【讨论】:

            猜你喜欢
            • 2012-12-07
            • 1970-01-01
            • 2011-03-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-03-02
            相关资源
            最近更新 更多