1

The context of this question is the hg-ssh script. It is helpful but not critical to know something about Mercurial. This script sets up a forced command using public keys so the given public key setup on the server will only allow the owner of the corresponding private key to push to a permitted set of repositories on the server. This forced commands is usually prefixed to the public key in the file ~/.ssh/authorized_keys on the server. With regard to this permitted set, the documentation before the script in the link above says:

You can use pattern matching of your normal shell, e.g.:
command="cd repos && hg-ssh user/thomas/* projects/{mercurial,foo}"

The idea is to permit only pushing to repositories on the server that match this pattern. I've been using hg-ssh with the forced command

command="cd /srv/hg && /usr/local/bin/hg-ssh * */* */*/* */*/*/*",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa [...]

to match all repositories (up to some number of path components) under /srv/hg, using shell globbing. I belatedly realized that it is not matching paths which contain components starting with .. My current non-working example is the MQ repository /srv/hg/faheem/bixfile/.hg/patches. So, my question is, can I select a pattern that corresponds to all paths? I would prefer to use shell globbing, which are less of a headache than regular expressions in general, but I'd take a regular expression if globbing is not an option.

1

1 Answer 1

2

For recursive matching, the right tool is often find. Since you want to match all files in the current directory and its subdirectories recursively, but only down to a certain depth, specify -maxdepth. This isn't in POSIX, but exists on all current *BSD and in GNU find (Linux, Cygwin) and in Busybox (embedded Linux) so it's a safe bet that you have it. -exec … {} + is a relatively recent addition to POSIX, but it's been in GNU and FreeBSD/NetBSD/OSX for a while now.

cd /srv/hg && find . -type d -maxdepth 3 -exec /usr/local/bin/hg-ssh {} +

(I added -type d because you seem to want to match directories only, even though your attempt with * */* etc. matches files of all types.)

8
  • Ok, thanks. How would this look exactly, in the context of the script as posted above, ie command="cd /srv/hg && /usr/local/bin/hg-ssh * */* */*/* */*/*/*",no-port-forwarding,...? Does everything up to the curly brackets go inside the command? Also, really, the idea is to match only the directories, not the files, since a repository can only correspond to a directory, and not a file. Jul 3, 2011 at 21:20
  • @FaheemMitha Everything, from cd to +, is the shell command. I copied what you did, matching all files regardless of type. If you want to match only directories, add -type d before -exec. But I wonder if this is really what you want (note that I know nothing about hg-ssh): are you looking for .hg directories? Jul 3, 2011 at 21:25
  • No, all directories are possible Mercurial repositories. The example I gave (/srv/hg/faheem/bixfile/.hg/patches) is the special case of a MQ repository, which lives inside the .hg directory corresponding to another Mercurial repository. I tried it and got remote: find: Expected a positive decimal integer argument to -mindepth, but got '-maxdepth'. Can one just leave mindepth out, or does it need to be given a number? Jul 3, 2011 at 21:42
  • It works if I take out -mindepth, but does it then default to mindepth 1? I'm currently using command="cd /srv/hg && find . -maxdepth 4 -type d -exec /usr/local/bin/hg-ssh {} +". Jul 3, 2011 at 21:50
  • @FaheemMitha I meant -mindepth 1 to exclude . (depth 0), but I guess you want to include it? So no -mindepth. Jul 3, 2011 at 21:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .