2

考虑以下情况:

$ 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 服务器进程会更新阶段是明智的因此。

4

3 回答 3

4

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

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

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

基本上这是一个历史怪癖,因为阶段是一种改造。

这留下的漏洞是变更集的原始所有者可以对其进行修改,而不会意识到该变更已经泛滥成灾。我希望这个漏洞不会让太多人担心,因为正在开发的“变更集演化”功能以更好的方式解决了这个问题。

我倾向于将阶段视为:

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

我认为draft只是在那里,因为这基本上是我们在添加阶段之前所处的位置,并且是一个有点弱的概念。真的,如果你在一个人们可能直接从你那里获得帮助的环境中工作,那么我建议更多地使用publicsecret阶段工作,并避免draft.

于 2013-05-26T09:12:12.350 回答
2

正如@zerkms 所说,pull并不是要更改远程存储库。

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

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

以下是如何在mercurial.ini/hgrc.

[phases]
publish = False
new-commit = public
于 2013-05-26T00:53:59.963 回答
1

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

并且要清楚 - 你不应该关心远程存储库中的哪个阶段。

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

为什么会有这种行为?

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

于 2013-05-25T23:46:35.880 回答