Mercurial authenticated pushing problem - mercurial

We have central repository via http on Apache with digest authentication for two users 'One' and 'Two'.
User 'One' can do:
hg commit -uTwo -mText
hg push http://central-repo/hg/project
How to prevent that fake on the central repository?
Or how to know who makes that push to the central repository?

You can install a pushlog extension to keep track of who pushes what. See the Mozilla hgpoller repo for the pushlog extension they use (they have a separate set of templates as well). An alternative solution would be to write a hook to deny pushing changesets authored by someone else than the authenticating user. Since that can also be a very valid scenario, the pushlog solution might be best.
http://hg.mozilla.org/users/bsmedberg_mozilla.com/hgpoller
http://hg.mozilla.org/hg_templates/

Related

Bitbucket pull requests automatically merging in code?

I'm just playing around with the bitbucket/mercurial pull requests feature, and either something is behaving strangely, or I'm doing something profoundly stupid.
I (theukdave) am the owner of a repository 'RepoA' which was created under a 'team' (which I gather bitbucket doesn't really have anymore). Let's say this lives at bitbucket.org/team1/RepoA
So I created a fork of that repository under my own username and called it RepoB. So now there's a fork that lives at bitbucket.org/theukdave/RepoB
I then create a test commit on a branch off our main development branch 'develop', and then merged that new branch back into develop. I pushed up to bitbucket.org/theukdave/RepoB, and then created a pull request from 'theukdave/RepoB develop' to 'team1/RepoA develop', I add a title and description and NO reviewers (since I'm just testing right now) and click the 'create pull request' button.
A few moments later, the test commit and merge from RepoB is showing up in my RepoA. The pull request is there, I can see it, I have not yet approved it, but the commit and merge and available to all users of RepoA. Even if I decline the pull request, the test commits are still in RepoA.
Is this because I'm the owner of RepoA, and so my pull requests are automatically merged in? Is it because I added no reviewers? A combo of both? Or am I missing something here ...
First of all really interesting. You can resolve this situation using this steps.
To disable automatic branch merging for all repositories in a project (requires project admin permission):
Go to Project settings > Branching model.
Select Disable automatic merging, then click Save.
I hope useful for you.

Is there a way to email regular, aggregated mercurial changesets reports?

In an effort to boost code reviews, I am looking to send a daily/weekly/monthly/some_regular_interval report of changes from mercurial? I figure that if a person does not have to go and find the changes, but they are instead brought to the person, then that should be a step in the right direction. However, I did not see anything already out there. (We use mercurial with TortoiseHG and Jenkins for the automated build in case any of those tools might help?)
What I am looking for:
MUST HAVE
commit message
list of files that changed
NICE TO HAVE
changeset guid
name of person who did the commit
some means to see what changed on each file (probably best via a URL or else the email could become overloaded)
You don't state what OS you are using. I am assuming Windows since you are using TortoiseHG.
On Linux (or other UNIX-based OS) you can create a cron that runs once a week/month/whatever. The following simple script satisfies most of your requirements on my Linux machine:
LOG_DATE=`date -d "1 week ago" +"%Y-%m-%d 00:00:00"`
hg log -d ">$LOG_DATE"
If you use Mercurial templates you can get exactly what you want. You can construct a URL using the changeset ID to point to a Mercurial web-server.
Would the notify extension work? You can configure this on a designated master repository so that emails with a summary of the changes (you can customise the template to include the short form of the hash, the user name, the commit message) along with URLs to the individual changesets are sent out to people whenever changese are pushed to the master repository.

Push to two repositories that can't reach each other

The setup:
a laptop L
an office server hosting various repositories SOffice
a customer's database server SCustomer
I'm writing code on L for a customer, and regularly want to push it both to SOffice as well as SCustomer.
I know I could use a changegroup hook to push to a third repository from the second (as described in this answer), but this requires that the second can reach the third network-wise.
In my case, each is behind a firewall, and only my laptop typically accesses both through a VPN (or by being physically there). I could set up the VPN on SOffice to get to SCustomer, but I'd rather not.
Is there a way I can, say, set default to two repositories?
You can't default to two repositories, but you can define more than one repository in your hgrc file :
[paths]
default= /path/to/first/repo
scustomer = /path/to/second/repo
You can then push to the scustomer repository explicitly :
hg push scustomer
If you want to automate the process of pushing to both repository at once, I'm not aware of a Mercurial method to do it, but it is really easy to create a shell script, alias or something else to run both commands one after the other.
You can even use a hook on the repository to automatically push to the other one, but you will have to discriminate between a "manual" push and the automatic push in the hook, and I'm supposing this will be really messy.
Could you create a second clone of the repository with a hook that automatically pushes to both of the external repositories? Then push from your working clone to the second clone.
There's a MultirepoExtension that adds commands for doing any operation on multiple repositories.
Or you could create an alias to push to both like:
[aliases]
pushboth = !$HG push http://first ; $HG push http://second
or you could create a pre-push hook that pushes to the other one. Something like:
[hooks]
pre-push = hg push http://second
But I like (and upvoted) krtek's answer the most. Just give each a path alias and run push twice with the short names instead of the URLs.

How do I set up a hook in HG / Mercurial that gets dictated by the repository?

I have a need for a hook to run after update (this will build the solution they have updated) and I don't want to have to add that hook manually for each person that clones my central repository.
When someone first clones my central repository, is it possible to include hooks into that clone? It seems that the .hgrc file doesn't get cloned automatically.
I did read about site-wide hooks, but as far as I understand it, they work on each created repository, where I only want to have the hooks on some repos.
As Rudi already said, this is (thankfully) not possible for security reasons.
However, you can reduce the per-clone workload to set up hooks manually: Ship the hook scripts as part of your repository, e.g. in a directory .hghooks, and additionally include a script in your repo which sets up these hooks in a clone's hgrc. Each coworker now only needs to call the setup script once per clone.
This is not possible, since that hooks do not propagate to clones is a security measure. If this were possible, one could set up a rouge repository, which runs arbitrary commands on any machine where the repo is cloned.
See http://hgbook.red-bean.com/read/handling-repository-events-with-hooks.html#id402330 for more details.
This will allow for centralised per-repo hooks, with a single setup step per user. It will however cause problems for users who are disconnected from the network. An alternative if you tend to have disconnected developers (or ones over high-latency/low bandwidth links) would be to have a repo containing the hooks, and set up each user's global hgrc to point into that repo (and require regular pulls from a central hook repo).
Note that I treat the ID of the first commit as the "repo ID" - this assumes that the first commit in each repository is unique in some way - contents or commit message. If this is not the case you could do the same thing but applying it over the first N commits - but you would then have to account for repos that have fewer than N commits - can't just take repo[:5] for example as newer commits would then change the repo ID. I'd personally suggest that the first commit should probably be a standard .ignore file with a commit message unique to that repo.
Have a central shared_hgrc file, accessible from a network share (or in a hook repo).
Each user's global hgrc has:
%include /path/to/shared_hgrc
Create a shared repository of python hook modules. The hooks must be written in python.
Create your hook functions. In each function, check which repo the hook has been called on by checking the ID of the first commit:
# hooktest.py
import mercurial.util
FOOBAR_REPO = 'b88c69276866d73310be679b6a4b40d875e26d84'
ALLOW_PRECOMMIT_REPOS = set((
FOOBAR_REPO,
))
def precommit_deny_if_wrong_repo(ui, repo, **kwargs):
"""Aborts if the repo is not allowed to do this.
The repo ID is the ID of the first commit to the repo."""
repo_id = repo[0].hex().lower()
if repo_id not in ALLOW_PRECOMMIT_REPOS:
raise mercurial.util.Abort('Repository denied: %s' % (repo_id,))
ui.status('Repository allowed: %s\n' % (repo_id,))
def precommit_skip_if_wrong_repo(ui, repo, **kwargs):
"""Skips the hook if the repo is not allowed to do this.
The repo ID is the ID of the first commit to the repo."""
repo_id = repo[0].hex().lower()
if repo_id not in ALLOW_PRECOMMIT_REPOS:
ui.debug('Repository hook skipped: %s\n' % (repo_id,))
return
ui.status('Repository hook allowed: %s\n' % (repo_id,))
In the shared_hgrc file, set up the hooks you need (make sure you qualify the hook names to prevent conflicts):
[hooks]
pre-commit.00_skip = python:/path/to/hooktest.py:precommit_skip_if_wrong_repo
pre-commit.01_deny = python:/path/to/hooktest.py:precommit_deny_if_wrong_repo
As #Rudi said first, it can't be done for security reasons.
With some prior setup you can make it so that hooks are run on clone, but putting a hook with a repo-relative path in /etc/mercurial or in each user's ~/.hgrc, which in a corporate setting can be done via your system management tools or by building a custom Mercurial installer. In a non-corporate setting follow #Oben's advice and provide the scripts and a readme.

Mercurial hook to test that username is valid when pushing to repository

I have a "central" repository that I want to ensure that no one pushes changes in to with a wrong user name.
But I can not figure out how to make a hook that tests the user name against a positive list. I have found in the Mercurial API a ctx.user() call that seems to be what I want to test my positive list against.
Also the hook could be a precommit hook that is distributed as part of the repository clone or it could be a hook on the central repository as a pre-incoming or something like that.
Any help or pointers would be greatly appreciated.
I have posted two functional examples on Bitbucket. Both examples are for searching a commit message for some specifically formatted text (like an issue tracked case ID), but could be easily modified to check a user against a list of valid users.
The first example is actually a Mercurial extension that wraps the 'commit' command. If it fails to find the appropriate text (or valid user in your case), it will prevent the commit from occurring at all. You can enable this in your .hgrc file by adding these lines:
[extensions]
someName = path/to/script/commit-msg-check.py
The second example uses a in-process pretxncommit hook, which runs between when the commit has been made, but before it becomes permanent. If this check fails it will automatically roll back the commit. You can enable this in your .hgrc file by adding these lines (assuming you kept the same file/function names):
[hooks]
pretxncommit.example = python:commit-msg-check-hook.CheckForIssueRecord
You can execute any Python code you like inside of these hooks, so user validation could be done in many ways.
Thanks for the examples dls.
In the end I decided to run it as a pretxnchangegroup hook and then use the hg log and grep to test the author field of the commits:
[hooks]
pretxnchangegroup.usercheck = hg log --template '{author}\n' -r \
$HG_NODE: | grep -qe 'user1\|user2\|etc'
It does of course not provide a very good feedback other than usercheck failed. But I think it is good enough for now.