September 16, 2008
Distributed source control is really great, and among them, the tool I love the most is, by far, mercurial. I use it for all my free software projects, my own non-software projects (config files, mathematical articles and such) and also, dare I say it, for my CLOSE SOURCE projects. Yes, I also do this kind of things, how harsh a world this is, isn’t it ?
In the latter case, though, I often have some problems with permissions. In my (quite common) setup, I have a central repository and the whole tree belongs to a (unix-) group. File access is restricted to this group only (chmod -R o= mydir).
On lot of current linux distribution, each user has an associated group with the same name (john:john), at least that’s how it behaves on both debian and gentoo.
When a user does a push which creates some new directory/file, then those are created as belonging to this user and its main group (john:john here). As a result, other people can not access to it, and when you want to pull the repository, you got a big ugly crash:
pulling from ssh://firstname.lastname@example.org///usr/olocal/hg/topsecretproject searching for changes adding changesets transaction abort! rollback completed abort: received changelog group is empty remote: abort: Permission denied: .hg/store/data/myfile.i
Of course, i can create a big fixperms scripts in the repository, but then I need to start it each time the problem arises, which if each time someone creates a new file/di: this is far too often.
I thought about the set-group-ID (see man ls) and indeed it works. I dont know if this is the official way of solving this problem among the mercurial communauty, and I would love to know if some other people solve it differently. At least that’s how it is documented on the mercurial site.
Now, you might as well find out about this problem once your repository has been used for a while and is already full of useful stuff. Then it is a little bit less simple than what the mercurial documentation says. Namely, you need to put the set-group-ID in the whole .hg/store/data :
cd topsecretproject/ chown john:topsecretgroup -R . chmod g=u,o= -R . find .hg/store/data -type d | xargs chmod g+s chmod g+s .hg # needed for .hg/requires