比如说,我对我的代码做了很多更改,只需要提交其中的一些更改。有没有办法在 mercurial 中做到这一点?我知道它darcs
有这样的功能。
我知道hg transplant
可以在分支之间执行此操作,但我需要这样的东西来在当前分支中提交代码,而不是在从其他分支添加更改集时。
比如说,我对我的代码做了很多更改,只需要提交其中的一些更改。有没有办法在 mercurial 中做到这一点?我知道它darcs
有这样的功能。
我知道hg transplant
可以在分支之间执行此操作,但我需要这样的东西来在当前分支中提交代码,而不是在从其他分支添加更改集时。
如果您在 Windows 上使用TortoiseHg 1.x,此功能开箱即用(无需扩展)。
对于TortoiseHg 2.x,Hunk Selection 选项卡现在消失了。取而代之的是搁置工具。它比旧的大块选择具有更多功能。这些新功能是以增加一些复杂性为代价的。
请注意,使用此功能时无需显式启用 Mercurial Shelve 扩展。根据 Steve Borho(TortoiseHg 首席开发人员)在回答另一个 TortoiseHg 问题时说:“我们有一个搁置扩展的本地副本并直接调用它。”
对于TortoiseHg 2.7+,此功能已得到改进并重新引入。它现在直接内置到 Commit 工具中:
请注意,在左侧的文件列表中,顶部的文件被选中以指示它将被包含,第二个文件未被选中,因为它不会被包含,第三个文件 Sample.txt 被填充(Null 复选框指示符)因为只有从该文件中选择的更改才会包含在提交中。
将包含的对 Sample.txt 的更改在图像的右下角更改选择部分中进行检查。将被排除的更改未选中,差异视图显示为灰色。另请注意,搁置工具的图标仍然可用。
我觉得我错过了一些东西,因为已经没有人提出这个建议了。
普通的“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”。
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
向邮件列表提交一个连贯的补丁。
一段时间过去了。现在看来最好的选择是hg commit --interactive
您可以使用随 Mercurial 分发的记录扩展。
您需要先在~/.hgrc
文件中启用它,方法是将其添加到以下[extensions]
部分:
[extensions]
record=
然后,只需键入hg record
而不是hg commit
,您就可以选择要提交的文件的更改。
您还可以使用crecord 扩展,它提供了一个更好的界面来查看和选择更改。(不过,它没有与 Mercurial 一起分发,而且我看到它偶尔会弄乱提交,因此它不是完全没有错误的。)
我相信Mercurial Queues填补了 Mercurial 的这个角色。那里有一个很好的教程链接。
试试 qct(Qt 提交工具)。它有一个“选择更改”功能,可以启动一个 3 向合并工具,让您撤消单个更改。提交后,您“撤消”的那些更改会回来。
我使用提交补丁。这是一个脚本,可让您在提交之前编辑差异。Emacs 的 diff-mode 和 vc-mode 真的很棒。
过去我使用crecord,但它有与unicode相关的错误(实际上记录扩展有错误,crecord依赖于)。
首先,您必须忘记您所知道的关于 GUI 的所有内容并返回命令行。接下来从命令行执行此操作:
hg stat > filelist.txt
这会将所有修改过的文件通过管道传输到一个名为 filelist.txt 的文本文件中
接下来编辑您的文件列表以仅包含您希望提交的文件。
最后使用文件集 sytnax 提交:
hg commit "set: 'listfile:test.txt'"