水星版本控制系统中的挑选更改以进行提交

61

假设我对代码进行了多处修改,但只需要提交其中几处更改。在mercurial中是否有这样的方法?我知道darcs有类似的功能。

我知道hg transplant可以在不同分支之间完成这个操作,但我需要在当前分支提交代码时使用这样的功能,而不是从其他分支添加变更集。


2
我最近因为重复问题而提出了这个问题。由于我不知道术语,所以在搜索时没有找到相关内容。请参考我的问题中被接受的答案,其中涉及到Mercurial 2.0中新增的hg graft功能。https://dev59.com/WWkv5IYBdhLWcg3w4kp2 - oob
10个回答

37

如果您正在使用Windows的TortoiseHg 1.x,那么此功能已经在开箱即用时实现得非常好(无需扩展)。

  1. 运行TortoiseHg提交工具。
  2. 选择一个文件,仅想提交其更改的子集。
  3. 单击预览窗格中的Hunk选择选项卡。
  4. 双击或使用空格键切换应包括在提交中的更改块。

在TortoiseHg 2中,Hunk Selection选项卡被暂时移除了。取而代之的是Shelve工具。它比旧的hunk selection有更多的功能。这些新功能增加了一些复杂性。

enter image description here

请注意,在使用此功能时,无需显式启用Mercurial Shelve扩展。根据Steve Borho(TortoiseHg主要开发人员)在回答不同的TortoiseHg问题中所说:“我们有一个shelve扩展的本地副本,并直接调用它。”

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

example of change selection in the commit tool

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

将被包含的Sample.txt更改在图像右下角的更改选择部分中被选中。将被排除的更改未被选中,并且差异视图已变灰。还请注意,工具架工具的图标仍然可以轻松使用。


1
啊哈,所以这就是我不明白为什么这是一个问题的原因。如果你没有使用TortoiseHg,这并不容易完成。我不知道这一点。 - Lasse V. Karlsen
1
有没有人发现在文件有很多更改的情况下,块选择失败了,无法显示块?提交和存储差异显示一个大的差异而不是多个块。外部差异应用程序可以正常显示各个差异。这种情况只发生在过去一个月内。 - ventaur
有点复活,但我注意到在THG 3.3中,这个提交已经被删除并重新放回了货架。出于好奇,有人知道这是为什么吗? - fostandy
我刚刚更新了从THG 3.1.2到THG 3.4.1版本,但看起来带有块选择的提交功能似乎没有变化。如果你升级到最新稳定版本3.4.1,@fostandy,请问你是否可以看到提交中的这个功能?也许在3.1.2和3.4.1之间的某个版本中已经删除并重新引入了该功能,但我没有兴趣运行几个旧版本... - mwolfe02
有点尴尬 - 我上次检查时(在3.3上),我正在使用补丁(mq)。正如你所说,提交工具确实可以工作(只是不能在补丁中使用),并且可能在上一个版本中也可以。谢谢。 - fostandy
显示剩余2条评论

34

MQ就像Chad提到的那样,是一种方式。还有更轻量级的解决方案:

  • Record扩展与darcs record大致相同。 它已经随mercurial分发。
  • Shelve扩展允许您“shelve”某些更改,使您只提交更改的子集(未被取出的那些)

请参考此答案中的附加信息:https://dev59.com/MWsz5IYBdhLWcg3wn5ba#7768682 - Joshua Goldberg

19

我感觉好像有什么东西被忽略了,因为没有人提出这个建议。

正常的“hg提交”命令可以用于选择性地选择要提交的内容(您不必提交本地工作目录中的所有待处理更改)。

如果您有一组类似以下的更改:

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

从命令行来说不太方便,因为你必须手动输入要选择提交的文件(而不是像tortoise那样通过复选框选择),但这是最简单直接的方法之一,并且不需要任何扩展程序。文件名通配符可以帮助减少输入(就像上面那样,所有要提交的文件在路径名中都包含“liferay”)。


7
其他答案中只涉及每个文件内部的选定更改(虽然不清楚这是否是问题所要求的,所以点赞)。 - Peter Gibson

16

Mercurial Queues 教程在这种情况下并不好用。我看到的所有示例都假设你还没有进行提交,且只需刷新一个补丁。但实际上,大多数情况下并非如此,你可能有2或3个提交需要合并或以其他方式更改。

假设你有这样的历史记录:

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

第一个示例是压缩提交 A、B 和 C。首先初始化 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的提交消息通过星号分隔的串联。这里的好处是,如果您使用bash并且已经加载了hg-completion脚本,hg qfold 将自动补全补丁。这将留下以下历史记录,其中A+B+C是我们感兴趣的三个补丁的组合的单个提交:

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

另一个使用案例是,如果我们具有与之前相同类型的历史记录,但希望删除补丁B并合并A + C。这实际上与上面非常相似。当您到达qfold步骤时,您只需折叠最后一次提交而不是最后的两次提交:

$ 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发送到邮件列表。


10

一些时间已经过去。现在最好的选择似乎是 hg commit --interactive


7
你可以使用Mercurial附带的记录扩展
首先,你需要在~/.hgrc文件中启用它,将其添加到[extensions]部分即可。
[extensions]
record=

然后,只需键入hg record而不是hg commit,您就能选择要提交哪些文件的更改。
您还可以使用crecord扩展,它提供了一个更好的界面来审核和选择更改。(虽然它不与Mercurial一起分发,但我曾经看到过它偶尔会出现提交错误,所以它并非完全没有缺陷。)

1
crecord相对于record有一个优势,就是你可以选择一个巨块的部分进行操作。而且它的界面也漂亮多了:D - Jürgen A. Erhard
1
记录扩展页面显示此扩展已弃用,该功能现在作为hg commit --interactive的一部分包含在Mercurial核心中。请参见此答案 - saaj

3

这似乎可以满足我的需求,但如果该过程更像hg转移命令那样交互式就更好了。 - mansu

2
我使用commit-patch。这是一个脚本,让您在提交之前编辑差异。在Emacs的diff-mode和vc-mode中非常实用。
过去我使用过crecord,但它存在与Unicode相关的错误(实际上是record扩展有这些错误,crecord依赖于它)。

2

尝试使用qct(Qt Commit Tool)。它具有“选择更改”功能,可启动3方合并工具,以便您撤消单个更改。提交后,“撤消”的更改会回来。


-1

首先,您必须忘记您曾经了解的所有GUI,并返回到命令行。接下来,在命令行中执行以下操作:

hg stat > filelist.txt

这将把所有修改过的文件导入名为filelist.txt的文本文件中。

接下来,编辑您的文件列表,只包括您想要提交的文件。

最后,使用文件集语法进行提交:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接