Does a mercurial subrepository have to be a subdirectory of the main repository?
Asked Answered
M

2

18

My project is made up of code in the following locations

C:\Dev\ProjectA
C:\Lib\LibraryB
C:\Lib\LibraryC

Presently each of these folders is a completely independent Mercurial repository. Project A changes all the time, Library B and Library C change rarely.

I currently tag each version of Project A as it is released and (when I remember) put a corresponding tag in the Library B and C repositories.

Can I improve upon this by using subrepositories? Would that require me to make Library B and C a subdirectory of Project A?

If Library B and C must be subdirectories of Project A what do I do if I want to start a Project D that uses Library B but isn't otherwise affiliated with Project A at all?

Mikey answered 16/12, 2010 at 4:51 Comment(0)
K
18

If Library B and C must be subdirectories of Project A what do I do if I want to start a Project D that uses Library B but isn't otherwise affiliated with Project A at all?

Any project can exist both independently and as subrepository of another project at the same time. I'll explain by suggesting a workflow.

First of all, each of your projects (A, B, C) should have a blessed repository that is published somewhere:

blessed repository

You could run hgwebdir on your own server, or make use of a Mercurial hosting service like Bitbucket or Kiln. This way developers have a central authorative point to pull/push changes from, and you have something to make backups of.

Now you can make clones of these repositories to work on in two different ways:

  • directly clone your project. For example:

    hg clone http://bitbucket.org/LachlanG/LibraryB C:\Lib\LibraryB
    
  • and/or create subrepository definitions by putting a .hgsub file in the root of ProjectA with the following content:

    libraries/libraryB = http://bitbucket.org/LachlanG/LibraryB
    libraries/libraryC = http://bitbucket.org/LachlanG/LibraryC
    

These subrepository definitions tell Mercurial that whenever Project A is cloned, it also has to put clones of Library B and Library C in the libraries folder.

If you are working in Project A and commit, then your changes in libraries/LibraryB and libraries/LibraryC will be committed as well. Mercurial will record which version of the libraries is being used by Project A in the .hgsubstate file. The result is that if you hg update to an old version of the project to see how things worked last week, you also get the corresponding version of your libraries. You don't even need to make tags :-)

When you hg push the Project A changes to the blessed repository, Mercurial will also make sure to push the subrepository changes first to their own origin. That way you never accidentally publish project changes which depend on unpublished library changes.

If you prefer to keep everything local, you can still use this workflow by using relative paths instead of URLs in the subrepository definitions.

Knorr answered 16/12, 2010 at 10:42 Comment(6)
Where is the libraries folder you mention at the end of the sentence, "These subrepository definitions tell mercurial that whenever projectA is cloned, it also has to put clones of LibraryB and LibraryC in the libraries folder."Mikey
Its just a folder, the left part of the: libraries/libraryB = bitbucket.org/LachlanG/LibraryB is where the clone from the right side should beRosaliarosalie
@LachlanG: it will appear in the root of the ProjectA clone, for example `C:\Dev\ProjectA\libraries`.Knorr
So references within my project source code to C:\Lib\LibraryB will need to be changed to C:\Dev\ProjectA\libraries\LibraryB?Mikey
@LachlanG: though you should of course use relative paths so that you don't force each developer to copy your exact absolute path layout. Any decent IDE should support this.Knorr
if anyone reading this can answer a related question here ==> https://mcmap.net/q/671441/-setting-up-mercurial-kiln-subrepos-on-osx/830899 i would appreciate itAloin
D
2

You can indeed declare B and C subrepos of project A (they will appear as subdirectory, as described in Mercurial Subrepository).
That would improve your release mechanism as it would allow you to:

  • get all repos in one place (A and under)
  • reference an exact tag of B and C under A
  • tag each sub-repo s first if they had any modification
  • tag A with the information about B and C tags in it (any clone of A will be able to get the exact tags of B and C used by A)

You can also declare B as a subrepo of D, independently of A. What you make in A (regarding B) will have no consequences for B used in D.

Dwan answered 16/12, 2010 at 7:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.