Mercurial: copying ONE file and its history to another repository - mercurial

I'm wondering if I can copy one file and its history from one repository to another, without having to import the whole other repository.

You can use the ConvertExtension to export just that one file from the first repository into a new temporary repository, then use hg pull -f to import the new repository into the target repository.
Create a filemap for the ConvertExtension with the single line:
include path/to/file
Then use:
hg convert path/to/original path/to/temporary --filemap filemap
to create the temporary repository. Next, in the target repository, do:
hg pull -f path/to/temporary
to pull in that file with its history. This will create a new head, so use hg merge to merge it with the head in your target repository.

Just to add to Niall C.'s answer, you can rename the files you are importing to place them at the correct place too.
You must first rename the file, then include it. Your filemap would look like that:
rename "original/path" "wished/path"
include "original/path"

Related

Move a file inside a mercurial forest from one repo to another?

Is there an hg command to move a file within a forest from one repo to another?
That is, a command, similar to what hg mv does for a single repository?
Or do I have to delete the file in one repo and create a copy in the another repo?
There are no commands to move files between repositories, so yes, copy and commit the file in the other repo and delete from the original.

Create a Mercurial repository out of an existing directory in another repository?

I want to split up one of my Mercurial repositories into two separate repositories. In particular, I want to take a directory sitting at the root level of the repository and convert that into it's own repository.
My initial thought on how to do this is to tell the existing repository to forget about that particular directory, add the directory to .hgignore, and then convert the directory into it's own repository. However, I'd like to preserve the history of the directory in the new repository.
How can I achieve this?
Convert extension with --filemap option will do it. See Converting from Mercurial part
It's also useful to filter Mercurial repositories to get subsets of an
existing one. For example to transform a subdirectory subfoo of a
repository foo into a repository with its own life (while keeping its
full history), do the following:
$ echo include subfoo > /tmp/myfilemap
$ echo rename subfoo . >> /tmp/myfilemap
$ hg convert --filemap /tmp/myfilemap /path/to/repo/foo /tmp/mysubfoo-repo

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.