Mercurial merge permissions - mercurial

Can you configure Mercurial permissions so only repository 1.1 can be merged into 1.0 and that other repositories (ie: 1.2, 1.3) can NOT be merged into 1.0? We were interested in adding some controls around what can be merged into what.

The Named Branches Case
You can't stop people from doing whatever they want on their local machine (that's the decentralized part), but you can refuse to accept those changes with a pretxnchangegroup hook. You'd need a hook that checks each incoming changeset to make sure that if it's a merge changeset (has two parents) that neither parent's branch violates your rules.
That's assuming you're talking about named branches. If you're using repos as branches, bookmarks as branches, or anonymous branches that becomes harder since the branch name isn't part of the changeset.
If you're using Named Branches you can use the AclExtension to make certain branches writeable by only select users -- perhaps only the release manager gets to push/merge into 1.0 once active development is done?
In the end, no restriction you put in place will replace good employee training.

My other answer addresses the named branches case, in which you have a few (not very great) options because the branch name is a part of the changeset and you can watch for changesets created initially on the 1.2 branch being merged into the 1.0 branch.
The Clones As Branches Case
If you're working with clones as branches (my preferred work mode) the "what branch was this changeset done on" information isn't available. What you could do, however, to put a pretxnchangegroup hook in the 1.0 repository that blocks the first changeset that you created in your 1.2 branch. Then if anyone tries to push 1.2 stuff into the 1.0 central(-ish) repository their push will be denied.
Here's an example of how to do that sort of hook: http://ry4an.org/unblog/post/mercurial_changeset_blacklist/

Related

HgFlow and multiple developers

I really like the Hg Flow for Mercurial repositories. we are currently using Bitbucket, and in each product multiple developers are working. basically they can work as below:
a team might work on a single feature.
another team might work on a release/hot fix.
So do i keep the "develop" branch in BitBucket or local repositories. and how about feature branches, should i push them to the central repository and remove when required. i assume we should do so right?
Thanks
I personally neither use git flow or hg flow as tools, but I do use some of the methods for my own projects (manually).
Before going into detail, you always need to provide branches in the main/bitbucket repository when multiple people need to merge or branch from them.
This definately includes "develop" and probably also features/fixes multiple people need to work on (unless you have another repository or method to exchange branches/commits between them)
The difference between using git and mercurial/hg is relevant here, since the branching models are quite different.
See A Guide to Branching in Mercurial for details. Using hg bookmarks would be quite similar to what git does with branches, but there is no full support for the bookmark branching model on BitBucket (see this ticket).
hg flow (the tool) uses named branches. In contrast to git branches, these are not at all light-weight, but permanent and global (they can at least be closed now).
This means whenever any commit created on any (named) branch other than "default" is pushed to bitbucket (even after merging) this will create the branch in the bitbucket repository.
So you don't have any other choice than keeping all branches in the main repository.
However, You can decide when to push and when to close these.
I would advise using hg push -r to push only the branches/heads you want to push and only pushing these when they are either needed by somebody else or finished and merged.
Branches should be closed as soon they are not needed anymore. (This is probably done by hg flow automatically)
You should close branches locally whenever possible. This way they might not even appear in the bitbucket interface. Some might reach the bitbucket repository only in closed state (which hides them from the interface).
Obviously you should often push any branches multiple people need to merge from.
In my understanding of the workflow the "develop" branch is always exactly one branch per project that should be pushed frequently (after local testing).
In case you are either not using hg-flow or named branches things are a bit different.
Both, using forks/clones or bookmarks as a branching method doesn't generate permanent or necessarily global branches.
Like mentioned above, you can't use bookmarks (reliably) when you also want to use bitbucket pull requests. You have to push bookmarks separately. A normal push will only update (a head of) the branch so you might miss commits from other team members when marging later. Hg will tell you when a new head is created. In that case you might want to merge the branch with the remote bookmark into your branch before pushing.
When using forks as branches it works a bit like with bookmarks, but bitbucket has full support for that. You need to have a new fork on bitbucket for every branch.
You naturally only want to create extra forks if you need different people to work on it and you don't have other means of commit exchange for them. You will need at least a separate "develop" repository then.
I personally wouldn't use the full "flow" with hg on bitbucket.
For my projects the "develop" branch is the same as master/default, since I don't roll out releases with git (other than development builds, that wouldn't use the release branch anyways). I don't need a separate "production" branch, since tags can mostly be used for production usage.
I also don't create a separate "release-preparation" branch. There is only a point in time when I only apply bugfixes on develop and stop merging features. That obviously won't work when you need to work at the same time on features that are dependendant on features not to be released in the next release.
Always using the full "git flow" is easy because git branching is easy and light-weight.
Depending on the branching model you use and how supportive the other tools are,
using the full "hg flow" might not be "worth it".
The hg guide actually discourages use of named branches for short-lived branches.
See Feature separation through named branches.
The "easy" branching concept promoted in the guide is forking/cloning. Bookmarks would be the natural way to translate git flow if the tool/bitbucket support would be better (and bookmarks longer a core hg feature).
Disclaimer:
I prefer git when I can choose. I do use hg, but not as my personal choice.
You also might have considered most of this, but since you didn't state any of these details and accept an answer (in the comments) that is quite different to what you are asking, I wanted to elaborate a bit.
Edit:
To follow-up on the comments:
I think hg bookmarks are comparable to git branches because both are just movable pointers to commits.
The main difference is, that when you delete a branch in git, the commits are possibly lost (when not part of other branches or pointed to in a another branch before they are garbage collected). When you delete a bookmark in hg, then the commits are still part of the repository (part of the (named or default) branch) unless manually stripped.
Anonymous heads are related, but only as something the bookmarks point to. Without bookmarks pointing to them the anonymous heads are not usable as a branch to work with (for more than just a local merge) and share. When you have anonymous heads in a repository you don't know what they are supposed to be or where they came from, unless you remember or have other clues. In my eyes anonymous heads are only a workaround for late implementation of bookmarks and no good implementation of remotes/remote heads.
Named branches are rather unrelated, as the only thing they have in common with git branches is having a name. They are light-weight in comparision to cloning the whole repository (forking as branch model), but not in terms of "you can't get rid of them". They are permanent.
Most places tell you not to use named branches unless you have a very good reason or it is a long-running branch.

Is a workflow of hg clone on non-bare hg repositories safe?

I know that git will refuse to push to a non-bare repository, but hg doesn't seem to... Does that mean that I do not need to worry about bareness when cloning with hg? I've experimented (in pastebin below), and I haven't seen any problems with this approach, but my inability to find problems is not the same as there being no problems. Also, I have autopush enabled in my .hgrc...
http://pastebin.com/qZyyqb6p
Mercurial does not auto-merge anything when you push, so pushing to a non-bare repository is completely safe. This is why Mercurial does not distinguish between bare and non-bare repositories - a bare repository is simply one where the working directory is at the null revision (i.e. before the initial commit).
If you are pushing a new head to an existing branch Mercurial will require you to specify hg push -f. This is because having multiple heads on the same branch imposes additional complications for other developers and could potentially result in the heads being merged in different ways, leading to a cascade of unnecessary merges.
The workflow you should generally follow is pull; merge your new heads to the existing head; push. Of course, this also depends heavily on the branching strategy you are using - one which uses bookmarks (equivalent to git branches) or anonymous branching for tasks will often end up with multiple heads on the same named branch, whereas one using named branches for tasks tend not to.

Mercurial: graft vs. record vs. qrecord vs. shelve vs. transplant vs. dirstate vs. queue

I am new to Mercurial and still somehow in the evaluation process, so these four concepts are kind of confusing for me. Some are mentioned to be an equivalent to Git's Staging/Index concept, or some even a better one than Git's Staging.
How do the four commands hg graft, hg record, hg qrecord and hg shelve (and hg transplant, but this is explained in Graft vs. Transplant already) compare to each other, and how the concepts of queues and the dirstate? In which use cases is one choosen over the other?
I know there are help pages for each one, but it still is difficult to figure out what each one does as VCS in general is a new topic for me.
The design of Mercurial simply does not include the concept of a staging area. That is, there is no intermediate state between local modification and commit.
Here is an overview of each of the concepts you mentioned:
hg graft is the equivalent of git cherry-pick. It copies a commit from one branch to another. A typical use case for this feature is to copy a bug fix from one release branch to another. This command replaces the older (and now obsolete) hg transplant extension.
hg record and hg qrecord are similar to git add --patch. They allow you to interactively select hunks for commit. So if you modified several different areas of one file, you could select which areas (i.e. hunks) you actually want to commit and which you want to leave as local modifications.
qrecord is only available if you have mq enabled. It commits to an mq patch rather than a standard commit.
hg shelve is similar to git stash. It allows you to temporarily set aside local modifications to your files (or hunks of a file). These modifications can then be unshelved when you are ready for them.
dirstate is an internal class of of the Mercurial source code. It is not exposed to the user.
Mercurial Queues (also know as mq) are probably the closest you will get to a staging area in Mercurial. Here is a description from the Mercurial wiki:
Changes are maintained as patches which are committed into Mercurial.
Commits can be removed or reordered, and the underlying patch can be
refreshed based on changes made in the working directory. The patch
directory can also be placed under revision control, so you can have a
separate history of changes made to your patches.
mq is often used to polish/rework commits that you are testing locally, but have not pushed to a public location. Some people also use it to maintain a set of modifications to 3rd party code.

HG workflow : how to pick/abandon single changesets from branch clones

I think it is common practice of many development teams to create new features or bugfixes in a separate feature clone repository and pull and merge back if the feature/bugfix is ready.
However, sometimes I don't want to include all of incoming changes. To harness all the power of DVCS to review incoming changes I think it is necessary to be able to fully modify and select single aspects of the incoming changes.
What's the preferred workflow for this scenario?
As far as I know transplant extension offers the possibility to pick single changesets but I would also like to prune/pick on a path/file base e.g. to exclude some test scripts or stuff like that, that isn't required for the final feature anymore.
Since transplant is an extension, what's the official way to have a "clone, change, ... review" cycle in HG?
Mercurial is changeset-centric VCS, thus - operational object is changeset, cherry-picking inside changeset not possible at all
In Mercurial you can't discard some of incoming changesets in bundle (but can do in Git, AFAICR)
It's not official way in any form, just personal POV: because pull produce anonymous branch, before merging this branch with mainline you can edit branch content in order to exclude unwanted parts, using
histedit - delete changests, join
MQ - remove changeset from branch, edit content of changeset (convert to MQ-patch, edit, finish, reorder)

Proper command flow for branching strategy

So I have a mercurial repository that is the "blessed" repository that I will have open release cycle branches, for example Release1, Release2 etc.
When a dev is working on a release cycle they will pull down Release1, then on their local machine branch for Bug1, Bug2 and fix those.
What command sequence needs to happen for the devs to correctly close their Bug branches, merge the changes into the Release1 branch so that when the changes are pushed to the server no branch information about Bug1, Bug2 etc will be pushed to the server?
If you're using named branches the branch information about bug1 will always be pushed to the server. Named branch names are parts of their changesets and never go away or get changed. You can cause them to not show up in default branch lists by using the --close-branch option to commit, but they're still there and listable.
If you want a branching model where the branch names don't escape Mercurial provides some other branch options that may suit your needs better:
http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
If someone suggests using the 'TransplantExtension' to merge the branches in and hide the branch information, don't listen -- it's a terrible idea.