开发者

mercurial subrepos at the current revision of a specific branch

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:    开发者_StackOverflow    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


This line is wrong:

echo subrepo = ../subrepo -r default > .hgsub

You cannot add extra options to the clone operation in the .hgsub file. It is also wrong to do

echo subrepo = ../subrepo#1.0 > .hgsub

The .hgsub file has the structure:

subrepo-mount-point = subrepo-source-URL

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 as subrepo-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 structure

subrepo-revision-ID subrepo-mount-point

where the subrepo-revision-ID is a changeset hash for Mercurial subrepos. You update this file by doing

 cd main/subrepo
 hg update 1.0
 cd ..
 hg commit -m 'Updated subrepo in main'

Every 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 do hg 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:

hg onsub hg update
# run test!
hg commit -m 'Updated all subrepos to their tip'

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜