mercurial push subset of directories to secondary remote site - mercurial

I'm considering using Mercurial in our small office. We've got a development server, a staging server and a live server. The live server contains our web site, the staging server contains our web site and additionally some intranet directories that should not be pushed to the live server.
In setting up Mercurial - is there any way to be able to push the entire repository to the staging server: our public site as well as the intranet directories, but, when pushing to the live server only send those directories associated with the public site?
In other words - when pushing to staging, push everything. When pushing to live, exclude the directories for the intranet site?
-Charlie

The push and pull operations act on the entire repository only. Some other options available are:
use hg archive -X to build an archive file with a subset of the repo (tip only, no history)
or
split your repo into multiple repos (ex: internal and external) that are subrepos of a larger repo. Have the outer repo on the dev and staging machine, and push only the external repo to production.

Related

Using one Mercurial repository as local for two Mercurial installations

We have a dedicated issue tracking (Redmine) machine, which has a Mercurial repository (call it "Redmine repository"). Redmine is set up to use that repository, and as far as I understand, Redmine never makes any changes to that repository. All developers (eventually) push their changes to that repository.
We also have a dedicated production machine, which can execute the code, but is not used to make any changes to the code.
We have two choices:
Set up another Mercurial repository on the production machine (call it "production repository"). When a new production release is approved, pull the changes from the Redmine repository to the production repository, and then update the local working directory to the appropriate revision from the production repository.
Reuse the existing Redmine repository on the production machine designating it a local repository for the Mercurial installation there (the Redmine repository is on the shared drive that can be easily mounted on the production machine). Whenever a new production is approved, update the local working directory to the appropriate revision from the Redmine repository.
With option #2, we get rid of an extra "pull" step (from Redmine repository to production repository), which slightly simplifies the process. But I'm not sure if it's ok that a single repository is used by two Mercurial installations as if it's local.
Any comments on this choice (or any other aspect of this setup) is appreciated!
It sounds like a bad idea. Mercurial does a really good job of keeping reads and writes to its repository atomic, but it has a harder time doing that when the repository is on a shared drive -- even if it's only one local repository using it -- because network shares (especially on Windows) don't always make things atomic that they say they do.
Ideally your repositories (both the working dir and the repository) are local when possible, and you use push/pull to get changesets to/from a network share. If that's not possible then having a single local application using the repo on the remote file system is the best idea.
If you positively want to try having two clones using the same underlying repository check out the ShareExtension, which ships with Mercurial but is for advanced users only.
Instead of trying to piggy-back, why not just put a hook like this in your redmine repository:
[hooks]
changegroup = hg push //production/clone
That will automatically push changesets that arrive in redmine to production.

Publish with Mercurial to Public Environments

Basically I am new to using mercurial in a small team environment. I am looking for a way (3rd party if necessary to publish my change-sets/revisions to a public staging and public live server(s).
Currently I have set up on our local ubuntu server, using wildcard DNS, a directory with folders, each folder contains a project. Inside of the folder I create another folder called "repo", this stores the local clean version of my website. Then I clone from that local folder into a custom one, do my work, and push it back into the before mentioned "repo" folder.
Next that "repo" folder connects to a 3rd party site bitbucket. That's so I can work off site.
What I want to figure it out is if there are open source or something to allow me in a web interface, see my revision and select to publish it to one of the 2 server locations. I know beanstalk can do it, but I really like bitbucket and it's cost effective. I have about 15-25 different repositories.
Is my process too much? How can I make this process the most efficient as possible.
Are you using hgweb? It's not clear from your description that you are, and you certainly should be.
That aside, cloning from a central-ish repo to a local working clone, modifying, committing, and pushing bash to the central-ish repo sounds pretty normal.
Why use a web interface to push from your central-ish private repo to your public site? Why not just go from your working clone to the public site?
For example on my local machine (not a web server at all) in the repository for my blog I have this in the .hg/hgrc file:
[paths]
default = ssh://ry4an.org/projects/unblog
publish = https://ry4an.org/hg/unblog
If I do hg pull I get changes from the private repo on my ry4an.org server in my home directory. Then I edit, commit, and hg push which again goes to my private repo on my remote server. When I want to actually publish the blog entry I do hg push publish which pushes the changesets from my local working repository to the public one (at http://ry4an.org/hg/unblog which is the live content for http://ry4an.org/unblog)
In theory I could use a web interface of some sort to move changesets from ssh://ry4an.org/projects/unblog to https://ry4an.org/hg/unblog, but sending them from my local working clone gives me better tools (hg incoming, hg outgoing, hg log, etc.)
Am I fundamentally misunderstanding your goals or was that helpful?

How to configure mercurial to deploy website folder only

I have a website that I want to deploy to a clients DEV and UAT environments, the site is part of a mercurial repo - it is in the Website folder at the same level as the .hg folder. I know I can push the entire repository but would rather push only the website folder so the client does not have the other files and folders.
The repo looks like this:
Project root
.hg
Database (SQL Source Control uses this)
Documentation (All specs, pdfs, art work etc.)
Lib (pre-Nuget 3rd party dlls)
packages (Nuget stuff)
Website (this is the only area I want to deploy)
.hgignore
Project.sln
Edit:
The clients servers are not connected directly to the internet, my access to them is over a vpn and then RDP. Currently to deploy any changes I need to zip the site up, put it on a shared ftp server then wait up to 3 days for the files to be copied to the servers. Rules have been configured so I can use Mercurial over this connection.
Edit 2
I have managed to create a subrepo from the Website folder by forgetting the Website folder and all it's contents, committing the change then putting the files back, creating a repo then echoing out the .hgsub file. Locally this works for me, I can clone from the Website repo without getting any of the additional folders. However I have not been able to use this version of the repo, even if I repeat the process on our repo server. When I try to clone the hosted version down to my local working copy I get 404 errors, but I can clone the hosted version on the hosting server.
I would appreciate some step-by-step instructions (a guide for dummies if you like) on how to achive my goal; which is to be able to push only the Website folder to the clients servers. The master copy of the repo is on our repo server, I have a local clone and need to be able to push out versions from my copy.
Edit 3
Turns out that the problem I was having converting a folder to a subrepo as described in http://mercurial.aragost.com/kick-start/en/subrepositories/#converting-folder-into-a-subrepository was that the convert command, in versions after 2.1.0, is broken and is still broken in 2.3.1. After I figured that out and rolled back to that version of TortoiseHg I was able to convert the folder to a subrepo, in the root of the repo I have .hgsub which says Website = Website. I was able to work with that locally, commit to the whole repo, the subrepo, clone either the full repo or the subrepo (which is what I want), however I can't get this to work from our master repo server.
I zipped the whole thing up and ftp'd it to our remote master repo server, then set it up so I could clone from it. Directly on the server this works fine (hg clone --verbose -- C:\Repositories\EM .), however when I try to clone from the server to my local development machine with (hg clone --verbose -- https://myserver.com/hg/EM/ .) it fails with "HTTP Error: 404 (Not Found)".
requesting all changes
adding changesets
adding manifests
adding file changes
added 628 changesets with 6002 changes to 4326 files
updating to branch default
resolving manifests
calling hook preupdate.eol: <function preupdate at 0x00000000035204A8>
getting .hgignore
getting .hgsub
getting .hgsubstate
HTTP Error: 404 (Not Found)
[command returned code 255 Fri Apr 20 10:51:23 2012]
I don't know what the problem is, the files are there so why the 404?
In my opinion Mercurial shouldn't be used for this purpose. This is particularly true if that website is a web application because you shouldn't have the DLLs in Mercurial.
You should look at the web deployment tool built into Visual Studio. Have a look at this page to see if it suits your purpose.
If you can't install the required services on the destination server then it can be configured to use FTP instead.
You can not push part of repo tree
If DEV and UAT environments are unversioned targets, you can use any other way for distributing Mercurial content
You can separate Website into subrepo and will be able to push this repo
As others have pointed out you can't use push for this. Just do 'rsync' from your server to theirs. You could even automated that in a hook, where you push to a local repository and it auto-deploys to their site. Something like:
[hooks]
changegroup.deploy = $HG update ; rsync Website account#theirserver:/path/to/docroot
I have a working solution to this. I created a batch file that creates an outgoing repo and starts the built in server so I can pull from it on the client machines. First it clears out the previous folder, then clones from my local working copy (there's a parameter to determine which tag it should clone from). Next it creates a map file and converts the Website folder to a new Website2 folder in order to preserve the history then gets rid of the original folder and renames the new one. Finally it spins up the built in server.
cd c:\inetpub\wwwroot
rd /S /Q _ProjectName
hg clone -- C:\inetpub\wwwroot\ProjectName#%1 C:\inetpub\wwwroot\_ProjectName
cd c:\inetpub\wwwroot\_ProjectName
echo include Website > map.txt
echo rename Website . >> map.txt
hg --config extensions.hgext.convert= convert --filemap map.txt . Website2
cd Website2
hg update
cd ..
hg remove Website/*
hg commit -m "Removed Website"
rename Website2 Website
hg serve
So it isn't pretty, but now I just need to call the batch file and pass the tag I want to build the outgoing website from (uat, dev etc.) and give it a minute to create my Website folder, with history, that I can use to pull from or push from. I don't need to call hg serve because I know the names of the client servers so I can push the changeset out by creating aliased remote repositories. But I included that step so the client machines can pull. I haven't fully explored this option, so I'm not sure whether it's got any particular advantage. It's fine for the case when it's just me working on the project, but if any other developer needs to work on this then the Uri for their local project server will obviously be different (http://SIMON-PC:8000/ won't be the case for everyone), in which case pushing into the client might be best.
But by using this approach my local working repo doesn't need to change and so I don't get any issues communicating with our central repo, the 404 errors mentioned in edit3. I keep the entire history of the repo with the convert process, so the next time I need to send changes I'm not starting at revision 1 - in other words it isn't destructive of the Website and although I am deleting the entire outgoing repo (_ProjectName) each time I am retaining the history and yet in a position to pull / push ONLY the Website directory because it is created each time as a 'standalone' repo

I have a slight confusion with setting up Mercurial on my webserver

I'm starting to use Mercurial on my web server (in this case MediaTemple's Grid). I've used SVN previously, though I'm not an expert of version control systems. I'm just needing a little help with clearing up some confusion with getting it set up optimally.
I have a 'data' folder which is outside the web server root and that the browser cannot access. It was recommended to me before to have my Mercurial repositories setup here, then I would clone from here locally on my computer. I would also have a 'domains' folder that is basically the web server root and inside there is my actual domains where my websites are actually served to the browser - these would need to be updated from the 'data' repositories too.
But with this in mind, after setting it up, it seems inefficient... I'm cloning to my local (that makes sense), adding, committing, pushing. That's fine... But then I'm then updating in my data repository folder and then updating in my domains folder to actually update my websites.
Surely, I don't actually need this 'data' folder for repositories? Wouldn't my actual live 'domains' folders be the main repositories themselves? So I'm cloning locally and updating from these? Please help me clear some confusions with all this (if you can).
It's strictly a matter of personal preference. Some folks make their live websites also the "master" repo, and some make it a clone of an elsewhere located repo. What you're doing right is serving your sites from directory in the repo, that's a good choice.
Some considerations as to whether you might want separate 'data' clones independent from the web root clones are:
do you want to have multiple heads in the same branch which might confuse the person updating the main repo?
do you want a repo to which people you don't trust with editing the live website can push so that a trusted admin (you?) does the push/pull from data to webroot?
One thing to note is that in the 'data' repo you can do hg update -r null which gets rid of the working copy (but keeps the repo!), so that the diskspace used is almost zero (assuming it's a clone of the webroot they'll share the same underlying files at the FS hardlink level).
I do have a repos (data) folder outside the website root, containing various repositories, and served through hgwebdir on a separate domain (hg.mywebsite.com).
However, my website’s repository I do store in the httpdocs directory of the main domain. I test on my local environment and then pushing my changes to the server will also publish them.
To achieve this I have this in my hgweb.config:
private/mywebsite = ../../../httpdocs
And this in that repository’s hgrc:
[hooks]
changegroup.update = hg update
This hook will update the working directory to the tip whenever changes are pushed. Of course I have also added a rule to the Apache configuration to ignore the .hg directory, and on the subdomain hg runs on, a rule to require authorisation for accesses to the private/ paths.
An alternative would be to instead host the repository together with the others, and then ‘hg archive’ into the httpdocs directory. A little more secure, a little slower, and as for convenience I would say it’s 50-50.
p.s. also adding a hook to forbid creation of remote branches may be a good idea, if people who might do push -f can access your repositories.

How to move a Mercurial repository created on a local PC to a web server?

I have created and committed to Mercurial repository that was created on my local drive. I now have a remote Windows 2003 web server setup to serve repositories via hgwebdir.cgi.
How do I move the locally created repository to the web server?
It looks like an ftp of the .hg folder on the local drive to the remote web server does the trick. Am I doing it the right way. Is there a more efficient way?
Copying the .hg directory is a completely valid way to do it.
NOTE: You will probably want to exclude, remove or edit the .hg/hgrc file if you have one, as it may contain an absolute path to the original location of the repository.
You could also initialise an empty repository on the remote server, ensure that write permissions are set up correctly, and then run hg push https://wherever. I haven't measured, but I imagine that this method would be slower.