Move Mercurial Repository To Another Server - mercurial

We have a project that lives in a mercurial repository.
Our customer would like to take ownership of the code base by doing the following:
Set up a mercurial repository on a server belonging to the customer.
Import the existing code into the new mercurial repository.
What is the best way to achieve step 2?
Is it a simple matter of doing the following:
Clone the existing mercurial repository:
hg clone <existing mercurial repo URL>
Push the cloned repository into the new one:
hg push <new mercurial repo URL>
Am I missing any steps? What about the hgrc file? Does it have to be modified in any way prior to pushing the project into a new repository?

Yes, you can do what you state, however it is worth noting that if you do a simple hg clone of your main repository, then a link will exist between the two, which may not be what you want. You can remove this link by editing the .hg/hgrc file and removing the default = ... item in the [paths] section.
I find that a better way is to do it without cloning. This way you don't have the link between repositories, which as this is going to a customer may be what you want.
The basic method is to set up a new repository with no changesets, and then bring in all of the changesets in one of three ways:
Push the changes from your repository to the new repository.
Pull the changes from into the new repository from the old.
If you don't have access to the new repository, create a bundle that can be provided to the customer - this can then be unbundled or pulled into the empty repo.
Pushing and Pulling is done as you normally would, but specifying the repository location:
// create the empty repository
hg init .
// pull in everything from the old repo
hg pull /projects/myOriginalRepo
or to push...
// create the empty repository
hg init /projects/myNewRepo
cd /projects/myOriginalRepo
hg push /projects/myNewRepo
Creating a bundle is perhaps a nicer way, as you can write the bundle onto a DVD and give it to your customer wrapped in a bow with a nice greeting card:
cd /projects/myOriginalRepo
hg bundle --all ../repo.bundle
Everything gets written out to a single file, which can then be extracted with hg unbundle repo.bundle or hg pull repo.bundle, into a repository with no existing changesets.
Regarding the hgrc file, as already mentioned in another answer it is not a controlled file, and so won't be copied. However, any contents are likely things like hooks to perform auto-building, or validating changesets before they are applied. This is logic which would probably only make sense to your own organisation, and I would suggest you wouldn't want this to be imposed on your customer - they are, after all, taking ownership of your code-base, and may have their own systems in place for things like this.

In the simple case - it's all.
But if you have modified .hg/hgrc file then you need to move it to the remote server manually and (if necessary) modify it correspondingly to a new environment.
Ie: you could have hooks set up in the original repository.
As of clients - just change a path to a repository in a default section (or any other section if you have several specified)

To move the master repository, you need to (a) create the new master repo and (b) tell the existing clients about it.
Create the new master repo any way you want: cloning or init+pushing, it makes little difference. Be sure to move any contents of the old repo that are not under version control, including .hgrc and any unversioned or ignored files that are not discardable. If you cloned, edit the new master's .hgrc and remove the default path, so that it doesn't try to talk to the old master repo any more.
Existing clones of the old master repo still push/pull from the old master. Everyone must edit their .hgrc, updating default (and/or default-push) so that it points to the new location. (They may also need to update authentication credentials, of course).
Only then is the migration complete. Remove (or move/hide) the original repo so that if someone forgot to update their repo path, they'll get an error on push/pull instead of pouring data down a memory hole.

Related

Mq on a subrepo without write access

I have a dependancy as a subrepository (without write access to) in my project.
I'd like to add a few personal customizations to that subrepository - possibly using mq.
I also would love to be able to just clone the main repo to build it. Currently I have to:
clone the repo - with subrepositories getting cloned automagically
manually clone all the patchqueues for subrepositories
How do I get rid of step 2? Is it even possible without an outside script? (I'm using bitbucket if it makes any difference).
One notion is to make the subrepo not the repo to which you have no write access, but a clone of your own based on their repo.
cd myclones
hg clone http://notmydomain.com/their-repo my-clone-of-their-repo
and in your project's .hg/hgrc you use a [subpaths] section to map their URL to your local clone:
[subpaths]
http://notmydomain.com/their-repo = ../my-clone-of-their-repo
Then you end up with your repo using your local (read-write) clone of their repo to which you otherwise have read-only access. This has a few benefits:
faster -- you're only checking local repositories for all actions
writeable -- you can edit directoy in myproject/their-repo and commit and push (to your local clone)
And when you want to merge in their upstream changes you just go into ../my-clone-of-their-repo and hg pull and hg merge their updates into your customizations.

Can I mark a branch as 'not going to push'?

I use named branches in Mercurial.
In doing so I have created one branch called playground where I can try out various wacky experiments. I never intend to merge this branch into any others and I never want to push it to our main repository.
Since creating it, every time I do a push I am told I have added a new branch and I have to use the --new-branch flag. At this point hg push -b default (or whatever branch I'm pushing) works fine but it's annoying. Is there any way to suppress that message by letting Hg know that I am not interested in pushing that branch ever?
Starting with Mercurial 2.1 (released in February 2012), you can mark your changesets secret to keep them from being pushed to another repository. You use the new hg phase command to do this:
$ hg phase --force --secret .
This mark the current working directory parent revision (.) as being in the secret phase. Secret changesets are local to your repository: they wont be pushed or pulled. Pushing now looks like this:
$ hg push
pushing to /home/mg/tmp/repo
searching for changes
no changes to push but 2 secret changesets
There is no equivalent mechanism in older versions of Mercurial. There your best bet is to create a local clone for the changesets you don't want to push.
Update:
Mercurial 2.1 introduced the hg phase command which allows users to control what change sets are exchanged with remote repositories. #MartinGeisler answer to this question details this method.
Original Answer:
If you want to create a local branch of your code you have a couple options. You can hg clone the repository which will locally create a branch of the entire repository in your filesystem. The other alternative is you can try to use a Mercurial extension like LocalbranchExtension.
There are many ways to branch in Mercurial without using a named branch. Just find a method that suits your needs.
Further reading: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
In addition to the excellent answer above concerning phases, you can also specify 'default-path' (in the [paths] section of your .hgrc) to refer to the local repository:
[paths]
default = ...
default-push = .
This will cause all outgoing changesets to be compared to the specified repository. In this case, comparing outgoing changesets in your local repository TO your local repository results in nothing to push.
You can still pull/update/merge from the main repository, but no push will ever send anything back to that main repository.
If you work on multiple machines/repositories, you can set one up as described above, and configure the others to specify the 'default' path to point to the server that pushes to itself. In this way, the other machines can push/pull to your local central repository, and these changesets will never escape your carefully configured collection of repositories.

Mercurial: How can I import only some changesets from a repository?

I have a repository, called "my project" based in a framework called "framework". The two of them have each it's repository, unrelated between them, with each branches and tags. I want to receive "framework"'s updates in my repository, but only from "default" branch and not from others. And, of course, I do not want to have "framework"'s tags in my repository, as it is a totally different project.
I have Mercurial HG, and I would like to be able to pull changes from "framework" repository directly from my "Manage repository" page.
Furthermore, I only want to download latest changesets, since I started my project not long ago. And It would be perfect if I could rename the "framework"'s default branch to other name in my repo, e.g. "Framework Changesets".
Note: I do not have write access to the "framework" repository.
I tried to do what mercurial wiki said:
hg pull -f -r default "framework"
It was OK, until I realised I had downloaded all the tags from the "framework" repository, and I had downloaded all the changesets from the remote repository. Furthermore, when in TortoiseHG->Configuration->Synchronization I put the "framework" repository as a remote repository for that project, and pulled from the remote repository, I got all the branches from that repository.
Of course I wasn't able to change default branch name, and updated my default branch, even though I tried to use hg convert --branchmap (but I didn't know how to use it).
Is there any solution to my problem? or even a partial solution?
I think you can address this issue through a combination of these things:
Pulling specific branches
Using the command line: hg pull -r <branch name>
Using TortoiseHg v1.1.X:
Check for incoming changesets by using the button labeled Download and view incoming changesets
Right-click on the tip of the branch you want to pull and select Pull to here
Reject the rest of the changesets using the Reject button
Removing existing tags
You can always hand-edit the .hgtags file to remove tags created on the "framework" branch, but I don't know of a way to pull changesets without the tags.
Changing branch name
Using the mq extension you can change the named branch that your new "framework" changesets live on. See answer to "Apply patches in branch" for instructions on how to do this in TortoiseHg v1.1.X, as well as the CLI. The basic idea here is to create a named branch with the name you want, import all of the "framework" changesets you pulled into a patch queue, and then apply them to the new named branch. They will shed the branch name from "framework" and use the branch name of the branch you applied them to.
If you are going to pull from "framework" more than once, you would need to use the patch queue to move only the new changesets with each pull. It should be easy to see which changesets you haven't moved yet.
We can specify the branch name by appending branch name with a # symbol in the clone url.
e.g.
hg clone --verbose https://user#cloneurl/my_product#MY_BRANCH "C:\myCode"

How Do I Migrate From One Mercurial Server To Another Without Losing My History?

I have a project where I'm using Bitbucket as my HG server, but I've recently discovered that as a lone developer I can use Fogbugz/Kiln for free. I want to move my files into Kiln but I don't want to lose my history. I'm sure there's a dead-stupid easy way to do it, but I just don't know. How do I do this?
Thanks!
Create the new project repo and do the following with your current copy of the original repo: hg push new-repo-path.
Then you use the new path in the future. You can delete the bitbucket repo.
With Mercurial, all history is in every copy of the repository, including your local copies.
Since you are already using Mercurial. I was just curious, shouldn't cloning your repository on Fogbugz/Kiln be sufficient.
hg clone "BitBucket Repo ..."
Of course, this won't copy your per-repository hgrc file. You will need to do that separately.
Another approach is to use bundle.
hg bundle --all bitbucket.bundle
hg clone bitbucket.bundle my_repo
Third approach is to push or pull from bitbucket repo to fogbugz repo.
Setting defaults
See: https://www.mercurial-scm.org/wiki/TipsAndTricks.
Reproducing it here:
It is possible to store a default push URL that will be used when you type just 'hg push'. Edit hgrc and add something like:
[paths]
default-push = ssh://hg#example.com/path
The other answers have already explained that right after creating a new empty repository, you can push your changes into it with hg push http://example.com/hg/newrepo. (Note that once you have pushed some changes into it, it will only accept changes from related repositories in the future.)
What you also seem to be wondering about also is how to then configure your local repository to push to that location by default, without needing to specify the URL every time. You can do that by editing the default location in the .hg\hgrc file of your repository. It is a text file that you can open with notepad or any other text editor.

How do I move a private Mercurial repository to a central server?

I’m just getting started with Mercurial, and I’ve read Joel Spolsky’s Hg Init tutorial, which I liked.
I’m wondering: let’s say I have a private repository and I work on it for about a month. Then I decide I want to centralize it or make it public, like on bitbucket.org. I want to retain all the history.
The intuitive thing would be to use hg clone, but according to the docs:
The location of the source is added to
the new repository's .hg/hgrc file, as
the default to be used for future
pulls.
I don’t think this is what I’d want, since the source is my local, private repository, and the destination is the public server. I don’t want the public server trying to pull from my private repository in the future thinking it’s the central one. I hope this makes sense.
Do I have to tweak the .hg/hgrc file on the server manually? Am I approaching this correctly?
BitBucket's help says it's as easy as making an empty repo on BitBucket, then pushing to it:
... create a new empty repository via the "Create repository" page. We will assume that this repository is named blonk and is to be found on http://bitbucket.org/jespern/blonk.
Now, just push to it:
$ cd ~/Work/blonk # our existing hg repository
$ hg push http://bitbucket.org/jespern/blonk
...
Done!
You can edit .hg/hgrc in your repository to include the default path to Bitbucket:
$ cat .hg/hgrc
[paths]
default = http://bitbucket.org/jespern/blonk
Now you can simply enter hg push and hg pull without having to specify the full URL.
Doing this operation using 'hg push', as described, is probably the best way to do this, overall.
However in other circumstances it might be convenient, or reassuring, to note that all of the Hg state is contained within the .hg directory, and so simply moving this directory is enough to move the repository.
For example, if you have ssh access to a machine at example.com, you can tar (or zip) up your .hg directory in the 'private' repository, unpack it in, say, ~/repo/foo on the remote machine (thus creating a directory ~/repo/foo/.hg there), and then simply clone this:
$ hg clone ssh://example.com/repo/foo
This does have a slight back-door feel to it, I agree. However, there's nothing really under-the-hood happening here, and no editing of configuration files is necessary. When I do this, I find it less confusing than the 'proper' way.