How to clone Mercurial to Subversion? - mercurial

I'm a VERY happy user of bitbucket and mercurial after years of putting up with subversion (and CVS, SourceSafe and others; anybody remember SCCS?). I've considerable project history now in my local hg repo, pushed daily to bitbucket and thence to my home machines.
Problem is, my company wants me to maintain a copy of this history in subversion. And I've hit a stone wall trying to set this up. I've installed hgsubversion, I think correctly. And I've used svnadmin to create an empty svn repository ready to hold the hg history.
But now what? The instructions say to start by pulling a clone (of nose? what's that? I assume this means checkout a copy of the new empty svn directory. OK did that.
But now what? I assume the next step is to push my real local hg clone to the empty svn repo I just checked out. But nothing I've tried will do this. Pull fails as follows, reporting "unrelated repository" (as I recall I gate it the URL of my master local hg repo to get around the "Needs a URL" popup on everything else I've tried.
found new changeset 139d02f4b233
examining 4e97a23b6815:342df9e52cec
abort: repository is unrelated
[command returned code 255 Mon Apr 25 11:29:33 2011]
The result of all this fumbling around is a directory with .hg, .svn and .hgignore entries and nothing else.
So, I feel I'm missing something basic that hundreds of others must have tried by now. Can someone please help me get started? Thanks!
PS: Currently the intent is to maintain SVN permanently as the team repo and push changes there from Hg periodically which would remain the main client for me indefinitely. In case this matters...

You can use the convert extension:
hg convert --dest-type svn mercurialrepo svnrepo
And hgsubversion allows you keep both of them in sync ( bidirectional)
Answered here at SO already:
Converting from Mercurial to Subversion
Migrating from Mercurial to Subversion

Perhaps look at the answers to this question.
Hgsubversion is for working with a repository cloned from SVN using Hg, not the other way around.

Related

hg largefile XXX missing from store (needs to be uploaded)

A coworker got this error after pulling from the repo. I searched for an answer online on how to solve it but couldn't find anything. I figured out a way to solve it so posting it below for anyone else with the same issue.
I asked everyone else working on the repository to check their user cache folder (C:\Users\username\AppData\Local\largefiles on Windows) to see if they had a file with that id ("XXX" from the title).
One of them did, the original author of the file.
I asked him to send it to me, I remote connected to the server that has the central repo. I then copied the file both to the server's cache and into .hg\largefiles
The user could then pull again and push and everything worked.
LF extension seems not compatible with keyword extension.
With these both extensions, at the commit, the LF is NOT put in the configured folder on the PC and then raises this error at push.
If you disable the keyword extension, it's perfectly working.
Unfortunately, I've not found any additional explanations.
If someone could provide a stable solution, it will be great.
It looks like hg pull is happily sparse, but hg push is not; thus you need all largefiles for every revision not already present on the new remote, so that it can populate for history and allow clients to successfully pull at any revision. Which makes sense.
When migrating to a new hg server, I hit this issue. The "within Mercurial" solution was to download all largefiles, for all commits, to my local repo, and then push to the new server repo:
$ hg lfpull --rev 1-tip
$ hg push newbox
(Disclaimer: my Mercurial-fu is weak, I only use it for this one largefile repo)

Is it possible to convert a googlecode hg repository to a largefile repository?

I have a remote hg repository hosted on googlecode. Thus I don't have admin access to run e.g. lfconvert on it (as far as I know), and of course lfconvert can only be used on local repositories.
So, is there any way to a convert an googlecode hg repository to a largefile repository?
(one idea is to convert a local clone of the repo to a largefile repo and then push the changes to the "central" googlecode repo, but I fear trying that without knowing if it is a valid approach).
Using your idea to do a local conversion and push, you can take advantage of the 'reset' feature for your repositories:
Do a local clone.
Convert to largefiles: `hg lfconvert normal_repo largefiles_repo``. Do NOT delete the original clone until you are sure everything works.
Reset the hosted repository (See https://code.google.com/p/support/wiki/MercurialFAQ#Mercurial_FAQ).
Push the largefiles repository.
Pushing the largefiles repository without reseting seems problematic because the largefiles repository is essentially a fork of the original one starting at the point the first largefile was committed.
If the push fails*, you can push the original clone and you'll be back where you started without any data loss. (One of the many advantages of DVCS. :-))
The big downside of course is that everybody who has ever cloned your project will now be working from a different fork of the repository. This is always a danger when you do anything involving changing history and is the motivation for Mercurial phases. If you want to be 'kinder', you can start a second project for the largefiles version and place a link at the original project cite describing the move.
[*] I can't figure out from Google Code's documentation whether the largefiles extension is supported. There is a reviewed feature request, but I couldn't find any mention of the request actually being implemented. The push failing would probably be a good indication that largefiles isn't supported though...

mercurial: recover from deleted repository after commit, before push

I have a mercurial repository my_project, hosted at bitbucket. Today I made a number of changes and commited them to my local repository, but didn't push them out yet.
I then majorly stuffed up and fatfingered rm -rf my_project (!!!!!).
Is there some way I can retrieve the changes that I committed today, given that I hadn't pushed them out yet? I know a day's worth of commits doesn't sound like much, but it was!
All the other clones I have of this project are only up-to-date to the most recent push (which didn't include today's changes).
cheers.
mercurial cannot save you. The data from mercurial is stored in a hidden directory in the base of your project folder. In your case, probably at my_project/.hg. Your recursive delete would have trashed this folder as well.
So maybe a file recovery tool?
No. The changes are only stored in the local repository directory (the .hg directory therein) until you've pushed. They're never put anywhere else (not even /tmp).
There is a possibility that you'll be able to recover the deleted files from the disk, though; search around for instructions and tools for doing that.
I'm afraid the commit is deleted together with the working copy and file recovery tools are your only option to recover the missing .hg folder. I see you could recover the code from the install — great!
If you're afraid of this happening again, then you could install a crude hook like
[hooks]
post-commit = R=~/backup-repos/$(basename "$PWD");
(hg init "$R"; hg push -f "$R") > /dev/null 2>&1 || true
That will forcibly push a copy of all your commits to a suitable repo under ~/backup-repos. The -f flag ensures that you will push a backup even if you play with extensions like rebase or mq that modify history. It will also allow pushing changesets from unrelated repos into the same backup repo — imagine two different repos named foo. So the backup repositories will end up with a gigantic pile of changesets after a while and you might want to delete them once in a while.
I tested this briefly and for everyday work I don't think you'll notice the overhead of the extra copy and you might thank yourself later :-)

When using Mercurial HG, how to just get the latest code?

I am new to Mercurial HG. My friends created a repo and I am going to use it.
I installed TortoiseHG and trying to get the latest code. I found that when using Clone operation, it will pull all code to my local, including the histories (Am I right?). This is not needed for me. I just wanna get the latest code. Is there an operation for this?
In short, no.
In a bit longer: Mercurial doesn't yet support “shallow” clones where you only get part of the history. So each time you clone you pull in the entire repository with all changesets.
Additionally, unlike Subversion, there is no way to make a “narrow” clone where you only checkout a portion of a repository. For example, if a repository has directories foo/ and bar/, there is no way to get only the bar/ directory. In other words, Mercurial always operates on project-wide snapshots.
The easiest way to achieve what you want:
hg archive [destination folder]
Once you cloned a repository, to get the code of the "tip" (the last version of the current branch - the default one if not precised) you just need to update.
You have an update action in TortoiseHG. Once done, you can look at the files in the folder.
If you wanted another state of the repository (an old version, or an old tagged state) then it's still the update command, with other parametters (see the docs or the TortoiseHG interface).
If you only want the latest code, and you don't intend to do anything related to the repository with it, like commit, or diff to older versions, or whatever, then you it depends on where you got the code from and how.
If he is using one of the hosting services, like bitbucket, there's usually a download link which gives you just the source code.
For instance, if you go here, there's a "Get source" link up and to the right which gives you a few choices in the file format (zip or whatnot.)
If you got the files somewhere else, you need to explore the interface you got them from. Try just pasting the link you cloned from into your browser and see what you get.
Sure. Clone the repository, then delete the .hg subdirectory.
I might be a bit late but actually it is possible to forget some history with Mercurial. You just need to enable convert extension from Your mercurial.ini file or .hgrc file.
[extensions]
hgext.convert=
Now you are able to use convert extension to "clone" only changesets starting from the revision specified.
hg convert --config convert.hg.startrev=[wheretostart] path_to_full_history_repo path_to_new_repo
Just note that this is not the same operation with hg clone. That's why the source repository must be a local repository. For example if we have a repository in folder MyProject and we want to forget all the changes done before revision 100. We can use the following command:
hg convert --config convert.hg.startrev=[100] MyProject MyShrinkedProject
If You are going to use this shrunken repository on a "central server" remember to take care of that everybody clones it before they continue working. Repositories are not compatible with each other anymore.
Mercurial now supports shallow clone using remotefilelog extension. Extension is bundled with mercurial probably since version 4.9. Older versions need to download the extension e.g. from github.
You have to enable it on the server e.g:
[extensions]
remotefilelog =
[remotefilelog]
server = True
serverexpiration = 14
and on client
[extensions]
remotefilelog =
[remotefilelog]
cachepath = /some/path
cachelimit = 5 GB
Than you can do shallow clone with much smaller footprint a and faster clone speed:
hg clone --shallow ssh://user#server/repo

Is it possible to checkout a single directory from a Mercurial (HG) repository?

So, I'm trying to checkout just the TestNG plugin from the Netbeans contrib repository. (Or is it module? I'm new to Mercurial, so I don't really know the lingo yet.)
When I run the following command...
hg clone http://hg.netbeans.org/main/contrib/
...I get the entire repository, which contains all of the the contrib plug-ins. Is it possible to just pull this location?
http://hg.netbeans.org/main/contrib/file/tip/testng/
Thanks!
This concept is called "narrow cloning" and no, it's not possible at the moment in Mercurial.
It's on the radar of some of us that contribute to Mercurial but it's a hard problem to solve. For example:
How do you calculate the hash of any new commits you make if you don't have all of the files in the repo?
What happens if you try to view the history of a file in contrib/testng if that file was moved from another folder?
I'm not sure, but I think the answer in the general case is "probably not".
If the repository is local (it doesn't sound like it is in your case), you can do something like:
hg archive -R /path/to/my/repo -I /path/to/my/repo/folder/i/want export-folder-name
(The command would need to be something that exports non-VC'd files, rather than creating a partial repo, since the .hg stuff is stored once at the toplevel, rather than in pieces in each folder as SVN does.)
It doesn't work on remote repositories, though. Neither does "hg log", and the hg folks explained why:
Imagine I send a log -p command to http://www.kernel.org/hg/linux-2.6, which is
approaching 100k changesets. At one diff per second (lots of seeking), this will
take about 3 hours of CPU/disk time on the server, nevermind metric tons of
bandwidth. It would be faster and simpler for everyone just to clone the repo
and do the log locally.
I suspect hg archive can't work remotely for the same reason.