Using subrepositories with bitbucket and ToritoiseHg - mercurial

I have subrepository structure as following in TortoiseHg:
/MainFolder/
/MainFolder/SubFolder1
/MainFolder/SubFolder2
MainFolder is a private repository on bitbucket
SubFolder1 is a private repository on bitbucket
SubFolder2 is a private repository on bitbucket
The file .hgsub inside MainFolder looks like this:
SubFolder1 = SubFolder1
SubFolder2 = SubFolder2
The file .hgsubstat inside MainFolder also have valid guids and subrepository names.
The problem is whenever I try to push to bitbucket for MainFolder, first it pushes the MainFolder, then SubFolder1, but when it gets to SubFolder2, TortoiseHg throws error "abort: repository is unrelated".
When i check my MainFolder repository on bitbucket, it has actually contents of SubFolder1 (it should be listed there as subrepository).
How can I fix this so that the MainFolder is correctly uploaded as parent repository and SubFolder1 and SubFolder2 are listed as its sub-repository on bitbucket?

The example shown in bitbucket documentation requires to rename repositories so that all the repositories are named as MainRepository-SubRepository. I didn't want to rename all my repositories so modified the regular expression as shown in following example and it works correctly now. This version doesn't require the dash separator in repository name, Main repository and sub repositories can be named independently. The example .hgsub looks like this:
SubFolder1 = SubFolder1
SubFolder2 = SubFolder2
[subpaths]
(https://(?:[^#]+#)?bitbucket\.org/[^/]+)(/[^/]+)/(.*) = \1/\3

Bitbucket doesn't do subrepos in situ. As a result, Mercurial is attempting to push every one of your repositories to the same location, and complains when you try to push the repo SubFolder2 into a remote copy of the SubFolder1 repo.
Subrepositories are ostensibly libraries that are shared between multiple projects, and therefore don't live under any one main repo but instead in their own space. Therefore, you must create separate remote repositories to house each subrepository (library) and reference that separate remote path in the .hgsub file.
For example, your example project could have three bitbucket-hosted repositories
https://bitbucket.org/bitbucketname/main_project
https://bitbucket.org/bitbucketname/library1
https://bitbucket.org/bitbucketname/library2
You want your local clone's filespace to look like this:
/MainFolder/
/MainFolder/SubFolder1
/MainFolder/SubFolder2
In your local clone of main_project (MainFolder), set the default path of the parent repository to https://bitbucket.org/bitbucketname/main_project
i.e., /MainFolder/.hg/hgrc contains
[paths]
default = https://bitbucket.org/bitbucketname/main_project
Now, indicate the remote paths of the subrepositories/libraries in the .hgsub file. The general format of the .hgsub entries is:
local/path/to/subrepo = remote/path/to/matching/library
So your .hgsub might contain relative local and remote paths (relative to the location of the main repo locally or remotely, as the case may be):
SubFolder1 = ../library1
SubFolder2 = ../library2
or relative local paths with absolute paths to each library's remote repo:
SubFolder1 = https://bitbucket.org/bitbucketname/library1
SubFolder2 = https://bitbucket.org/bitbucketname/library2
or absolute paths for everything:
/MainFolder/SubFolder1 = https://bitbucket.org/bitbucketname/library1
/MainFolder/SubFolder2 = https://bitbucket.org/bitbucketname/library2
Now, when you push from your local main project, Mercurial knows exactly where to find all subrepositories (locally) and where to push the changes made to each library (remotely).
Additionally, let's say you want to add someone else's library to your project. Then your .hgsub might look something like this:
SubFolder1 = ../library1
SubFolder2 = ../library2
another_library = https://bitbucket.org/honkaboy/honkaboys_excellent_library

Related

Mercurial commit with subrepositories in subfolders

I have file/directory structure:
main/.hg
main/subrepo/.hg
main/subrepo1/.hg
I have .hgignore file with such content
.hg
Finally, I want to make a commit in 'main' repository that will include all files in it, including all files from main/subrepo and main/subrepo1 and excluding folders main/subrepo/.hg and main/subrepo1/.hg (so all files from main folder, excluding .hg folders in it will be commited). But Mercurial skips main/subrepo/* and main/subrepo1/*. It does not include this subfolders/subrepos to commit fully. How can I fix this?
I'm going to guess that you have simply created some nested repositories, but not properly linked them as subrepositories.
Make sure that the root of the main repository has a file called .hgsub. You create the file, add the following and then add + commit the file to the main repository:
subrepo = https://path-to-subrepo/
subrepo1 = https://path-to-subrepo1
If the subrepos do not point to some remote server, you would use the local path of course.

Multiple paths for subrepositories

I have main repository and 12 subrepositories in it. .hgsub contains mappings of local paths and repository hosting URLs. Besides default pull/push URLs for subrepositories, I need to be able to push each subrepository to another server as a standalone repository. So, I add new path alias in .hg/hgrc of each subrepository.
The problem is that aliases are not save anywhere except my local machine, so when I do clean clone of main repository, this aliases are gone and I need to setup them again.
Can I permanently save this path aliases in repository configuration file or maybe there's some workaround for this?
I think the best option available to you is to keep a .hgrc snippet in place in the parent repository filled with [subpaths] entries. For example create subpaths.hgrc as a tracked file in your repository:
[subpaths]
repoa = http://remote/path/to/repo/a
repob = http://remote/path/to/repo/b
Then when you want to initialize those repositories you add this line to your clone's .hg/hgrc:
%include ../subpaths.hgrc
and then comment it out when you want the repoa and repob paths being their usual, local selves.

TortoiseHG to Bitbucket - Sub-Repository setup in TortoiseHg

I originally posted this question and found that Bitbucket does not support nested sub repos (CORRECTION: Bitbucket was not the problem at all...potentially bad information or misunderstood what they meant by nested subrepo) . I had to arrange them in Tortoise as sibling Repos. Mercurial to Bitbucket - Subrepository - Repository is unrelated error
My problem now is that TortoiseHg/Mercurial does not pick up the changes in my subrepos.
My directory structure looks like this: (sibling and not child folders)
MainRepo (to hold all subrepos)
SubRepo1 (main project)
SubRepo2 (class library)
SubRepo3 (class library)
etc...
In my .hgsub file, i have the following
SubRepo1 = ../SubRepo1
SubRepo2 = ../SubRepo2
SubRepo3 = ../SubRepo3
etc...
My problem is that the MainRepo does not detect any of the changes in my SubRepo. I noticed that there is now a folder for in the MainRepo folder for each of my subrepos. I suspect TortoiseHg is looking in there for changes...and not my ../SubRepoX folder.
Can anyone guide me to a working SubRepository scenario for TortoiseHg pushing to Bitbucket
UPDATE: See this link for the resolution to my subrepo problem. Recommended way to coordinate versions of multiple dependent mercurial repositories?
The subrepo directory reference should be relative to the location of the .hgsub file.
Therefore, you should have = ./SubRepo rather than ../SubRepo.
Here's the official docs. They're not too hard to read.

Mercurial to Bitbucket - Subrepository - Repository is unrelated error

Here are the steps I've taken to build the repo and subrepos.
Everything is hosted on Bitbucket.
Per best practices, created a skeleton repo to hold all of the subrepos. Cloned to my machine.
Cloned primary project as subrepo1 (within the mainrepo directory structure).
Added primary project to mainrepo as a subrepo1.
Committal of mainrepo works as expected.
Pushed successfully mainrepo and subrepo1 to Bitbucket.
Proceeded to clone another subrepo2 to mainrepo directory.
Added subrepo2 to mainrepo as subrepo2
Committal of mainrepo works as expected.
Push of mainrepo results in "Repository is unrrelated" error after is "searching for changes" Error occurs only on the newly added subrepo2.
Here is directory structure:
mainrepo
--subrepo1 (main project)
--subrepo2 (class library)
I've spent countless hours trying to get this working and I must be missing something obvious.
What is causing this error and what am I missing?
I need to be able to add additional subrepos as the project grows.
The steps that I took to make my example are as follows:
Create MainRepo on BitBucket
Create SubRepo on BitBucket
Clone MainRepo
Clone SubRepo as a sub-directory of MainRepo
Manually create the .hgsub file with the contents SubRepo = ../SubRepo
Add the .hgsub file to MainRepo, commit and push
Create SubRepo2 on BitBucket
Clone SubRepo2 as a sub-directory of MainRepo
Manually edit .hgsub and add SubRepo2 = ../SubRepo2
Commit and push MainRepo again
From then on, I could edit either of the two sub-repositories and see that they had changed when looking at MainRepo in the workbench. I could then commit the changes to the sub-repositories, commit the sub-repository states in MainRepo and push all three repositories with a single push from MainRepo
The way that you said that it was set up by TortoiseHg in your other question (subrepo = subrepo) won't work with BitBucket because of how their structure is. I think that you can only have repositories at the top level like this:
bitbucket.org/SteveKaye/MainRepo
bitbucket.org/SteveKaye/SubRepo
whereas having the line subrepo = subrepo is trying to set up a structure like this:
bitbucket.org/SteveKaye/MainRepo
bitbucket.org/SteveKaye/MainRepo/SubRepo
When you push this it looks like it is trying to push SubRepo into MainRepo which would explain the unrelated repository error message that you are getting.
The .hgsub syntax is such that the left of the equals defines the folder in the working copy where the repository will be and the right of the equals defines where to get it from. When the right of the equals is a relative path, it defines where the sub-repository is on the central server relative to the main repository. So in the example above, you go up one folder to bitbucket.org/SteveKaye and the SubRepo is contained in that folder.
The documentation says:
The source path of a Mercurial repository can either be a relative or absolute path or URL. It is generally recommended to use trivial relative paths where the source path is the same as the working dir path: This will ensure that the subrepositories always can be found 'in place'.
Other relative paths can be used if the subrepositories can't be hosted 'in place', for example because of limitations of a central repository or hosting service. A consequence of using such non-trivial relative paths is that clones can't be cloned.
This looks relevant to your situation when using BitBucket and I'd expect that your clones can't be cloned as it says in the last sentence.

tortoisehg and subrepos

I can't get Tortoisehg (1.0) to work with subrepos
I have a directory structure like this:
root
.hg
.hgsub
.hgsubstate
Customer1
Project1
.hg
foo.txt
Project2
.hg
Customer2
Project3
.hg
the .hgsub file under root looks like
Customer1\Project1=Customer1\Project1
Customer1\Project2=Customer1\Project2
Customer2\Project3=Customer2\Project3
If modify the file Customer1\Project1\foo.txt and commit from the root it works
>hg ci -m "command line commit"
committing subrepository customer1\project1
in Tortoisehg customer1\project1 is displayed with status S (subrepo)
but when commiting I get a message
abort: customer1/project1: no match under directory!
Is this scenario not supported or am I doing something wrong?
The doc says:
"TortoiseHg 1.0 introduced rudimentary support for subrepositories, and only in the commit / status tool. When Mercurial considers a subrepo as dirty, it will appear in the commit tool as a special entry in the file list with a status of S. If a subrepo is included in the file list of a commit, the subrepo is committed along with the other changes, updating the .hgsubstate file in the main repository root."
I had pretty much the same problem and started trying a whole bunch of variations and I finally got it working for me by using a forward-slash (/) on both sides of the equals sign and not a back-slash (\) anywhere.
So try...
Customer1/Project1=Customer1/Project1
Customer1/Project2=Customer1/Project2
Customer2/Project3=Customer2/Project3
Also, when it was not working, my .hgsubstate file only had a bunch of zeros in it. When it started working, it had a genuine GUID in it.
I was able to get past this problem by committing using the command line for the main repo.
hg commit -m 'Updated subrepo'
I had the same problem:
In one of my repositories committing of one of my changed subrepo modules failed with message
"abort: mysubrepo: no match under directory!"
The reason:
TortoiseHG fails to commit to the subrepository because it handles folder names case-sensitive!
Example:
Your original repository:
C:\Shared\MySubRepo
Cloning this as a subrepo into another repository by command line
hg clone C:\shared\mysubrepo <--- Note the lower cases!
will create a subrepo folder mysubrepo inside your parent repository.
Adding it to the .hgsub file as usual (I always use the platform independent '/' instead of '\', so I don't think that's the reason for the error).
Trying to commit with --subrepos TortoiseHG will end up with the "no match under directory!" error. However, commiting by command line works.
After renaming the subrepo folder mysubrepo to MySubRepo (as the original folder with upper cases) TortoiseHg could commit successfully!
Maybe you have to edit the folder name also in the hgrc file, but I'm not sure if this is really neccessary, because I renamed it in the file before figuring out, that there are canse-sensitive differences in the folder name iteself. Also removing the repository from TortoiseHg Workbench's repository registry and readding it may be needed (and/or restart of the Workbench as well).
I think your problem is with specifying "Customer1\Project1" as a sub repository because Customer1 should be a nested repository as well.
Customer1 and Customer2 should both have '.hgsub' files describing the subrepos inside them (Project1/2)
Remake your Customer1 repository elsewhere and clone Project1 and Project2 into it. Add Project1 and Project2 entries to the '.hgsub' file within Customer1.
Then do the same for a Customer2 repository.
Remember that nested repositories can themselves be nested so create a 'root' repository and then clone Customer1 and Customer2 into it remembering to add entries to the .hgsub file.
Commit 'root' and you should be fine.
The key is to push changes from all instances of a subrepos to its clone master so that other clones that include that subrepos are able to pull that revision if needed.
I have all master repos in the same parent folder on my machine so it makes putting relative paths inside '.hgsub' files such as '../Project1' or '../Customer1' a simple way to push changes to my local clones from our central server.
As far as using TortoiseHG, you will be fine with v1.0 as it will create and manage the '.hgsubstate' file in a nested repository as long as you have already created the '.hgsub' file!
Adding my 2 cents.
I was receiving this error abort: customer1/project1: no match under directory on Windows in the following scenario:
repo was in a folder named MyFolder (note the upper case)
repo had a subrepo
some files (only some!) in the parent repo were commited using myfolder/filename.ext (note the lowercase)
Everything works fine, commandline commits work fine, but Tortoise complains.
Rename the files (find the lowercase ones using hg status --all and you're fine)