Mercurial:为什么撤销变更集不会公开?

时间:2013-05-25 23:41:15

标签: mercurial

考虑以下情况:

$ md repo1; cd repo1
$ echo some data > myfile
$ hg init; hg addremove; hg commit -m "First commit."
adding myfile
myfile
committed changeset 0:32c7aa047f3b
$ hg serve
listening at http://vostro.rath.org:8000/ (bound to *:8000)

然后在另一个终端:

$ hg clone http://vostro.rath.org:8000/ repo2
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
updating to branch default
resolving manifests
getting myfile
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

$ cd repo2; hg phase tip
0: public

..再次在第一个终端:

127.0.0.1 - - [25/May/2013 16:38:40] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
^Cinterrupted!
$ hg phase tip
0: draft

对我来说,这看起来非常错误。有人刚从第一个存储库中删除了变更集,所以它显然是公开的。但是,它仍然在存储库中显示为“草稿”。

有人可以解释这种行为的理由吗?作为第一个存储库的所有者,我非常想知道某人什么时候撤销修订版(例如我不再修改它),所以我认为如果hg服务器进程会更新阶段是明智的因此。

3 个答案:

答案 0 :(得分:4)

您可能会在邮件列表上找到更好的答案,但我的理解是:

hg pull一直是只读命令,可以在没有对远程存储库的写访问权的情况下运行。更改远程存储库中的阶段(显然)需要写入。另一方面,hg push始终写入远程存储库,因此阶段没有引入任何更改。

hg pull从只读更改为读写可能会导致某些人的工作流程中断,这对于mercurial开发来说是致命的罪。 (例如,匿名用户从公共服务器拉出,通过电子邮件包发回更改)

基本上这是一个历史怪癖,因为阶段是复古的。

这个开放的洞是变更集的原始所有者可以修改它,而没有意识到变化已经进入了荒野。我希望这个洞并没有让太多人担心,因为正在开发的“变更集演化”功能以更好的方式解决了这个问题。

我倾向于将阶段视为:

  • 公开 - 公开可见且不可变
  • 草稿 - 公开可见和可变
  • 秘密 - 不公开可见和可变

我认为draft仅在那里,因为这基本上是我们在添加阶段之前所处的位置,并且有点弱概念。实际上,如果您在人们可能直接从您那里获取的环境中工作,那么我建议您使用publicsecret阶段进行更多工作,并避免使用draft

答案 1 :(得分:2)

正如@zerkms所说,pull并非旨在更改远程存储库。

如果您的工作存储库被用作服务器,您有几个选择:

  • 将提交的默认值设置为“public”而不是“draft”。其他人可以随时拉,所以假设他们是公开的。
  • 将提交的默认值设置为“secret”。其他人无法拉动它们。当您准备好分享时,将它们设置为“公开”。
  • 将您的存储库设置为“非发布”。其他人可以提取你的草稿变更集,但它们仍会被标记为“草稿”。

以下是如何在mercurial.ini/hgrc中指定这些行为。

[phases]
publish = False
new-commit = public

答案 2 :(得分:1)

pull无意更改远程存储库阶段,而是更改本地存储库的阶段。

要明确的是 - 您不应该关心远程存储库中的哪个阶段。

甚至更多 - 可以使用不支持阶段的旧的mercurial版本托管远程存储库。

  

为什么会出现这种情况?

因为阶段只对本地存储库有意义,并且有助于防止历史修改错误。