How to work without access to subrepository in Mercurial - mercurial

There is a project repository A that uses framework subrepository B. Internal team has access to both. Is it possible to limit access to B for external team without breaking possibility to work with A?
Currently it says "abort: response expected (in subrepo ...)" when cancel password entering during cloning.
Or maybe there is another way for collaboration with different access rules?
Thanks in advance!

Sorry, not possible. Actions on the "parent" repo require at least read access to the "child" repo. It's probably a lot of work at this point, but one thing to consider is making them both "sibling" repositories of an "outer" umbrella repo. That setup would look like:
UMBRELLA
PROJECT
FRAMEWORK
Then people w/ access to both can checkout UMBRELLA and have both in known, predictable locations and can still do commits across both from a single location. Those that can access PROJECT but not FRAMEWORK would check out only PROJECT.

Related

Storing PCB files *and* software files in the same Mercurial repo

I have my Banana Pi set up as my Mercurial server. It works well for me for my software as generally speaking I have firmware and that's about it in my repositories. I can access it via open VPN from anywhere in the world. However, I have started to use version control for my PCB files as well now, due to a new CAD system which complicates my old, crude but effective way of doing my PCB archiving and backup. (Also, everything in my new CAD system, all the PCBs and schamtics, are text files which makes version control work nicely.)
So, with Mercurial I started doing as I did with software and creating a new repo for my PCB for one of the boards I'm updating for a customer, and immediately came across an issue that svn seems to cope with easily and I was wondering whether Mercurial can do the same.
I have my BH0001 project repository which has all the embedded C in it and I have started creating a new issue of the PCB for which the C code is used. I had to create a new Mercurial repo called BH0001_pcb to differentiate between code and PCB. With svn you can have a project repo and then Hardware and Software directories within the project number, but still be able to check out the two different types of files to different places independently.
I could, of course, clone the BH0001 software repository to a local machine, add the PCB info in a new folder in the local Mercurial repo send it all back to the server and it would be perfectly happy. The problem then comes when checking out because I would be cloning both firmware and PCB on to a machine when I might only want one or the other.
Also, this goes against how I store stuff locally. In my /username/home directory I have a Software directory and a CAD directory and within those I have projects. So I would have:
home/CAD/CustomerName/BH0001
and
home/Software/CustomerName/BH0001.
If I'm to carry on using my current method do I have to:
Change my local directory structures to be something like:
home/Projects/CustomerName/BH0001/CAD
and
home/Projects/CustomerName/BH0001/Software
Suck it up and use things like ProjectName_pcb for separate repos.
Some other way I can't think of/can't find/am unaware of? e.g. There's a way of checking out part of a Mercurial repository to one directory and a different part of the repo to a different directory.
Or should I just use svn if I really want to carry on as I have?
With default mercurial you currently cannot do partial repository clones as you can do with SVN. So your approach to use separate repositories is a good choice.
However there ways to achieve a similar result: sub-repositories. In your case I'd create a parent repository which contains your two current repositories as sub-repositories. Mind though, sub-repositories have some rough edges, so read the linked page carefully - I'd like to especially stress that it's good practise to have a parent repo which basically only contains the 'real' repos but not much on its own.
There exist ideas like a thin or narrow clone (which is somewhat identical to what SVN does), but I haven't seen them in production.

VCS: managing multiple feature pull requests

Assuming I am expanding some project hosted on bitbucket with multiple features (managed by mercurial).
If I build up the features one on top of the other (linear local history) I have a local code base that has all the features I need, but the maintainer of the package cannot pick and choose the features he likes. (Because they build on each other.)
If I build up each feature in a separate branch based on the origin master, all the feature PRs are independent of each other (allowing the maintainer to pick and choose), but I no longer have a unified local code base with all my required features.
How does one solve this problem? With patch queues? If so, how?
I'd go for both actually: create a separate feature branch (anonymous heads, maybe named by means of a bookmark) and pull request for each feature.
Additionally, for your own benefit, and maybe also for others to check it all quickly, merge those into your main development branch, your main line.
In principle mercurial has the system of phases and allows for non-publishing repositories which allows to keep a draft history and allows you to easier make updates - but that's afaik something which bitbucket does not yet (fully?) support.

How do large companies deal with Mercurial?

I am investigating how to migrate our source control from SVN to Mercurial. One thing I am not sure how to deal with is usernames in commits. From what I've seen, there is no way to force an HG user to use a specific username, even if specified in Mercurial.ini, the user can override it in commits with the -u flag in hg commit.
How do companies deal with this? there is nothing to prevent developer A to commit something in his repository as developer B, and then pushing it to someone else.
Thanks.
I wouldn't say our company is large (4 developers), but it's never been an issue for us so far. I haven't seen any way to prevent that behavior either in my searching. I guess it comes down to an issue of trust amongst your developers.
Unrelated, we did successfully migrate from SVN to Mercurial about two years ago so I may be able to answer other questions you have.
EDIT: An idea:
I'm not sure how you were planning on setting up your topology, but we have a server that functions as the central repository for all our repos. It is possible to push changes between developers (bypassing the central server), but we never do that. We always commit locally and then push/pull from/to the central server. Additionally, we use https and windows authentication to authenticate with this central server.
If you're planning on having something like this, you could create a hook on the server (see repository events) (maybe the precommit event) that would verify that the user name in each commit being pushed is the same as the authenticated user from the web server.
Not sure if this would work, but it sounds plausable.
Another attempt(s)
Path-based ACLs in pseudo-CVCS workflow
If you'll use "controlled anarchy" workflow (p2p communications aren't controlled, resticted AND trusted and single authoritative source is common push-target), you can use "Branch Per Developer" paradigm. I.e - with ACL extension on central repo the following restrictions apply:
Nobody can push to default branch
Each developer can push only in his personal branch (under any name, name means nothing, auth-data for tracking is branch-name)
Only trusted mergers can work with repo-Central (merge dev-branches to default, NO rebase|NO history rewrite in dev-branches)
Each mergeset in default branch contain authentication piece - source branch
Signing branches
If you can't trust (and you must not trust) username in commits, you can trust strong crypto. Mercurial have at least two extensions, which allow digitally sign commits, thus providing accurate (so-so, see notes below) information about the authorship with own advantages and disadvantages in both cases
Commitsigs Extension Wiki and Signing Mercurial Changesets on Windows mini-HowTo are complete enough to understand and demonstrate all aspects of the start. Pro: no additional commits for signing, you can't (by design) sign old historic commits. Contra: not-so-nice output of needed commands (see screenshots in Damian's post for log and verifysigs), because it's GnuPG (no PKI), theoretically it's possible to create and use key-pair for any name-email and only "extra" comparison will show two different keys for one user
GPG extension and Approval Reports from wiki as quick-start. Pro: can use pgp-keys or openssl-certs (TBT!!!) (where openssl means one corporate source of issued certs), more readable and informative output of sigcheck command. Contra:
commiting changes to a .hgsigs file in the root of the working copy
and so it requires extra changesets to be made. This makes it
infeasible to sign all changesets. The .hgsigs file must also be
merged like any other file when branches are merged.
and at last file can be modified by hand by malicious user as any other file in WC
Edit and bugfixing
Openssl can be used in Commitsigs, not GPG extension

What's the best way to track private files in a public Mercurial repository?

"If it’s not in source control, it doesn’t exist."
This question was addressed for Git here: Techniques to handle a private and public repository?. What about for Mercurial?
I have several public Bitbucket repos (with multiple committers) where I'd like the source to be public, but which load API, SSH keys and other sensitive info from untracked files. However this results in someone emailing around the new config file if we add a new Mailchimp or Hunch or Twilio API key. Is there a way to shield these files from public view somehow and still track them? Everyone is syncing their repo through Bitbucket.
There are two good ways to handle this (besides zerkms's solution, which doesn't offer the easy of synchronization you want, but is what I'd do anyway):
Use Mercurial Queues. When you create a mercurial queue with hg qinit --create-repo it creates an overlay system that can be qpushed atop the existing repo. So you keep your secrets in queues and qpush them when you need them, and qpop them when you don't. With --create-repo the set of overlays (patches) is handled in a repository of its own. So people in the know can push/pull the secret overlay repo and people w/o access to it can use the base repo. The patch repo can be a private repo on bitbucket or hosted elsewhere.
or
Use a subrepo exactly as described in the git solution.
Create filename.ext.sample files with templates inside (probably filled with dummy data), which need to be copied and filled with actual data in the particular working directory.
That is what I usually do ;-)
Zerkms' solution is fast, easy, and clean, and likely your best bet for preventing secure content from being tracked / published; however as you say, "If it’s not in source control, it doesn’t exist." I find that far more often what I'm trying to keep out of source control is not a security concern, but simply a configuration setting. I believe these should be tracked, and my current employer has a rather clever setup for dealing with this, which I'll attempt to simplify / generalize / summarize here.
REPOSITORY
code/
...
scripts/
configparse.sh
...
config/
common.conf
env/
development.conf
testing.conf
production.conf
users/
dimo414.conf
mycoworker.conf
...
hosts/
dimo414-laptop.conf
dimo414-server.conf
mycoworker-laptop.conf
...
local.conf*
makefile
.conf*
* untracked file
Hopefully the idea here is pretty clear, we define settings at each appropriate level, enabling highly granular control of the codebase's behavior in a logical and consistent fashion.
The scripts/configparse.sh script reads all the necessary configuration files in turn and builds .conf out of all the settings it finds.
config/common.conf is the starting point, and contains logical default values for every setting. Many will likely get overwritten, but something is specified here. It's an error for a setting to be found in another file that isn't first set in common.conf.
config/env/ controls the behavior in different environments, doing things like pointing to the correct database servers.
config/users/ looks for a $USER.conf file, useful for setting things I care about, such as increasing the logging level for aspects my team works on, or customizing behavior I prefer to use across all my machines.
config/hosts does the same for machines, looking for $HOSTNAME.conf. Useful for machine-specific settings like application paths or data directories.
config/local.conf is an untracked file, and lets you set checkout-specific values and/or content you don't want in version control.
The aggregate of all these settings is output to .conf, which is what the rest of the codebase looks for when loading settings.

How to prevent Mercurial commits/pushes of certain files?

At a point in our development process we send all *.resx files to a translator. The translator usually takes a week to send back the files. During this time no one is allowed to add, remove or update any resx file.
How can I configure mercurial to enforce that policy?
Our setup: Each dev works with a local clone of our central repository.
Nice to have:
I'll turn the "policy" on and off every few weeks. So ideally, I'd like something that is easy to configure at one place and that affect all devs.
I'd rather enforce that policy at the local repository level then at the central repository level because if we prevent the "push" on the central repository, it will be harder for the dev to undo the already locally committed changeset.
Thanks
UPDATE:
More info on the translation process:
Merging is not an issue here. The translator does not change the files that we sent to him. We send him a bunch of language neutral .resx (form1.resx) and returns a bunch of language specific resx (form1.FR.resx).
Why prevent adding new resx? Adding a resx occurs when we add a new UI to our application. If we do that after the translation package has been sent, the translator won't know about the new UI and we'll end up with a new UI with no translation.
Why prevent updating resx? If the dev changes a label value from "open" to "close", he has made a very important semantic change. If he does that after the translation package has been sent, we won't get the right translation back.
You cannot stop by people from committing changes to .resx files unless you have control over their desktop machines (using a pretxncommit hook), and even then it's easily bypassed. It's much more normal to put the check on the central server at time of push using a pretxnchangegroup hook, but you're right that they'll have to fix up any changesets and re-push, which is advanced usage. In either case you'd used the AclExtension to enforce the actual restriction.
Here are two alternate ways to go about this that might work out better for you:
Clone your repository at the start of the translation process, warn developers to leave .resx alone for awhile, apply the work of the translators when they're done, and then merge those changes back into the main development repository with a merge command that always gives the incoming changes priority: X . Then use a simple hg log command to find all the changes in .resx that just got overwritten and tell the developers to re-add them. Chide them at this time.
alternately
Make the .resx files a Subrepository of the larger outer repository. Then turn off write access to that resx repository during the forbidden period. Developers will be able to commit in the outer repository but not the inner one, but clones will still get both exactly as they always did.
For what it's worth, everyone else handles this problem with simple merging, .resx is (XML) text, and it merges just fine.
When working with a DVCS it's not always easy to exactly mirror your svn experience, but there's usually a better option anyway.
You could add *.resx to the hgignore file