Multiple paths for subrepositories - mercurial

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.

Related

Is there a Mercurial (hg) equivalent of `git remote -v`?

That is, does Mercurial have a command to tell where it was originally cloned from?
The following question seems to not serve that purpose: Mercurial repository identification
I can't recall special command for it, just because I always read repo's hgrc [paths] section by eye due to fact (hg help config)
The following special named paths exist:
"default"
The URL or directory to use when no source or remote is specified.
'hg clone' will automatically define this path to the location the
repository was cloned from.
but if you want hg command and trust hgrc's content (which can be edited at any time), you can use hg config paths.default which output key from repo-config, without warranties of using this URL for the whole lifetime of repo

In a mercurial repository, how to set origin path for git subrepos during hg update?

I have a mercurial repository with a clone on several computers. In particular, I have a Ubuntu computer where the repository resides in ~/.vim and a Windows computer with a related repository in C:\Users\ben\vimfiles.
This repository contains subrepositories, some of them git subrepositories. For example, from .hgsub:
pack/thirdparty/start/signify = [git]pack/thirdparty/start/signify
I wanted to merge changes made in each repository. So I cloned the repository from my Ubuntu computer to a USB stick, plugged it into my Windows computer, and pulled from the repository on the Windows computer into the clone on the USB stick. So far, so good.
Now I go to merge, or even just update to any of the versions coming from the Windows computer. I got an error like this:
pulling subrepo pack/thirdparty/start/signify from /home/ben/.vim/pack
/thirdparty/start/signify
fatal: 'C:/Program Files/Git/home/ben/.vim/pack/thirdparty/start/signify' does not appear to be a git repository
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
abort: git fetch error 128 in pack/thirdparty/start/signify (in subrepo pack/thirdparty/start/signify)
[command returned code 255 Thu Dec 13 11:24:15 2018]
After a bunch of digging, I eventually solved the issue by manually editing the .git/config file in every single git subrepo to change the origin path from /home/ben/.vim to C:/Users/ben/vimfiles.
What's the correct way to do this using only Mercurial commands or configurations? Using TortoiseHg, when I update (but not merge!) I can select any of the saved paths to pull subrepos from. This seems to manually override the paths.default configuration for the pull operation. But, that setting seems to be ignored by the git subrepos.
From the mercurial's documentation on subrepositories (accessible on command line through hg help subrepos):
Subrepositories
...
Remapping Subrepositories Sources
A subrepository source location may change during a project life,
invalidating references stored in the parent repository history. To
fix this, rewriting rules can be defined in parent repository hgrc
file or in Mercurial configuration. See the [subpaths] section in
hgrc(5) for more details.
Documentation on subpaths:
subpaths
Subrepository source URLs can go stale if a remote server changes name
or becomes temporarily unavailable. This section lets you define
rewrite rules of the form:
<pattern> = <replacement>
where pattern is a regular expression matching a subrepository source
URL and replacement is the replacement string used to rewrite it.
Groups can be matched in pattern and referenced in replacements. For
instance:
http://server/(.*)-hg/ = http://hg.server/\1/
rewrites http://server/foo-hg/ into http://hg.server/foo/.
Relative subrepository paths are first made absolute, and the rewrite
rules are then applied on the full (absolute) path. If pattern doesn't
match the full path, an attempt is made to apply it on the relative
path alone. The rules are applied in definition order.

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.

Move Mercurial Repository To Another Server

We have a project that lives in a mercurial repository.
Our customer would like to take ownership of the code base by doing the following:
Set up a mercurial repository on a server belonging to the customer.
Import the existing code into the new mercurial repository.
What is the best way to achieve step 2?
Is it a simple matter of doing the following:
Clone the existing mercurial repository:
hg clone <existing mercurial repo URL>
Push the cloned repository into the new one:
hg push <new mercurial repo URL>
Am I missing any steps? What about the hgrc file? Does it have to be modified in any way prior to pushing the project into a new repository?
Yes, you can do what you state, however it is worth noting that if you do a simple hg clone of your main repository, then a link will exist between the two, which may not be what you want. You can remove this link by editing the .hg/hgrc file and removing the default = ... item in the [paths] section.
I find that a better way is to do it without cloning. This way you don't have the link between repositories, which as this is going to a customer may be what you want.
The basic method is to set up a new repository with no changesets, and then bring in all of the changesets in one of three ways:
Push the changes from your repository to the new repository.
Pull the changes from into the new repository from the old.
If you don't have access to the new repository, create a bundle that can be provided to the customer - this can then be unbundled or pulled into the empty repo.
Pushing and Pulling is done as you normally would, but specifying the repository location:
// create the empty repository
hg init .
// pull in everything from the old repo
hg pull /projects/myOriginalRepo
or to push...
// create the empty repository
hg init /projects/myNewRepo
cd /projects/myOriginalRepo
hg push /projects/myNewRepo
Creating a bundle is perhaps a nicer way, as you can write the bundle onto a DVD and give it to your customer wrapped in a bow with a nice greeting card:
cd /projects/myOriginalRepo
hg bundle --all ../repo.bundle
Everything gets written out to a single file, which can then be extracted with hg unbundle repo.bundle or hg pull repo.bundle, into a repository with no existing changesets.
Regarding the hgrc file, as already mentioned in another answer it is not a controlled file, and so won't be copied. However, any contents are likely things like hooks to perform auto-building, or validating changesets before they are applied. This is logic which would probably only make sense to your own organisation, and I would suggest you wouldn't want this to be imposed on your customer - they are, after all, taking ownership of your code-base, and may have their own systems in place for things like this.
In the simple case - it's all.
But if you have modified .hg/hgrc file then you need to move it to the remote server manually and (if necessary) modify it correspondingly to a new environment.
Ie: you could have hooks set up in the original repository.
As of clients - just change a path to a repository in a default section (or any other section if you have several specified)
To move the master repository, you need to (a) create the new master repo and (b) tell the existing clients about it.
Create the new master repo any way you want: cloning or init+pushing, it makes little difference. Be sure to move any contents of the old repo that are not under version control, including .hgrc and any unversioned or ignored files that are not discardable. If you cloned, edit the new master's .hgrc and remove the default path, so that it doesn't try to talk to the old master repo any more.
Existing clones of the old master repo still push/pull from the old master. Everyone must edit their .hgrc, updating default (and/or default-push) so that it points to the new location. (They may also need to update authentication credentials, of course).
Only then is the migration complete. Remove (or move/hide) the original repo so that if someone forgot to update their repo path, they'll get an error on push/pull instead of pouring data down a memory hole.

how do i setup a local working directory to work with a local repo using Mercurial

Following is the scenario: I have a remote Mercurial repository at ssh://remotehost//dir/repo and I am able to clone it to a local host "pandora" in directory /home/user/localrepo/.
Now, I have a superset of this remote repository, where I add my own testing framework, but do not want to merge to the main depot until I am certain it works. So I clone this "local" repo to /home/user/workingdir/ but when I issue the command to do so
$ hg clone /home/user/localrepo/
only the repository folder gets copied none of the files get copied.
I'm not sure what you mean when you say that "only the repo folders gets copied". So there's two things you can try :
Try to do a hg update in your new clone.
List the directory in /home/user/workingdir and if there is a directory name localrepo in it, this is actually your repository. To clone in the current directory, you must do hg clone /home/user/localrepo .
This sounds odd but try a few things:
First in the local repo that you cloned from do a
hg status -A
are all the files that you think should be in there in there? If not are you at the tip of the repo.
You can see what revision you are at with
hg parent
If you want to just go to the tip do hg update
If there still aren't any files listed in the repo do the same to check the one on the server.
If there aren't any files on the server you will need to add all of the files you want mercurial to track, mercurial doesn't automagically start tracking files in the repo location.
(Use hg add --all to add all of the file in the entire directory tree under the repo location.)
If there are files in the local repo, check the testing area and make sure that it is on the proper changeset.