Can a Mecurial repository and its subrepos be cloned using --noupdate? - mercurial

I have a repository with a number of sub repos, and I wish to clone all of them without having working files. When ever I try to clone using --noupdate no of the sub repositories are available in the closed repository. Is this due to the lack of a .hgsub file in the cloned repository?

That is sort of the reason why.
More specifically, subrepos are implemented not as their own repos, but as part of the working copy their parent repos ( conceptually, you can think of a subrepo as being just a single file existing in your main repo ). However as soon as you update, the repo and subrepos will be at the same state as if you had cloned without using -noupdate.

Related

Mercurial CLONE with PULL on a repository with subrepos doesn't create a fully independent repository

I have a shell repository OriginalWithSubrepo with a subrepository Sub containing a bunch of actual files.
When I clone OriginalWithSubrepo like this
hg clone --pull --noupdate "C:\TestRepo\OriginalWithSubrepo" "C:\TestRepo\OriginalWithSubrepo-clone"
The clone thus created contains just a few mercurial housekeeping files, there is no actual data from the original Sub\.hg directory. I don't know what those files mean but apparently they are enough to recreate the repo because when I update the working directory in clone, the whole thing gets filled out with all the files, including inside the Sub\.hg directory. However, if I clone, then rename the original, and then attempt to update the clone, it doesn't work saying the OriginalWithSubrepo is not found, which means it's all based on links to the original.
This problem doesn't arise when I run clone with update, or when I clone a repository without subrepos.
It behaves the same when I clone to a network share, which is where I really want it to work.
So how do I make a fully independent clone of a repo with subrepos (w/o a simultaneous update)?
Windows XP, hg version 3.4.1
When you add the first subrepo to the parent repo, .hgsub is added to the parent repo. The subrepo only becomes a subrepo from the changeset that commits .hgsub.
When you do hg clone --noupdate --pull parent parent-clone, parent-clone is not at any changeset yet, and so not yet at a changeset at which the subrepo has been created
So how do I make a fully independent clone of a repo with subrepos (w/o a simultaneous update)?
I don't think you can do this as such.
But this may achieve what you're trying to do (I'm reading between the lines here, but I'm guessing to have the repo on the share, but without any files visible):
Create repos on your network share for your parent and sub \\fileserver\repos\OriginalWithSub\ and \\fileserver\repos\Sub\
Modify your local OriginalWithSub .hgsub set the remote path to be \\fileserver\repos\Sub\ and commit.
push your local repositories to their respective network share equivalents.
Both repositories now exist on the network share, without any files visible apart from inside .hg, and you can clone \\fileserver\repos\OriginalWithSub\ (with update) from another computer and get the full history of both OriginalWithSub and Sub.

Embedding a github repository inside a mercurial (kiln) repository - how integrated is it?

Summarised Question:
Are github-hosted sub repositories within a mercurial/kiln repository possible, and if so are they automatically updated/cloned when the parent mercurial repository is operated on by a hg clone or hg commit command?
Detailed Question:
Following on from my question that was answered so excellently here , some of my third party code is in folders I downloaded a while ago from opensource efforts on github. Since at that stage I was not using version control, those folders where just standard folders that now been incorporated as sub repositories in mercurial.
This is obviously not ideal, as for one thing, new versions of the libraries may have bug fixes, or new features I wish to use in the future. I also may need to locally customise some of the libraries.
I can see from reading this link that it possible to have mercurial "know" about those git server urls (and revisions), so I can then have mercurial clone the github hosted libraries direct from their parent repos.
Am I right in saying that when I clone the parent (mercurial) repos, those files will be pulled from github, without having to separately manage this using git?
What is also not clear is, if I were to do this, and it transpired that code might need to be customized from within that github-cloned repository, would I need to use git to manage revisions of the local files, or would mercurial do that by proxy? eg id I were to hg commit -S would mercurial invoke git on my behalf to handle that?
Am I right in saying that when I clone the parent (mercurial) repos, those files will be pulled from github, without having to separately manage this using git?
Yes, clone of a Mercurial repository that contain subrepositories will trigger a clone of the subrepos too. It really happens on update. Mercurial notices the .hgsub file and issues the needed hg clone and git clone commands for you. It uses the information in .hgsubstate to know exactly what revision to checkout.
The subrepositories can be hosted anywhere. For a Git subrepository declared like
foo = [git]https://github.com/user/repo.git
Mercurial will simply issue the corresponding clone command:
git clone https://github.com/user/repo.git foo
It's then your reponsibility to later go into the foo repo and use Git to fetch new commits as necessary. After you fetch/pull new commits, you can make a top-level commit to record the new state of the subrepo in the .hgsubstate file. Use hg summary to see if a subrepo is dirty in this sense.
[...] would I need to use git to manage revisions of the local files, or would mercurial do that by proxy? eg id I were to hg commit -S would mercurial invoke git on my behalf to handle that?
When you edit files and make a top-level hg commit, Mercurial will make sure to commit the subrepo first (if you use hg commit -S or if ui.commitsubrepos=True). If you make a top-level push, then Mercurial will always push the subrepos first so that you always have a consistent set of changes on your server.

Mercurial repository with bitbucket subrespository - how to prevent push

I am in the process of setting up some third-party subrepositories under a Mercurial repository. One subrepo is another Mercurial repo hosted on Bitbucket.
Since it is a public repo, and I am not a contributor to it, I don't wish to push back to it. However I would like to still have the repository automatically cloned when I clone the parent repository. For one thing, I'd like to have access to the collective history of the subrepository so I can see what may or may not have changed over time.
So, I made an entry in the parent repo's .hgsub file as follows:
thesubrepo = https://bitbucket.org/user/repo
and cloned the repo using
$ hg clone https://bitbucket.org/user/repo thesubrepo
I made a commit to record the subrepo state. I then went to push my parent repo back to it's server (Kiln) only to discover that it was trying to push the subrepo I back to the Bitbucket server. The push to the Bitbucket subrepository appears to not do anything, though.
I did not observe this behaviour when I made a Git subrepo in the same manner (hosted on Git hub) using an entry in .hgsub like this
abc = [git]git://github.com/xyz/abc
Is it best for me just to do this by not setting up a subrepository, and just let Mercurial store the files as files? Or (preferably) is there some setting somewhere that I can use to tell Mercurial to never actually push the contents of this subrepo back to it's source location?
I'd rather be able to configure it to only push those subrepos manually, so if anyone can shed some light on this, I would appreciate it.
I found a reference to commitsubrepos = no in another stack overflow answer, which as far as i can tell is about commits, and not pushes of sub repositories. I then looked this up on the mercurial website, in the hope there might be some reference to a setting pertaining to pushing subrepos, but... no
You cannot (currently, as of version 2.0) ask Mercurial to not push subrepositories.
The fundamental problem is that Mercurial must ensure that you have a consistent state on the remote repository when you push. It would be unsafe if you could push back to Kiln and then have a changeset there that references a revision on Bitbucket that isn't there. Mercurial doesn't know if a changeset you have locally is published or if you created it — so it has to (try to) push.
We're currently working on a concept called phases. With that in place, Mercurial will begin tracking if a changeset is created locally or already published. That can be used for subrepositories too: if there are only changesets in the "public" phase in a subrepo, then there's no need to try pushing!

Pushing mercurial repo without pushing subrepos

I'm using Mercurial 1.6. I have a repo with a few subrepos (11). I would like to push the parent repo to the default remote repo without pushing the child repos. Reasons for wanting to do this include:
I'm using SSH repos, and it takes a long time to establish a connection and push nothing to each of the subrepos.
I have commits in subrepos I don't want propagated to the remote repos (yet).
Subrepos have named branches that should not be propagated to the repote repos (and there's apparently no way to pass branch names to the push operation of the subrepos).
However, I've been unable to find a way to accomplish this. I tried deleting the content of .hgsub and .hgsubstate (without committing), but still mercurial insists on pushing the subrepos.
How can I push the changes from the local repo to the remote repo and ignore the subrepos temporarily?
I think you'll need to make local clones of the subrepos.
The problem with pushing the main repo without pushing the subrepos is that the contents of the subrepos are not part of the main repo - only their states are. The contents are referenced from the original location specified in .hgsub. So your main repo's .hgsubstate says "subrepo A is at revision abcd1234", but abcd1234 is a change you made that you don't want to push... and now what would happen if you cloned the main repo? It'd try to clone the subrepo from its original location and update it to abcd1234, but that revision doesn't exist in the original location, so the clone would fail.
Instead, you can make local clones of each external repository and reference those as the external locations of the subrepos. Then when you push the main repo, the subrepo changes will only propagate to your local clones. When you're ready to share those changes, just go over to the local clones and push from there, and you'll be able to pass branch names and so on.

How do I get changes to propagate to all subrepos in Mercurial?

I have recently switched from Subversion to Mercurial for source control and in doing so have split up one repository into several. I used subrepos to manage the dependencies between repositories. The problem is that pull is not suprepo aware so I have to go into each subrepo and pull changes in order to update a repository. Is there a better way to do this?
pull is not suprepo aware
hg pull should be subrepo aware, provided it is used with the -u (--update) option.
The hg update should, when it comes to subrepos, take them into account:
Whenever newer Mercurial versions encounter this .hgsubstate file when updating your working directory, they'll attempt to pull the specified subrepos and update them to the appropriate state.
Subrepos may also contain their own subrepos and Mercurial will recurse as necessary.
The OP CoreyD adds:
That has not worked for me.
I create two repos /repo and /sub and I clone sub into repo (/repo/sub).
Then I create an .hgsub file in /repo with this a line like this sub = ../sub and commit it.
When I make changes to /sub and then do an update in /repo /repo/sub is unchanged.
Am I doing something wrong?
That looks about right:
SubRepos or submodules (for Git) are all about referening a precise configuration (changeset ref for hg, or commit ref for Git, as explained in this SO question)
When you change anything outside of /repo, you don't change the .hgsubstate file within /repo recording the exact configuration (changeset reference).
Hence no change at all.
You could rather do your /sub changes directly in /repo/sub, commit them, then commit /repo.
Then, a clone of /repo would have the new configuration.