Get latest revision of the remote repository with javahg - mercurial

In our current Java project we want to compare the local with the remote revision number of an alreay cloned mercurial repository, especially we want to get the latest revision number from the server. We are using javahg to access mercurial functions. But we can't find any command in the javahg library to achieve that.
Normally, you would use the identity command, but this is not supported in this library. Another way could be to use the incoming command, which is supported, but it seems not to work for us. We tried to execute the following code line:
IncomingCommand.on(localRepo).execute(serverURL)
and the resulting bundle returns "-1". After a quick look into the source code of the execution function we found out that this method operates only on local repositories.
Has anybody an idea how the incoming command could be used to get the latest revision from the remote repository? Or is there another way to do this?
Any help is appreciated. Thanks!

The incoming command downloads a 'bundle file' containing the remote changesets not present locally. From the Bundle instance you can use getOverlayRepository() to get a Repository instance that any other command can be invoked on.
Here's an example of using Incoming with a remote repository:
Repository repoB = ..;
Bundle bundle = IncomingCommand.on(repoB).execute("http://localhost:" + port);
List<Changeset> changesets = bundle.getChangesets();
List<Changeset> heads = bundle.getOverlayRepository().heads();
I'm not sure the precise semantics of 'identify' but maybe a similar effect could be achieved by listing heads of the bundle overlay repository.
Identify seems much more efficient if you're just interested in the node id and not the changes themselves. Feel free to post a feature request here: https://bitbucket.org/aragost/javahg

Related

Managing composer and deployment

So, I'm enjoying using composer, but I'm struggling to understand how others use it in relation to a deployment service. Currently I'm using deployhq, and yes, I can set it to deploy and run composer when there is an update to the repo, but this doesn't make sense to me now.
My main composer repo, containing just the json file of all of the packages I want to include in my build, only gets updated when I add a new package to the list.
When I update my theme, or custom extension (which is referenced in the json file), there is no "hook" to update my deployment service. So I have to log in to my server and manually run composer (which takes the site down until it's finished).
So how do others manage this? Should I only run composer locally and include the vendor folder in my repo?
Any answers would be greatly appreciated.
James
There will always be arguments as to the best way to do things such as this and there are different answers and different options - the trick is to find the one that works best for you.
Firstly
I would first take a step back and look at how you are managing your composer.json
I would recommend that all of your packages in composer.json be locked down to the exact version number of the item in Packagist. If you are using github repo's for any of the packages (or they are set to dev-master) then I would ensure that these packages are locked to a specific commit hash! It sounds like you are basically there with this as you say nothing updates out of the packages when you run it.
Why?
This is to ensure that when you run composer update on the server, these packages are taken from the cache if they exist and to ensure that you dont accidentally deploy untested code if one of the modules happens to get updated between you testing and your deployment.
Actual deployments
Possible Method 1
My opinion is slightly controversial in that when it comes to Composer for many of my projects that don't go through a CI system, I will commit the entire vendor directory to version control. This is quite simply to ensure that I have a completely deployable branch at any stage, it also makes deployments incredibly quick and easy (git pull).
There will already be people saying that this is unnecessary and that locking down the version numbers will be enough to ensure any remote system failures will be handled, it clogs up the VCS tree etc etc - I won't go into these now, there are arguments for and against (a lot of it opinion based), but as you mentioned it in your question I thought I would let you know that it has served me well on a lot of projects in the past and it is a viable option.
Possible Method 2
By using symlinks on your server to your document root you can ensure that the build completes before you switch over the symlink to the new directory once you have confirmed the build completed.
This is the least resistance path towards a safe deployment for a basic code set using composer update on the server. I actually use this method in conjunction with most of my deployments (including the ones above and below).
Possible Method 3
Composer can use "artifacts" rather than a remote server, this will mean that you will basically be creating a "repository folder" of your vendor files, this is an alternative to adding the entire vendor folder into your VCS - but it also protects you against Github / Packagist outages / files being removed and various other potential issues. The files are retrieved from the artifacts folder and installed directly from the zip file rather than being retrieved from a server - this folder can be stored remotely - think of it as a poor mans private packagist (another option btw).
IMO - The best method overall
Set up a CI system (like Jenkins), create some tests for your application and have them respond to push webhooks on your VCS so it builds each time something is pushed. In this build you will set up the system to:
run tests on your application (If they exist)
run composer update
generate an artifact of these files (if the above items succeed)
Jenkins can also do an actual deployment for you if you wish (and the build process doesn't fail), it can:
push the artifact to the server via SSH
deploy the artifact using a script
But if you already have a deployment system in place, having a tested artifact to be deployed will probably be one of its deployment scenarios.
Hope this helps :)

Prevent access to some files in webserver - mercurial/ssh

I have a centos server with code maintained using a mercurial repo.
To allow a new person to commit code to mercurial, I create a new user, add them to the webdev group, and they can push / pull code by
hg pull ssh://name#server.com.
However, there are some files (config files) that I would not like new users to have access to. Mercurial has been asked not to track these files, so the only way to access them is to ssh into the system and look at the files. Which I dont want new users to be able to do.
In essence, I want my new developers to only pull/push files through hg and disallow ssh-ing directly into the system. What the best way to do this? Can I provide hg access to a repo without providing ssh access to the files?
(or is my approach to the problem flawed?)
Thanks!
This can be really easily done by taking advantage of the command option available in .ssh\authorized_keys files. When you're granting their key access in that file you can prepend a "command=...." argument to their key and that's the only command they can run.
Mercurial ships with a handy script for doing exactly that. It has instructions inside:
https://www.mercurial-scm.org/repo/hg/file/tip/contrib/hg-ssh
In term of an authorization layer (similar to Gitolite for Git), you have mercurial-server (not to be mixed up with the Mercurial light-weight web server hgserve)
mercurial-server gives your developers remote read/write access to centralized Mercurial repositories using SSH public key authentication; it provides convenient and fine-grained key management and access control.
See its repository here.
It is based on the same SSH forced-command mechanism than the script mentioned by Ry4an in his answer (+1 on his answer, because it is already packaged with Mercurial).
See for illustration the "mercurial-server" source of refreshauth.py.

scp a mercurial repository

I have a shared web host and I am trying to figure out a way to download the latest copy of a private project from bitbucket onto the server.
The server does not have any versioning tools installed, but it does have scp and ssh with a jailshell level of access. It also has wget and curl...
Can I can do something like this?
scp ssh://hg#bitbucket.org/jespern/testrepo ~/public_html
I don't have a problem setting up the identity files / DSA keys, but I'm not exactly sure how the protocols are put together here so I need some help with the basic syntax.
Or, if scp is not the way to go, does ssh have an option for doing this? or is it possible to use CURL or wGet to grab the latest version of the repository and then reconstruct it on the server?
I am sure there is a way to do this, so please don't respond saying "it can't be done."
Thanks!
You can download from bitbucket using either http with URL like this:
http://bitbucket.org/jespern/rewsfeed/get/tip.tar.bz2
Notice how tip can be used in place of a revision ID in that URL form to always get the latest snapshot.
Alternately, you can just install Mercurial in your home directory on the shared web host -- people have succeeded in doing that on almost every webhost out there no matter how locked down they are.
Then you can just do: /home/me/bin hg clone ssh://hg#bitbucket.org/jespern/testrepo ~/public_html

I am trying to use mercurial and the perfarce extension to check out and getting an error

I am trying to use the "Perfarce" extension to Mercurial to create an hg repository (working copy) that is managed by mercurial, with a link to check out and in to a central perforce server "depot".
The help says to enter a command like this:
hg clone p4://hostname:portnumber/userid
When I do this, it creates a folder under my current working directory named with the userid name (so it seems sub-optimal way to pass the user name to the p4 url), and I get this error:
abort: p4: ... - must create client 'userid' to access local files.
The second try fails with destination is not empty error.
I have also tried specifying a destination:
hg clone p4://hostname:portnumber/userid dest
This doesn't work either -- same error message about creating a client. I don't see a way to tell it about my WORKSPACE, if any, or which depot, on the particular hostname to check out.
I already having a WORKSPACE that p4 and p4v know about, and it's in a different folder than the place where I would like to have my hg+perfarce working copy. I suspect the p4 command line program might be confused by this.
Has anyone gotten the "perfarce" extension working with mercurial? What did you do exactly, and what am I doing wrong, and not understanding?
You must have a Perforce client created when using Perfarce. You then use the specified convention to access the perforce depot. As per Perfarce documentation
hg clone [--startrev REV] [-r REV] [p4://server/clientname] [dest]
Also, make sure you have the destination folder created on your machine. It must be the same as set in the client. If your client spec specifies d:\foo you must run the Perfarce command in d:\ and have an empty foo directory. Not using the optional dest Perfarce creates a directory using the client name.
If your Perforce client is using the default settings and using the read-only flag, you might want to use the MakeWriteable extension.
It looks like you have to type "p4 client", and then edit the resulting file which sets up access to various depots within the p4 server. Then the hg commands will work in this working folder.
Except that it dies with an abort, from p4 client run within the hg clone operation, with a missing file error, each time a different missing file.
I'm new to Perfarce, too, but I've found that I need to use p4 login, even though this is not otherwise required by my P4 server. Perfarce doesn't seem to recognize P4 settings files set up via P4CONFIG.

How to configure hosted Mercurial in TeamCity 5

This is probably a simple problem and I'm feeling exceptionally dumb because I can't find a any kind of documentation.
I've just installed TeamCity 5 and I want to get files from my Mercurial hosting and there is two fields I just can't figure out.
HG Command path. What should I put here? The path to a file containing what? Can I get an example of that file somewhere?
The host is using Mercurial over SSH where do I define my private key?
Pull changes from? Should I put the address I'm cloning from i.e. ssh://username#myhost.something/project
I figured this out for my TeamCity 5 server last week.
HG Command path: HG
Pull changes from: https://bitbucket.org/.../.../
Don't put the username# in the URL. This is specificed as in the Username/Password fields. If you include the username in the URL it'll fail as there is a bug in the configuration tool. You'll also see a screenshot of the configuration attached to the thread:
http://www.jetbrains.net/devnet/message/5254640#5254640
I'd suggest getting things working with HTTPS and then moving to SSH if possible. This breaks things down into two easier to solve configuration problems. I used the following tutorial to get SSH going on my Windows client machine.
http://www.codza.com/mercurial-with-ssh-setup-on-windows
I've not set this up on my TeamCity server yet. However I did get TeamCity to pick up my Mercurial.ini settings by putting the ini file in \Documents and Settings\TeamCity, which is the account the service runs under.
I've not used team city, but I think hg command path is probably the full path to your local mercurial executable. For me (on linux) that's:
$ type hg
hg is /usr/bin/hg
On windows it's where the 'hg' executable in your system path was placed by whichever (of the many) windows installers for mercurial you used.
Pull changes from sounds like the URL to the repo, so:
ssh://username#myhost.something/project
or
ssh://username#myhost.something//project # note the _two_ double slashes
if you're using absolute paths on the server side.
Your private key location/specification depends on what you're using for ssh and whether or not you're running ssh-agent, but here's a links that explicitly points from within mercurial.ini, which seems sound:
http://dev.openttdcoop.org/projects/home/wiki/Configuring_TortoiseHg_(Windows)#Pointing-to-you-Private-key