Multi-user access for Mercurial sub-repositories - mercurial

What is the right way to organize ssh access to sub-repositories in mercurial?
Consider the following situation:
master
|--.hgsub
|--slave1
|--slave2
And .hgsub:
slave1 = ssh://user#host://var/local/repos/slave1
slave1 = ssh://user#host://var/local/repos/slave2
The problem is that .hgsub is the part of the repository thus it is not possible (or is it?) to store various usernames in the ssh addresses of the repos. And I really want to avoid using a "global" user to access the repositories just because of this.

You have basically two choices:
If your subrepositories live in the same server as the container, use relative paths. This is the most convenient solution.
Otherwise, you can have each user define a subpath rule. Look for the subpath word in this document.

Related

With Mercurial: How to record different machines source code changes happened on

I use Mercurial on 2 different computers changing the same repository. If I want to keep tabs on which changes have happened on which machine, how should I record this?
I came up with the idea of using different user names on the two machines ([ui] -->
username variable in the hg config file), but does a more appropriate mechanism/variable exists for this?
This looks like a good idea; user names are exactly to identify the committer, here the computer. The alternative would be to work on different branches on each computer and merge in default often. However, the latter is more error-prone.
For a couple of years, you've been able to expand shell variables inside .hg/hgrc files.
So I just do something like this in my .bash_profile:
export HGUSER=$(hostname)
Then inside .hg/hgrc:
username=${HGUSER}
The BIG ADVANTAGE of this technique is that now you can put the EXACT SAME .hg/hgrc on ALL the machines. The same is true of .bash_profile: it can be the same on all machines. This helps a lot when you're automating machine configurations!
Note: the HGUSER environment variable is an old way of telling Mercurial your username, so, technically, setting HGUSER in .bash_profile ought to solve the problem on its own, but I believe its use is deprecated/discouraged, and I recommend defining username in .hg/hgrc explicitly, as I've shown above.

A practical way to provide code updates via Mercurial without sharing main BitBucket account

I suspect this might be really obvious but I can't find a straightforward solution in the documentation or forums:
I have written some code that is held in a Mercurial repository on BitBucket.
I use this code to build Linux virtual servers. When I build a server, I clone the repo onto the server, run my build script, and then delete the clone. The result is a configured server with several files from my repo located in various folders on the server.
Now, I'm looking for a mechanism where I can roll out bug fixes and improvements to my users' servers after I have handed them over. At that time, I won't have SSH access to the servers and I cannot expect my end users to do anything more complicated than kick off a cron job or launch a script.
To achieve this, I'm thinking of setting up a BitBucket account for my users with read-only access to my repo.
I have no problem writing a script to clone my repo, via this read-only account, and apply the updates, but I don't want to include all my files. In particular, I want to exclude my build script as it is commercially sensitive. I know I could remove it from my repo, but then my build wouldn't work.
Reading around, it seems I may need to create a branch or a fork of my repo (which?). Or maybe a sub-repo? Then, I could remove the sensitive files from that branch/fork/sub-repo and allow my users to clone it via a script.
That's OK, but I need a way to update the branched/forked/sub repo as I make changes to the main one. Can this be automatic? In other words, can it be set up to always reflect the updates made in the main repo? Excluding the sensitive files of course.
I'm not sure I'd want updates to be automatic though, so I'd also like to know how to transfer updates from the main to the branch/fork/sub manually. A merge? If I do a merge, how do I make sure my sensitive files don't get copied across?
To sum up, I have a main repo which contains some sensitive files and I need a way to roll out updates of all but those sensitive files to my read-only users.
Sorry if this is hugely obvious. I'm sure it's a case of not seeing the wood for the trees and being overwhelmed by the possibilities. Thanks.
I don't think that you need to solve this in Mercurial at all.
What you actually need is Continuous Integration / a build server.
The simplest solution goes like this:
Set up a build server with something like TeamCity or Jenkins, that's always online and monitors changes in your Bitbucket repository.
You can set it up so that when there's a change in your repository, the build server runs your build script and copies the output to some FTP server, or download site, or whatever.
Now you have a single location that always contains the most recent code changes, but without the sensitive files like the build script.
Then, you can set up a script or cron job that your end users can run to get the newest version of the code from that central location.
You are ok with two branches, one for the users clone (main) and other for your main development (dev), the tricky part is merging the new changes from dev to main.
You can solve this by excluding files in the merge process. Excluding a file while merging in Mercurial
By setting the [merge-patterns] section in your .hgrc you can sepcify what files are not affected by the merge.
[merge-patterns]
build.sh = internal:local
For more info read hg help merge-tools.
"internal:local"
Uses the local version of files as the merged version.
Entire Mercurial trees always get moved around together, so you can't clone or pull just part of a repository (along the file tree axis). You could keep a branch that has only part of the files, and then keep another branch that has everything, making it easy to merge the the partial (in terms of files) branch into the other branch (but merging the other way wouldn't be particularly easy).
I'm thinking maybe subrepositories work for your particular use case.

How to clean confidential data in mercurial changesets?

I want to sell a copy of my system and need to transfer the source code to my customers. I use Mercurial as the VCS. There are some confidential data in my code. For example, Amazon access key/secert key, database passwords and ssl private keys. Those keys are written in the code or configuration files, like this:
# settings of Amazon S3 storage
s3.storages:
access_key: <secret>
secret_key: <secret>
Before I transfer my code to them, I need to clean all those confidential data in the code base. But all of them are in history (changesets). With Mercurial, how can I clean those secret?
If you're giving the customers only a snapshot you can do it after you run hg archive.
If you want to give them access to the repository with full history you need to use hg convert to exclude that file.
In that case you're probably better off just invalidating the AWS key and using a new one in the future -- Amazon makes that very easy.
Going forward you're better off not putting those keys into source control. Instead put in a config.sample file and then add config.actual top your .hgignore.

tortoise hg clone two separate mercurial projects to the same directory

I wanted to combine two projects from separate remote mercurial repositories into the same local directory (one is a framework, the other my code).
My thoughts about doing this were to simply clone them both to the same working directory but this generates the error abort: destination 'C:\Workspace\project' is not empty using tortoise hg.
Is this the right way to approach this and if so does anyone know how to get this to work?
First of all, are you sure you want to do this? There's no way to safely push back to the original sources without getting everything, from both "projects" after you have combined.
In other words, they effectively become one project, and it won't be easy to split it back up.
You should consider using sub-repositories which is the typical way that Mercurial deals with these sorts of things.
Having said that, to combine two distinct repositories, you need to pull one into the other.
In other words, here's what you would do:
Clone one of the projects
Pull into your new clone, and specify the URL to the second project. You will need to force the pull, otherwise it will complain about not being the same repository.
Optionally: Move one or both of the projects into their own sub-directories, to separate them in the directory structure
Merge the two heads to combine them into one big set of files
If any of this was unclear, please leave a comment with your questions and I'll update/edit accordingly.

How can I commit a set of files only once in Mercurial?

I have some files I'd like to add to have them as a "backup". The thing is, I'd like to commit them only one time, and then, I'd like for Mercurial to don't track them anymore ( don't notify me if they're changed, and don't commit them on other commits ).
Basically, something like this:
hg add my_folder
hg commit -m "added first version of my_folder"
Then, after a while, the contents of that folder might change. And if I commit other files, the new version of that folder will get commited as well. This is something I'd like to avoid. Is it possible, without specifying directly which files I want to commit?
I've never seen any option in Mercurial that might allow that... but why not simply copy them elsewhere ?
I mean, what's the point of using a Version Tracking System if you don't need versioning on these items anyway ?
We ran into a similar case with binary documents ('.doc', images, etc...) and finally decided to commit them on a separate repository, dedicated to those.
I think the traditional way of doing this is to commit files named something like "file.ext.default", and just inform users that they should copy the defaults and modify the copies.
VCSs aren't backup sysytems. consider using a proper backup mechanism.
having said that you should be able to do this using hooks, there are many ways you could do this but ACLs would be an obvious one assuming a remote server