Can I nest subrepos in Mercurial? - version-control

I am having trouble setting up a project in Mercurial with subrepos.
Goal:
I want to set up the structure like so:
-- Build_Repo (this repo will be used to track dependencies)
-- Subrepo_A (this is the main source)
-- Modules (Part of Subrepo_A)
-- Subrepo_B
So there are three repos: Build, A, and B. B is nested inside A, A is nested inside the root build repository. The build repo will be used to track dependencies, subrepo A will be used to track the main source files, and subrepo B (and others) will be used to track module/plugin development.
Problem/Question
I have no problem setting up the initial build repo and the nested Subrepo_A by simply adding the Subrepo_A path and source to the .hgsub file and committing it to the build repo. However, when after I add the subrepo_B path/source to the build repo's .hgsub, and then try to commit I get the error message:
abort: path 'Subrepo_A/Modules/Sebrepo_B' is inside nested repo 'Subrepo_A'
Mercurial doesn't appear to like a nested repo inside an already nested repo. Is this true, or am I missing something? Any better ideas on how to manage builds/dependencies?

The problem here is one of Mercurial's inescapable constraints: a repository corresponds to a folder tree on your computer. The repository is responsible for everything under that folder tree.
When your top-level repository includes a sub-repository, it hands over to the sub-repo complete control of that part of its folder structure. So the top level can't specify another sub-repository somewhere in the first sub-repos folders.
Solution 1
Subrepo_B is actually a dependency of Subrepo_A. In that case, make your repositories reflect the true dependency by editing Subrepo_A's .hgsub file to add Subrepo_B under Modules/Sebrepo_B. This works because Subrepo_A retains control over its folders.
Solution 2
Subrepo_A doesn't depend on Subrepo_B, you were putting it there for convenience. In this case, you should make both Subrepo_A and Subrepo_B be subrepos (in different locations) of the Build_Repo.

In your situation, you'll have to add subrepoB to subrepoA.
I would suggest trying to move dependencies so that your tree only has 2 levels, but that may not be possible. It's always not a very smooth experience otherwise.

Related

How to prevent a folder from being pushed to mercurial repository?

my problem is quite simple: there is a folder in my project which I want versioned, but not pushed along with the rest of the project when I push updates. The situation is that I made an Android app stub along with the project, and I don't want to push it until it is actually somewhat functioning. It's a pretty bulky folder.
I do not want to make a separate branch for that folder, because of two problems: firstly, updating that branch whenever I pull from remote will require a merge; secondly, swapping between the two branches requires noticeable waiting time as the thousands of Android files are created/deleted, and this is very annoying to me.
I was thinking about editing .hgignore in some way, but I think it is wrong that the remote repo will then have my local folder as ignored.
Any suggestions?
You can add this snippet to your repo's hgrc file:
[ui]
ignore = /path/to/.hg/hgignore
where the point about this hgignore file is that it is non-versioned and local to you. The contents hgignore can be anything that would also be suitable for the (versioned) .hgignore. e.g:
syntax: glob
/directory/to/ignore
The name of the file, hgignore, can be called anything, but it's what I use.
You can use the configuration [defaults] section to add some "--exclude" options to usual commands (see my answer to Mercurial hg ignore does not work properly ) for more details. You can even specify which files you do not want to commit in your directory, e.g., stub/**.c for all C files in the hierarchy of directories below stub.
But.. be careful that it is dangerous to silently ignore modifications to files and also that this [defaults] section has been marked as deprecated (it is still present in 2.9.2).
If this is a temporary situation, it would solve your problem though: you would just have to remove the --exclude parts when you feel ready to commit and push your stub.

github: referring another project file revision

To prevent copy/pasting foreign code to my github repository I would like to refer from my project (in specific dir) another project files (of the specific revision)
To make things clear I'd like to achieve situation like in this repo: https://github.com/husio/vim-configuration/tree/master/bundle
How can I do so?
Not sure if it's a github only feature, or somehow git itself supports it.
You are looking for git submodules. It is a feature of git, but GitHub's file browser will resolve submodules when you view them on the site (which is what you can see in the repository you linked to).
Note that while submodules let you choose their location (within your repository), name, and commit (from the submodule's repository), they will include the entire trees of the original repositories. If you only want specific files or directories, check out subtree merge instead.

Using Coldfusion Builder and the Mercurial Eclipse plugin, how can you check in changes - including those in linked folders

We have a Hg repository set up for the root of our webserver. There are a number of projects which have their own directories and there is a common C directory for components.
In CFBuilder, I have a project set up for each of them and I'm using linked folders to make it easier to access the components.
CFBuilder and the plugin correctly show that both are under version control, and update properly when changes are made -- but when select that I want to commit from the Project > Team > Commit, none of the changes from the C directory are shown in the changes which will be committed.
Is it possible to have it work this way, or is there a preferred way to work with linked folders?
You need to set up a separate project for the Components, and do your commits from there. Changes made in your linked folders should be reflected in the C project, but if the C project is part of a different repository (which it would seem is the case, given your linked folders), you'll need to commit from that project.

Mercurial "vendor branches" from external repositories?

I want to store a project in Mercurial that contains external code (which can be modified by me) coming from Git and SVN repositories. In SVN I would solve this with vendor branches and copy the code around, but I understood that in Mercurial it's better to have different repositories for different projects, and pull between them when needed.
The project layout will be like this:
- externalLibraryA [comes from a SVN repo]
- ...with some extra files from me
- externalLibraryB [comes from a SVN repo]
- ...with some extra files from me
- externalPluginForExternalLibraryB [comes from a Git repo]
In Subversion I would create vendor dir and a trunk dir, copy all external libraries first in vendor, and then in the right place in trunk. (I think) I can do this in Mercurial too, with subrepositories, but is this the best way to do this?
I tried setting up different repositories for the external libraries, but then it seems I can't pull the externalLibraryARepo into the externalLibraryA directory of my main repository? It goes in the main directory, which is not what I want. I can also create a Mercurial mirror repository and include it as a subrepo in my main repository, but then the changes in this subdirectory go to the mirror repository, while I want them to stay in the main repository.
I'd probably just store this in one repository - note that in the link you give they are using their build system in the end to bring together the binary output from the different repos. I'm not clear on their rationale there.
If the underlying problem you're trying to solve is how to update the externals in a clean way, I'd probably use anonymous branching for that.
I.e. add the external lib to your project, and your modifications. Make sure it works. Tag with ExternalA-v1.0. Hack away on your actual project. Now ExternalA, Inc. has a new version of their stuff. Update your repo to ExternalA-v1.0 tag. Import their new version and apply your modifications on top. Commit. Now you have two heads: one with the latest version of your code (that works with ExternalA-v1.0) and one with the latest version of ExternalA (that does not work with your code, maybe). So then you merge and reconcile the two. Tag again, now with ExternalA-v2.0. Repeat as needed.
You can still keep your externals in separate repositories, but I assume that the project that is using those does not need to be up to date with changes there all the time - looks like the whole point of vendor branches is to have some point of isolation between dependee and dependants. Of course, moving the changes from the externalA project to the project that is using that will then be a manual affair (well, a copy, much like in SVN really).
It depends on whether your vendor code is going to be customized by your team or not. Our teams have had a great deal of success maintaining a named "vendor" branch on repositories with our own customizations on branches named by project name. This vendor code is then easily included in a project as a subrepository.
A caveat to this approach: if active development is going on in the subrepository, best keep it to directly editing the subrepository as a separate clone, otherwise it becomes necessary to pay close attention to the top-level repository so you don't inadvertantly bump your .hgsubstate forward to the wrong revision and break your build.
Watch out for merges of the top-level repository (your project) between versions which point to different named branches of your subrepository, as this can result in a merge between the "vendor" and "project" branches in the subrepository as it recurses, which may not be desirable.
Note that this functionality may change in the future as well, as some "warm" discussions have been taking place in recent months on the mercurial-devel mailing lists about the future of subrepository recursion.
edit:
I just saw this discussion in the related links as well, which seems relevant: https://stackoverflow.com/a/3998791/1186771

Keeping custom build configuration files in a git repository

I've got a project in a git repository that uses some custom (and so far unversioned) setup scripts for the build environment etc. I'd like to put these under version control (hopefully git) but keep them versioned separate from the project itself, while still living in the base directory of the project - I've considered options like local branches but these seem to have the problem that switch back to master (or any other "real" branch) will throw away the working copies of the setup scripts.
I'm on Windows using msysgit so I've got a few tools to play with; does anyone have a recommendation or solution?
If you really need them separate from your main git repo while still living directly within it, you could try:
creating a new repo with those script within it
and:
adding that new repo as a submodule to your repo. Except:
a/ those scripts won't live directly in the base directory, but in a subfolder representing the submodule
b/ you need of course to not publish (push) that new repo, in order for other cloning your main repo to not get those setup files
or:
merging that new repo into your main repo (with the subtree project), but:
you need to split back your project to get rid of those files
for a project with a large history, and with frequent push, that step (the split) can be long and cumbersome.
I would consider a simpler solution, involving some evolution to your current setup files:
a private repo (as in "not pushed") with those setup files
environment variables with the path of your main git repo in order for your setup files (which would not be directly within the base directory of said main repo) to do their job in the right directory (like beginning for instance with a 'cd right_main_git_repo_dir').
I want to share an additional solution and some samples from which to start.
I've has a similar problem in attempting to build Mozilla Firefox with Buildbot -- I need to have some files in the root folder (namely the .mozconfig file and some helper scripts) and I wanted to version them separately.
My solution is as follow:
checkout the Firefox code from the Mercurial repository;
checkout an additional repository with the additional file I need;
before starting the build, I copy these file to the folder with the Firefox code.
This approach is implemented in the following repositories:
buildconfig-mozilla-central: it contains the Buildbot configuration, which
pulls both repositories
copies the files from the scripts repository
and start the build;
buildscripts-mozilla-central: the repository with the build configuration and helper scripts.
Please note that the code might not be well factored (for example the paths) but it should be a good starting point.
This procedure is tailored for Firefox, but it can be applied to any repository.