特定分支当前修订版的 Mercurial 子存储库
我对 Mercurial 很陌生,我读过很多关于这个主题的主题,但我仍然不明白我是否能实现我想要做的事情。
基本上,我有兴趣通过单个命令(作用于主存储库)从主存储库及其子存储库克隆分支的当前版本。我稍后会尝试更好地解释它。
假设我将代码分成模块(下面的示例中只有一个模块)。我希望每个模块都有自己的存储库,并有一个主存储库(具有 .hgsub 的存储库)作为粘合剂,以将所有子存储库保持在适当的位置。主存储库仅包含 .hgsub 和一个脚本,该脚本 (1) 将每个子存储库存储在预定义目录中,并且 (2) 执行代码的源外构建。所有开发、提交、推送、拉取、合并都在各个子存储库中完成。
# create a module (subrepo of the master)
hg init subrepo
cd subrepo/
echo "a file" > aFile.c
echo "another file" > anotherFile.txt
hg add
hg ci -m "initial rev of subrepo"
# create the main (master) repo & add the reference to subrepo
cd ../
hg init main
cd main
hg clone ../subrepo subrepo
echo subrepo = ../subrepo > .hgsub
echo hg archive and out-of-source build > build.script
hg add
hg ci -m "initial rev of main repo"
到目前为止,一切都很好。如果我 hg clone main
我会按照预期获得 subrepo 默认分支的当前版本。
但是,现在让我们想象一下,我已经准备好将我的代码发布到一个版本中:1.0.0。我会做如下。
# create the branch 1.0 to manage the bug fixes to 1.0.0 and furthers
cd ../subrepo/
hg branch 1.0
hg ci -m "creating the branch 1.0"
# backstep to the main line to carry on the development of new features
hg up default
echo "working in the main line" > aNewFeature.c
hg add
hg ci -m "carrying on the development in the main line (a new feature)"
hg glog
@ changeset: 2:c499329c2729
| tag: tip
| parent: 0:50d4522a99ea
| user: XXXX
| date: Tue Dec 07 16:13:28 2010 +0100
| summary: carrying on the development in the main line (a new feature)
|
| o changeset: 1:0a81043e6e8a
|/ branch: 1.0
| user: XXXX
| date: Tue Dec 07 16:12:02 2010 +0100
| summary: creating the branch 1.0
|
o changeset: 0:50d4522a99ea
user: XXXX
date: Tue Dec 07 15:52:57 2010 +0100
summary: initial rev of subrepo
这就是问题发生的地方。当我执行 hg clone
时,如何更改主存储库以获取默认版本的当前版本或最终子存储库的 1.0 分支?
我会说这有效。
# replicate the branch structure also in the main repo
cd ../main/
hg branch 1.0
echo subrepo = ../subrepo -r 1.0 > .hgsub
hg ci -m "adding -r 1.0 to .hgsub"
hg up default
echo subrepo = ../subrepo -r default > .hgsub
hg ci -m "adding -r default to .hgsub"
hg glog
@ changeset: 2:f97c90a31a21
| tag: tip
| parent: 0:1fd6b5d528b4
| user: XXXX
| date: Tue Dec 07 16:22:05 2010 +0100
| summary: adding -r default to .hgsub
|
| o changeset: 1:3d9ed2f8b026
|/ branch: 1.0
| user: XXXX
| date: Tue Dec 07 16:21:32 2010 +0100
| summary: adding -r 1.0 to .hgsub
|
o changeset: 0:1fd6b5d528b4
user: XXXX
date: Tue Dec 07 15:55:53 2010 +0100
summary: initial rev of main repo
但是,当我hg clone
主存储库时,我得到
cd /a/directory
hg clone /path/to/main -r 1.0 main
requesting all changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 3 changes to 2 files
updating to branch 1.0
pulling subrepo subrepo
abort: HTTP Error 404: Not Found
Is there a way to get what I Want to do?
谢谢。
快速更新:在我发布问题一分钟后,我发现了一个我从未见过的答案前。在那里,建议使用以下语法
http://[user[:pass]@]host[:port]/[path][#revision]
:使用 #branchname
代替 #revision
。因此,在我的示例中,以下内容应该有效(对于分支 1.0):
echo subrepo = ../subrepo#1.0 > .hgsub
但是当我 hg clone
主存储库时,我得到:
pulling subrepo subrepo
abort: unsupported URL component: "1.0"
Exception AttributeError: "'httprepository' object has no attribute 'urlopener'" in <bound method httprepository.__del__ of <mercurial.httprepo.httprepository object at 0x871332c>> ignored
我正在使用 Ubuntu 10.04,mercurial 1.4.3-1。建议?
-- 迪伦
I'm quite new to mercurial, I've read a lot of topics on this subject but I still can't understand if I can achieve what I'm trying to do.
Basically I'd be interested in cloning the current revision of a branch from a main repository and its subrepos in a single command (acting on the main repo). I will try to explain it better in a moment.
Let's say that I separated my code into modules (only one module in the example below). I'd like to have each module in its own repository, and a master repo (the one that has the .hgsub) as a glue to keep all the subrepos in place. The master repo just contains .hgsub and a script which (1) hg archive
each subrepo in a predefined directory and (2) performs an out-of-source build of the code. All development, commit, push, pull, merge is done in the individual subrepos.
# create a module (subrepo of the master)
hg init subrepo
cd subrepo/
echo "a file" > aFile.c
echo "another file" > anotherFile.txt
hg add
hg ci -m "initial rev of subrepo"
# create the main (master) repo & add the reference to subrepo
cd ../
hg init main
cd main
hg clone ../subrepo subrepo
echo subrepo = ../subrepo > .hgsub
echo hg archive and out-of-source build > build.script
hg add
hg ci -m "initial rev of main repo"
So far, so good. If I hg clone main
I get the current revision of the default branch of subrepo, as expected.
BUT, let's imagine now that I'm ready to ship my code into a release: the 1.0.0. I'd do as follows.
# create the branch 1.0 to manage the bug fixes to 1.0.0 and furthers
cd ../subrepo/
hg branch 1.0
hg ci -m "creating the branch 1.0"
# backstep to the main line to carry on the development of new features
hg up default
echo "working in the main line" > aNewFeature.c
hg add
hg ci -m "carrying on the development in the main line (a new feature)"
hg glog
@ changeset: 2:c499329c2729
| tag: tip
| parent: 0:50d4522a99ea
| user: XXXX
| date: Tue Dec 07 16:13:28 2010 +0100
| summary: carrying on the development in the main line (a new feature)
|
| o changeset: 1:0a81043e6e8a
|/ branch: 1.0
| user: XXXX
| date: Tue Dec 07 16:12:02 2010 +0100
| summary: creating the branch 1.0
|
o changeset: 0:50d4522a99ea
user: XXXX
date: Tue Dec 07 15:52:57 2010 +0100
summary: initial rev of subrepo
And here's where the problems happen. How do I change the master repo to get the current revision of the default or, eventually, the 1.0 branch of subrepo, when I perform hg clone
?
I would have said that this worked.
# replicate the branch structure also in the main repo
cd ../main/
hg branch 1.0
echo subrepo = ../subrepo -r 1.0 > .hgsub
hg ci -m "adding -r 1.0 to .hgsub"
hg up default
echo subrepo = ../subrepo -r default > .hgsub
hg ci -m "adding -r default to .hgsub"
hg glog
@ changeset: 2:f97c90a31a21
| tag: tip
| parent: 0:1fd6b5d528b4
| user: XXXX
| date: Tue Dec 07 16:22:05 2010 +0100
| summary: adding -r default to .hgsub
|
| o changeset: 1:3d9ed2f8b026
|/ branch: 1.0
| user: XXXX
| date: Tue Dec 07 16:21:32 2010 +0100
| summary: adding -r 1.0 to .hgsub
|
o changeset: 0:1fd6b5d528b4
user: XXXX
date: Tue Dec 07 15:55:53 2010 +0100
summary: initial rev of main repo
But when I hg clone
the main repo, I get
cd /a/directory
hg clone /path/to/main -r 1.0 main
requesting all changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 3 changes to 2 files
updating to branch 1.0
pulling subrepo subrepo
abort: HTTP Error 404: Not Found
Is there a way to achieve what I want to do?
Thanks.
Quick update: just a minute after I posted the question, I found an answer I've never seen before. There, it is suggested to use the following syntax
http://[user[:pass]@]host[:port]/[path][#revision]
by using #branchname
in place of #revision
. So, in my example, the following should work (for the branch 1.0):
echo subrepo = ../subrepo#1.0 > .hgsub
But when I hg clone
the master repo I get:
pulling subrepo subrepo
abort: unsupported URL component: "1.0"
Exception AttributeError: "'httprepository' object has no attribute 'urlopener'" in <bound method httprepository.__del__ of <mercurial.httprepo.httprepository object at 0x871332c>> ignored
I'm working on Ubuntu 10.04, mercurial 1.4.3-1. Suggestions?
--
Dylan
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
此行是错误的:
您无法在
.hgsub
文件中向克隆操作添加额外的选项。 也是错误的.hgsub
文件具有以下结构:就是这样。然后,Mercurial 将使用
subrepo-source-URL
克隆子存储库,并将子存储库克隆作为subrepo-mount-point
放置在外部存储库内。下一个问题是 Mercurial 子存储库的哪个版本应该为您签出:
.hgsubstate
文件中提到的版本。该文件的结构中
subrepo-revision-ID
是 Mercurial 子存储库的变更集哈希。您可以通过以下方式更新此文件:每次在外部存储库中进行提交时,所有子存储库的确切修订版本都会写入外部存储库中的
.hgsubstate
文件中。这就是版本控制发挥作用的原因:当您在外部存储库中执行hg update
时,.hgsubstate
文件会发生更改,Mercurial 将确保签出子存储库的相应版本。我认为您正在尝试创建一个伞存储库,自动跟踪一堆子存储库的给定分支。 Mercurial 无法做到这一点:它坚持认为,当您克隆主存储库时,您将获得一个工作副本,其中包含处于已知状态的子存储库,即在主存储库中提交的状态。
如果您安装我的 onsub 扩展,那么您可以像这样更新并提交所有子存储库:
然后您可以构建这个修订版并将其发送给您的客户 - 如果他们返回错误和主存储库的变更集哈希,那么您就知道您可以准确地重新创建构建。如果 Mercurial 没有在
.hgsubstate
文件中记录子存储库状态,情况就不会如此。This line is wrong:
You cannot add extra options to the clone operation in the
.hgsub
file. It is also wrong to doThe
.hgsub
file has the structure:and that's it. Mercurial will then go out and use the
subrepo-source-URL
to make a clone of the subrepo and place the subrepo clone assubrepo-mount-point
inside the outer repo.The next question is what revision of the subrepo Mercurial should checkout for you: the revision mentioned in the
.hgsubstate
file. This file has the structurewhere the
subrepo-revision-ID
is a changeset hash for Mercurial subrepos. You update this file by doingEvery time you make a commit in an outer repository, the exact revision of all the subrepos are written into the
.hgsubstate
file in the outer repository. This is what makes version control work: when you dohg update
in the outer repository, the.hgsubstate
file changes and Mercurial will make sure to checkout the corresponding versions of the subrepos.I think you are trying to make an umbrella repository that automatically tracks a given branch for a bunch of subrepos. You cannot do this with Mercurial: it insists that when you clone the main repository, then you will get a working copy that contain subrepos in a known state, namely the state that was committed in the main repository.
If you install my onsub extension, then you can update and commit all subrepos like this:
You can then build this revision and send it to your customers -- if they come back with a error and a changeset hash for the main repository, then you know you can recreate the build exactly. That would not be the case if Mercurial had not recorded the subrepository states in the
.hgsubstate
file.