<> <> = Custom Configuration of Sets of Repositories in .hgrc = This page summarizes a lengthy discussion on the developer mailing list. It originated with [[http://www.selenic.com/mercurial/bts/issue918|issue 918: Option to copy some of .hg/hgrc upon local clone]]. == What's the idea? == One often has several local clones of the same project. Sometimes these clones all require the same extra configuration in their local `.hg/hgrc` files (`[email] to=mercurial-devel@selenic.com` for all clones of hg, for instance). It's easy to forget adding that when creating a new clone. The idea now is to: Do this extra configuration in such a way that ''new clones are automatically configured correctly''. Obviously, this defines a notion of ''sets of clones'' where such extra configuration should apply, as opposed to others where it does not. Key issues: * By what grouping mechanism can we define the sets of clones? * How are new local and remote clones added to existing sets? * Where do we define the sets we want to add extra configuration for? * Where do we put the extra configuration? * Can we update the extra configuration centrally (like `~/.hgrc`)? * Must be secure. * Don't conflict with managing `~` using hg. * Can read config before touching repo (see http://www.selenic.com/pipermail/mercurial-devel/2008-January/004291.html). == Recap Of Discussion Up To Jan 15, 2008 == === Copy elements from .hg/hgrc on local clone === This was the initial proposal. A repo's `.hg/hgrc` would contain instructions as to which of its elements to copy over when cloned locally. See [[http://www.selenic.com/mercurial/bts/issue918|issue 918]] for details. This proposal stands apart from the others: * The local clone operation groups the source and target repos into a set for the duration of the clone only. New remote clones are never automatically added to a set, and thus never auto-configured. * The extra configuration is kept where it usually is, in `.hg/hgrc`, which is augmented by copy-on-clone directives. * We cannot update extra configuration centrally as its replicated in all of the clones. === Grouping Mechanisms === We discussed two approaches which both apply extra config to qualifying repositories dynamically. They differ in the selector by which repos are included in a set (grouped): * Based on directory hierarchy. Assumption is that people will usually keep multiple local clones of the same project as children of a common parent directory. * Based on `hg id -r0`, that is, the hash of revision 0. Assumption is that this neatly identifies separate projects. While nifty, this [[http://www.selenic.com/pipermail/mercurial-devel/2008-January/004308.html|will not always work]]. === Definition Of Sets === We discussed: * Indicator-files in parent dirs of repos. For example, `/sources/hg/.hgrc-ref-python` would make all repos under `/sources/hg/` members of the set `python`. * Rev0 hashes used directly as set names. For example, `[email@b626de8b95d1]`. * Path prefixes or patterns used directly as set names. For example, `[email@/sources/hg/**]`. * Explicit configuration in `~/.hgrc`. For example: {{{ [sets] hg = ~/dev/hg/ afc = ~/dev/afc/, /public/repos/afc/ # multiple selectors nb = glob:/sources/netbeans/* jdk = re:.*/jdk/.* jcite = rev0:b626de8b95d1 }}} Note that in the last example, there is no need to support all the listed selector options. And I didn't list the other explicit definition syntax proposals here because this one seems least likely to cause problems with special characters like `:` in selectors. === Configuration Location === We discussed these approaches for where to keep the extra config: * In `~/.hgrc` within tagged sections like `[defaults@specific-set]`: {{{ [defaults@nb] log = -M [email@hg] to = mercurial-devel@selenic.com }}} * In `~/.hgrc-specific-set`, which looks exactly like `~/.hgrc`. * In an arbitrary file with the `.hgrc` format, configured per set in `~/.hgrc`. This would even allow to use multiple extra config files per set to configure different aspects. Example (from `~/.hgrc`): {{{ [set-configs] hg = ~/.hgrc-hg, ~/.hgrc-python afc = ~/.hgrc-java jcite = ~/.hgrc-java, ~/.hgrc-sourceforge }}} * In `.hgrc` files in parent dirs of a given repo. We dropped this approach because it is [[http://www.selenic.com/pipermail/mercurial-devel/2008-January/004234.html|not secure]]. == What Now? == I, Peter Arrenbrecht, favor a first implementation using just: {{{ [sets] hg = ~/dev/hg/ # path prefix as default and only option for selecting repos afc = ~/dev/afc/, /public/repos/afc/ # multiple selectors allowed [set-configs] hg = ~/.hgrc-hg, ~/.hgrc-python afc = ~/.hgrc-java jcite = ~/.hgrc-java, ~/.hgrc-sourceforge }}} I think Jesse Glick favors the variants using `[section@set-name]` in `~/.hgrc`, but I guess he could accept the above `[set]` element. Maxim Dounin thinks introducing sets and section suffixes is overkill, and still suggests much more simple syntax: {{{ [include] /path/prefix = /path/to/included/config }}} Where Matt stand now, I have no idea. Note that my and Jesse's favorites could coexist, but I think that would be overkill for a feature that will likely not see that much use in practice. == Comments == Paul Crowley said (on IRC): if there were some sort of "source" directive for hgrc files then that would fix a disadvantage of "copy hgrc on local clone" - the "source" directive would also be copied Peter Arrenbrecht said (on IRC): I also had an idea on how to fix Jesse's rev0 idea. We could add an explicit, versioned .hgidentity file. Then projects could identify themselves. Marcin Kasperski said (shamelessly writing inside this page): What is wrong with the idea of handling .hgrc file INSIDE the repository in addendum to the .hg/hgrc? Such file would be normally versioned, cloned everywhere - whether locally, or remotely, and would be perfect for all sticky settings except those personal... And one could make it so .hg/hgrc overwrites this when necessary.... This would basically introduce same security issues as looking for .hgrc in parent directories. Additionally, this wouldn't solve original Jesse's use case - he want to use other user name for set of repos. -- MaximDounin Every solution which works only locally seems to be only improving confusion, I get used to have clones copying setting, then suddenly when I clone to test machine or so, everything is lost. -- MarcinKasperski Regarding security -- I feel that the problem is somewhat mitigated when we talk about the file which belongs to the cloned repo, but ... it exists. And there are two possible approaches. Either catalog "safe" settings and allow only for them (so, for example, allow to enable some extension, but do not allow to set its path), ignoring the rest, or require review on every change (I imagine solution in which after pulling changes to .hgrc mercurial would require the user to accept or reject them via some dedicated command, accepted changes could be moved to .hg/hgrc). -- MarcinKasperski Revisiting the above: maybe the crucial idea would be to "offer" the hgrc changes to be accepted (and many sources may be used, even both in-repo .hgrc and parent dir and sth else) and save those accepted to .hg/hgrc (using normal merging algorithm). This way the user would review changes and could even patch them appropriately (say, changing the extension path) -- MarcinKasperski This really looks like an overkill for me. Additionally, it looks like it have usability problems since you have to "offer" options at least once per repository. -- MaximDounin Well, if for security reasons it is impossible to get things automatically, even within the same repo, then what one can imagine apart review? See above for proposed solutions. Basically, one can use well known places to store configuration instead (i.e. ~/.hgrc), and make user responsible for security of includes. -- MaximDounin The idea of ~/.hgrc is almost useless. It gives nothing when you use more than one machine or even more than one account, it also gives nothing for the originally quoted problem of "selected subset" of repositories. Mercurial already has /etc/hgrc.d to handle "common things", ~/.hgrc has similar merits. What Mercurial lacks most is handling configuration which is specific for the project, not for the system or user -- MarcinKasperski Marcin, it looks you understand problem better that others. Could you please point out the way Jesse can use to set his username to '...@netbeans.org' when working on netbeans, and to '...@sun.com' for other projects (this is original use case; using another machine user isn't considered as an option)? Thank you. -- MaximDounin Well, I understand you are ironic, but I will nevertheless make some attempt (after all ~/.hgrc does not solve Jesse's problem). For me it sounds like a kind of "work context" problem. We have some settings which are neither repository-bound, nor user-bound. Simple workaround could be to return to HGUSER and EMAIL variables, and write short shell scripts which setup variables correctly before spawning the true mercurial. Say {{{hgnb}}} script containing {{{ export EMAIL=...@netbeans.org hg "$@" }}} and similar {{{hgsun}}} script. This is of course very error-prone (one must remember which script to call where), but I imagine that the idea may be taken further, say to writing {{{myhg}}} script with {{{ . `hg parent`/../config.vars hg "$@" }}} (to further avoid errors one may alias such script as hg and call via full path inside, and also maybe add some error checking for the presence of config.vars file). There is no security issue here as it is Jesse's local convention and once he introduces it he is to know what he is doing. Mercurial support for such a things could be mostly around allowing one to use environment variables (instead of hgrc) for more such purposes. Maybe even sth like HGEXTRARC variable pointing to the extra hgrc file could work? This is really error-prone (the first) and not secure (the second) solutions, and as you understand can't be recommended for generic use. That's why we are trying to develop more robust one. -- MaximDounin This may be secure. Say I use directory layout ~/devel/sunprojects/projectA, ~/devel/sunprojects/projectB, ~/devel/nbprojects/projecX etc. If I write hgwrapper script which checks whether I am somewhere under /home/marcink/devel and only then loads settings/variables from /home/marcink/devels//settings.conf, then there is no risk as long as I know what I am doing and do not copy/clone remote things to ~/devel/sunprojects and ~/devel/nbprojects. But such a thing can't be done in generic way as we do not know layouts people use. Of course example script could be written and put into contrib.... -- MarcinKasperski Note: in-repo .hgrc still would be useful for sticky repo settings (my favorite example is keyword maps for hgkeyword) -- MarcinKasperski Good example, agreed. But it looks for me that keyword maps is really repository information, and probably should be stored in repository explicitly, like .hgignore and others. May be just fix keyword expansion for this? I don't really like idea of in-repo .hgrc with all related complexity involved. -- MaximDounin Whatever one would fix in keyword expansion, the first thing is to enforce it being enabled for every clone. This can't be done this way while in-repo .hgrc handles it perfectly. Also, I feel that mercurial should have some standard method of keeping extension parameters instead of expecting every extension to invent their own... -- MarcinKasperski ----