Mercurial Nested Repo Issue - mercurial

I have accidentally created a repo in a sub directory of another repo
Since doing this the sub repo now contains a number of commits
I realised my mistake when I attempted an hg st on the original (parent?) repo and it complained of a file being inside a nested repo
What I would like to do is somehow move the sub repo history up into the parent then just delete the sub repo so I have just one repo
The dir structure is like this:
my original repo:
core/
my directories containing src code i'm trying to version control:
core/src/
core/test/
my accidental repo is in:
core/src/
e.g. its this one I want to push?/merge? up a level into the core/ repo, then just kill the core/src/ repo (by deleting the .hg dir)
I have read a few stack overflow discussions on this but they seem to be trying to solve more complicated sub repo scenarios. I'm hoping a straightforward (dare i say it simple) solution may exist?
I have not had much luck with the HG wiki on this either

Preserving history
Depending on the version you're using, you can use the Transplant or Graft extension to achieve your goal.
I've never done that and don't have time to test it before hand, but something like the following steps should work :
Move your actual core/src/ dir somewhere else, for example ~/temp.subrepo/
Remove the subrepo from the .hgsub file
Use the Convert extension to rename the files in the subrepo (see below for a quick example)
Transplant the changes : hg transplant -s ~/temp.subrepo.converted/ 0:tip
To convert the subrepo, you can use something like this :
$ echo include . > /tmp/myfilemap
$ echo rename . src/ >> /tmp/myfilemap
$ hg convert --filemap /tmp/myfilemap ~/temp.subrepo/ ~/temp.subrepo.converted/
Like I said, I'm not sure this will work out of the box, but it's at least a lead. If you have any problem, don't hesitate to ask.
History doesn't matter
Or maybe the simplest solution is just to remove the .hg directory in the subrepo, remove any mention of the subrepo in the .hgsub file of the main repo, and just add and commit the files :
hg add core/src
hg commit
You will lose all the history of the subrepo, but at least the solution is really simple.

Related

Cloning a mercurial repository, .hgsub refers to a dead external subrepo

We're trying to clone a Mercurial repository A where it references a subrepository B that's moved hosts. We'd like to update .hgsub in A to point to the new location of B, but it's a chicken and egg problem if we can't hg clone A in the first place.
Does anyone know how to work around this?
$ hg help subrepos
...
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.
$ man hgrc
...
subpaths
Defines subrepositories source locations rewriting rules of the form:
<pattern> = <replacement>
Where pattern is a regular expression matching the source 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/.
All patterns are applied in definition order.
...
So, you can do it in .hgrc in a [subpaths] section.
First note that clone is init + pull + update and that subrepo cloning is part of the update step, not the pull step. This means that you can avoid clone failing simply by skipping the update step:
$ hg clone -U <url>
Now the problem is reduced to "how do I update to a revision with a problematic .hgsub/.hgsubstate file?" There are two possibilities here:
remap subrepos using the [subpaths] feature (see hg help subrepo and hg help config)
manual update and repair
A "manual update" can be done like this:
$ hg revert -a -r default -X problematic-file
[adding a bunch of files]
$ hg debugrebuildstate -r default
Now you can manually fix-up your subrepos and .hgsub and commit. Be sure to test your fix with a clone before pushing it.
Also, see this mailing list thread on the topic: http://markmail.org/thread/ktxd2rsm7avkexzr
It could be easier to tamper with DNS as a quick workaround (e.g. hosts file on Windows) and then fix .hgsub.

Would like to do a mercurial clone with filter of patterns in hgignore

Over time a number of the developers have committed files that were then added to the .hgignore. From what I hear there is no way to remove items from the history of mercurial, which is ok. But I also heard that there is a way to do a clone, I think using the convert plugin, to clone/export a repo while specifying which files to not include in the conversion.
I can't help but think that someone out there has a script that does this export/filter/convert using the patterns from the .hgignore file.
Has anyone created such a beast?
You could create a filemap from .hgignore doing something like this:
hg clone -U yourrepo temprepo # create a temp repo with no files in working dir
cd tmprepo
hg revert --all # put files in working dir
hg forget ** # un-add the files
hg status --ignored --no-status | sed 's/^/exclude /' > ../filemap
that will get you a filemap you can pass into hg convert that removes all the added files that would be ignored given your .hgignore.
Do understand though, that running convert creates a whole new repo that is unrelated to your previous repo. All existing clones will be unusable with the new one. It's not normally worth it.
hg convert is indeed the thing you want to use.
You will want to create a file map (just a text file) which will list all of the things you either want to include, exclude, or rename:
include subfolder
exclude subfolder/supersub
etc...
Read the following for a more concrete example:
https://www.mercurial-scm.org/wiki/ConvertExtension#A--filemap
Once you have created this file you will just use the following command:
$ hg convert --filemap my_file_map /path/to/source/repo /path/to/dest/repo
The source repo will not be modified and a dest repo will be created. I don't want to just copy verbatim what the documentation already says so here is the link:
How to keep just a subdirectory (or run on the mercurial repo):
https://www.mercurial-scm.org/wiki/ConvertExtension#Converting_from_Mercurial

cloning a part of the repository

Is it possible to clone a part(a single folder or even a single file) of a repository?
Basically it's not possible, there is nothing like Subversion's svn checkout http://example.com/project/dir1.
But you can get a partial clone by rewriting the changeset history with hg convert. On the upside, it will be a partial clone. On the downside, the resulting repository will be not related any more to the initial one. The changeset IDs will be different and it will be very hard to continue interacting with the source repo.
An example of creating a partial clone. Suppose you want to clone only the doc directory from the repo:
$ hg clone http://example.com/project local-project-repo
$ cat > filemap.txt << END
include doc
exclude .
END
$ hg convert --filemap filemap.txt local-project-repo docs-only-repo
Nope. That's called partial cloning (some file paths but not all) or shallow cloning (some revisions but not all), and not provided because the point of a DVCS is that everyone has a full copy of the full repository.
Some online repositories will let you download .tar.gz files of all the files in a specific revision or a specific file from a specific revision, but that's not done using the Mercurial tool.

hg convert - trying to move a directory from one repo to another

So I have a directory called flash. I'd like to move it totally from an existing Mercurial repo located at ~/wdm to another existing Mercurial repo, located at ~/wdm-js.
I've been told this is possible with hg convert, but I don't really know how this works. I have tried the following, but think I may have got something wrong.
Having read up on the hg convert for Mercurial docs, I've created a filemap, which reads as follows:
include flash
Then I've gone to ~/wdm and run the following command:
$ hg convert . ~/wdm-js --filemap ~/filemap.txt
I've seen a load of output as follows:
scanning source...
sorting...
converting...
413 [doc/design][m]: first stab at a design doc for model (sent to list).
[412 more history items]
So this looks fairly promising. But when I look at wdm-js there is no flash directory there. And none of the flash directory files have moved from the wdm directory. And the hg status of both repos looks no different.
Do I still have to copy the flash directory across manually, and hg add/hg remove all the files manually to both repos?
Or... should this have been done for me, meaning that I have messed up in some way?
hg convert doesn't update the working directory in the destination repository (it leaves it at the original null revision), so do a hg update there to see the files. Also, the way you ran it, it copies the files; you can either delete them from the original repository via hg forget or hg remove, or use hg convert again using a filemap with the line:
exclude flash
To copy into existing repository you need first copy flash folder into new repository as you did it with convert command and then push the changes from new repository into existing target repository.

How do I add a subrepo to an existing repository in mercurial

What is the best/easiest way (or is it even possible) to add an existing repository to another existing repository as a subrepo?
Situation is I have an existing (main) project where I want to include a library project so that i can edit the library project from the main project, and commit the changes to the library project when comitting the main project.
Also: Do I need to clone/push/pull to the original library project, or is this done automatically when committing in the main project?
Regards
Jesper Hauge
The subrepo documentation confused me so much so I wrote a shell script to abstract that part of it away.
addsubrepo.sh
Call it like
$ cd $TOP_OF_HG_PROJECT
$ addsubrepo.sh $URL_TO_HG_PROJECT relative_path/you/want_to/put_the_subrepo
Reading the docs, the subrepo plugin supports this functionality.
I haven't used it yet, but will likely start using it in the near future.
It is improved every release of Mercurial, and I believe people are successfully using it. It seems to get a reasonable amount of attention, and was on the agenda for the last coding blitz.
According to the help, pull, push, commit etc should act on the subrepo as well. It sounds like a commit will check if there are any changes in the subrepo. If there are, they will be committed, and the new changeset in the subrepo will be recorded in the .hgsubstate file. This file, as well as the changes in the main repo will then be committed.
When you clone, Mercurial should see the .hgsubstate as well as the .hgsub file, and correctly pull the subrepo, and update to the correct revision.
You might want to use the deps extension.
Here's how I did it:
$ cd /projects/main_project
$ hg clone /projects/plugins/awesome plugins/awesome_plugin
$ echo plugins/awesome_plugin = plugins/awesome_plugin > .hgsub
$ hg add .hgsub
$ hg commit -m "added awesome_plugin plugin as a subp-repo"