提交和推送单个文件而不进行其他修改的最简单方法是什么?

我对 Mercurial 还是比较新的,我的团队现在正在试用它作为 Subversion 的替代品。

如何提交一个文件并将其推送到另一个存储库,而不提交工作目录中的其他修改(或者至少不推送到另一个存储库) ?

数据库迁移时会发生这种情况。我们希望将迁移提交到源代码管理,这样 DBA 就可以在我们进行代码修改以进行数据库迁移的同时查看和编辑它。这些变化还没有准备好,所以我们不想把它们都推出去。

在颠覆中,我会简单地做:

svn add my_migration.sql
# commit only the migration, but not the other files I'm working on
svn commit -m "migration notes" my_mygration.sql

继续在当地工作。

对于 mercurial,当我将它推出到另一个存储库时,如果有我没有推出的更改,它希望我将它们拉下来,合并它们,并将合并提交到存储库。合并后的提交不允许您省略文件,因此它强制您提交本地存储库中的所有内容。

我能想到的最简单的方法是将文件提交到本地存储库,克隆本地存储库,从实际存储库中获取任何新的更改,合并它们并提交合并,然后它们将我的更改推出。

hg add my_migration.sql
hg commit -m "migration notes" my_migration.sql
cd ..
hg clone project project-clone
cd project-clone
hg fetch http://hg/project
hg push  http://hg/project

这个方法很有效,但是我感觉我错过了一些更简单的方法,比如告诉 mercurial 忽略我工作目录中已经存在的文件,只需要进行合并并发送文件。我怀疑多变的队列可以做到这一点,但我还没有完全理解 mq。

38737 次浏览

Mercurial 有一个实现搁置和取消搁置命令的特性,它提供了一种交互式的方式来指定要存储到以后的更改: 架子

然后,你可以 hg shelvehg unshelve暂时存储变化了。它可以让你在“补丁大块”级别工作,挑选项目,以搁置起来。它似乎没有搁置一个文件已经列出添加,只有文件已经在修改的回购。

它作为“扩展”包含在 Mercurial 中,这意味着您必须在 hg 配置文件中启用它。


Mercurial 真正老版本的说明(在搁置之前——这已经不再需要了) :

我没有看到任何伟大的安装说明与一些谷歌,所以这里的组合东西,我用来让它的工作:

用:

hg clone http://freehg.org/u/tksoh/hgshelve/ hgshelve

项目中(当前)唯一的文件是 hgshelve.py 文件。

修改 ~/. hgrc 以添加搁置扩展名,指向克隆回购的位置:

[extensions]
hgshelve=/Users/ted/Documents/workspace/hgshelve/hgshelve.py

如果您不想依赖扩展,另一个选择是在本地保留您的上游存储库的一个克隆,只用于这些类型的集成任务。

在您的示例中,您可以简单地将您的更改拉/合并到集成/上游存储库中,并将其直接推送到远程服务器。

Dr: 我最初的解释看起来很复杂,但我希望它能充分解释如何使用补丁队列。长话短说:

$ hg qnew -m "migration notes" -f migration my_migration.sql
$ hg qnew -f working-code
# make some changes to your code
$ hg qrefresh # update the patch with the changes you just made
$ hg qfinish -a # turn all the applied patches into normal hg commits

Mercurial Queues 使这种事情变得轻而易举,并且使得更复杂的变更集操作成为可能。值得学习。

在这种情况下,你可能首先想要保存工作目录中的内容,然后再下拉更改:

# create a patch called migration containing your migration
$ hg qnew -m "migration notes" -f migration.patch my_migration.sql
$ hg qseries -v # the current state of the patch queue, A means applied
0 A migration.patch
$ hg qnew -f working-code.patch # put the rest of the code in a patch
$ hg qseries -v
0 A migration.patch
1 A working-code.patch

现在让我们对工作代码做一些额外的工作。为了明确起见,我将继续使用 qseries,但是一旦您建立了补丁队列的心理模型,您就不必继续查看列表了。

$ hg qtop # show the patch we're currently editing
working-code.patch
$ ...hack, hack, hack...
$ hg diff # show the changes that have not been incorporated into the patch
blah, blah
$ hg qrefresh # update the patch with the changes you just made
$ hg qdiff # show the top patch's diff

因为现在所有的工作都保存在补丁队列中,所以您可以取消应用这些更改,并在拉入远程更改后恢复它们。通常要取消所有补丁,只需执行 hg qpop -a即可。为了显示修补程序队列的效果,我将一次删除一个。

$ hg qpop # unapply the top patch, U means unapplied
$ hg qseries -v
0 A migration.patch
1 U working-code.patch
$ hg qtop
migration.patch
$ hg qpop
$ hg qseries -v
0 U migration.patch
1 U working-code.patch

此时,就好像您的目录中没有任何更改。做 hg fetch。现在,您可以将修补程序队列更改推回,并在出现任何冲突时合并它们。这在概念上有点类似于 git 的 rebase。

$ hg qpush # put the first patch back on
$ hg qseries -v
0 A migration.patch
1 U working-code.patch
$ hg qfinish -a # turn all the applied patches into normal hg commits
$ hg qseries -v
0 U working-code.patch
$ hg out
migration.patch commit info... blah, blah
$ hg push # push out your changes

此时,您已经推出了迁移,同时保留了其他本地更改。您的其他更改位于队列中的补丁中。我使用补丁队列进行大部分个人开发,以帮助我更好地构建更改。如果您想摆脱补丁队列并返回到一个正常的样式,您将不得不导出您的更改并在“正常”汞中重新导入它们。

$ hg qpush
$ hg qseries -v
0 A working-code.patch
$ hg export qtip > temp.diff
$ rm -r .hg/patches # get rid of mq from the repository entirely
$ hg import --no-commit temp.diff # apply the changes to the working directory
$ rm temp.diff

我非常沉迷于用于开发的补丁队列,而 mq是最好的实现之一。同时进行多个更改的能力确实能够提高您的提交的专注度和清晰度。它需要一段时间来适应,但它与 DVCS 工作流程非常好。

从我最初提出这个问题到现在已经快两年了。如果是我的话,我现在会做得不一样(正如我在上述问题的评论中提到的那样)。我现在要做的是将我的更改提交到本地 repo 中的一个文件(可以使用 hg 记录扩展名仅提交文件的片段) :

hg commit -m "commit message" filename

那就推出去。

hg push

如果有冲突,因为已经对回购进行了其他更改,我需要首先合并,我将更新到父版本(见“ hg father-r”)如果你不知道它是什么) ,提交我的其他变化,这样我有两个头。然后恢复到原来的单个文件提交,并将更改拉入/合并到该版本中。然后用

hg push --rev .

只推出单个文件并合并该修订。然后你就可以把两个脑袋合并在一起。

这种方法消除了 mq 内容和被拒绝的块的可能性,并通过源代码控制跟踪所有内容。你也可以“ hg 带”修订关闭,如果你以后决定你不想要他们。

我通常使用的是提交单个文件:

 hg commit -m "commit message" filename

如果以后出现合并冲突,而我还没有准备好提交更改,请按照以下步骤操作:

1)创建一个补丁文件。

hg diff > changes.patch

2)只有在检查你的补丁文件之后,恢复所有未提交的更改。

hg revert --all

3)拉取、更新和合并到最新版本

hg pull -u
hg merge
hg commit -m "local merge"

4)现在简单地导入你的补丁并得到你的修改。

hg import --no-commit changes.patch

记住在自动提交更改时使用 -no-commit 标志。

因为您说的是最简单的,所以即使在提交整个文件时,我也经常使用 hg commit -i(——交互式)。使用 --interactive,您只需选择所需的文件,而不必在命令行上键入它们的整个路径。作为额外的好处,您甚至可以有选择地在文件中包含/排除块。

然后用 hg push推送新创建的提交。

在这个答案中,我提供了更多关于使用 hg commit --interactive的细节: https://stackoverflow.com/a/47931672/255961