Mercurial: enable merge but forbid commit - mercurial

How can I forbid commits and allow merges into specific branch?
eg. master branch can't be complete with a commit but can with merge.

If you want to allow only merges in a branch, check in the hook whether every commit for that branch has two parents - and reject the incoming changes if it has only one.

Based on #planetmaker's idea
I found a hook what can help me:
https://www.mercurial-scm.org/wiki/HookExamples#pretxnchangegroup:_enforce_the_stable_branch_to_contains_only_merge_commits_on_the_server

Related

Duplicate a branch in Mercurial?

How can I duplicate a branch in Mercurial? I need the new branch to be against head (as the first one is).
The GIT equivalent (if I was in branch-a) would be:
git checkout -b branch-b
A Mercurial branch is a named entity that consists of all the commits contained within the branch. So in order to duplicate some existing branch, you must also duplicate all of its commits to new commits that are in the new branch. We then get into metaphysics arguments about commit identity. It's probably not a good idea to go here at all, but if you do want to go here, use hg graft to copy all the desired commits into the new branch.
A Git branch consists of a name containing a raw commit hash ID. So duplicating a Git branch under a new name is trivial. Note that the set of branches that contain any given commit changes dynamically over time: a branch that was only on feature/tall may now only be on master, even though that commit is still that commit, even via most of these metaphysical arguments. (Only the "no identity over time" argument lets us claim that this is not the same commit.)
Another way to put it is that Mercurial's branches actually mean something, but Git's don't. If you need true branches, you can't use Git in the first place. Don't try to import Git's bizzareness into Mercurial: you'll just make your own life miserable.
Meanwhile, though, Mercurial contains a DAG just like Git. If you use Mercurial bookmarks, those work like Git branches. It's probably wiser, then, to just use bookmarks and be done with it.
If all else fails, see hg graft.
the new branch to be against head
What is this (in usual business-term, not Git-lingua)? While in common (and in details) #torek is totally right, he forgot to write exact command-set, something like
hg up <rev-id>
hg branch <new-branch-name>
hg graft -r "branch(old-branch-name)" --log

mercurial - have I lost a commit after checking out parent and commiting there?

I committed some changes in hg, then checked out the parent of that commit and made other changes followed by another commit (from that parent).
What happened to the 1st commit? How can I find and recover it? I don't see it in the log.
What happened to the 1st commit?
It should still be there. Making the extra commit should have just created another head within the branch.
How can I find and recover it?
It should also be obvious (for finding), in Mercurial, which makes me wonder:
I don't see it in the log.
How exactly are you looking at the commit log? If you just run hg log or hg log -b <branch>, you should see all commits, or all commits in the given branch, in reverse numerical order. If you use hg log --follow, commits not reachable from the current commit will seem to disappear, because, as the documentation says:
--follow without a filename will only show ancestors or descendants of the starting revision.
In any case, you can do revision surgery if you really want to, but the simplest thing is just to merge the heads. Use hg heads . to view the heads in the current branch; check out one, and merge another, to combine the two commits with a new merge commit, making both previous heads become ordinary non-head commits, with the new merge being a single head in that branch.

Disassociate a file on a feature branch from parent in mercurial?

Is there a way to disassociate a file on a feature branch from its parent branch, in that changes to the file on the parent branch will no longer merge into the feature branch?
ie: app/index.html [develop] changes should no longer merge into app/index.html [feature/redesign] when merging develop into feature/redesign ?
You should ask yourself why you want to do this, it sounds backwards. Anyway, the following should work: perform the merge as usual, don't care about what happens to app/index.html (that is, in case of conflict just accept something, don't think about it). Then, before doing the merge commit, revert that file to its previous revision on redesign branch. To make an example:
(on branch redesign)
hg merge develop
hg revert -r redesign app/index.html
Now hg status will still show app/index.html as modified, but if you look at its contents, they are the same as before the merge. Do the merge commit as usual:
hg commit -m 'Merge develop into redesign'
Note: you must do this each time you do a merge, there is no "dissociate" capability.
Just delete and re-create it on the branch.

Mercurial Checkout without removing changes

I am attempting to work with two separate branches. The first branch is a closer to deployment phase while the second branch is an early development phase. For one reason or another the second branch does not contain some of the developments from the first branch. When I attempt to checkout the first branch while working on the second branch I receive the following error:
abort: crossed branches (use 'hg merge' to merge or use 'hg update -c' to discard changes)
Now my problem is I don't want to get rid of the second branch or really edit it in anyway. When are my options, am I missing some fundamental fact with Mercurial?
You need to either commit your changes or otherwise save them (e.g. with hg shelve) before checking out a new branch.
Mercurial (and most CVSes AFAIK) doesn't save the state of the working directory until you commit the changes, so switching branches effectively discards anything you haven't commited. You can work around this with the hg shelve extension, or by having one working copy for each branch you're working on.

Is it a bad idea to hg update when your working copy has changes?

Seems like it would be better if you did commit followed by merge. I'm a little surprised update'ing is even allowed when your working copy has changes. Is allowing updates in such cases to avoid having commits that have two parents, which result from a merge?
I believe hg update will try to merge your uncommitted changes:
The following rules apply when the working directory contains uncommitted changes:
If neither -c/--check nor -C/--clean is specified, and:
if the requested changeset is an ancestor or descendant of the working directory's parent, the uncommitted changes are merged into the requested changeset and the merged result is left uncommitted.
If the requested changeset is not an ancestor or descendant (that is, it is on another branch), the update is aborted and the uncommitted changes are preserved.
With the -c/--check option, the update is aborted and the uncommitted changes are preserved.
With the -C/--clean option, uncommitted changes are discarded and the working directory is updated to the requested changeset.
That will avoid an unnecessary commit (registered in the .hg repo) for an operation (hg update) which only is about updating your working directory.
Mercurial encourages recording all the history of a project. If you've done some work in your working directory, why not to commit these changes providing a meaningful description of your results as a commit message and then merge your results into the main branch? It will be more clear for other people to see in two separate changesets what you have made as your normal work and what you have made just for resolving merge conflicts.
Usually an extra merge changeset is OK, but sometimes you just want to rebase your current changes on top of the main branch before committing them. You might take a look at the rebase extension. The new hg rebase command allows you to rebase already committed changeses.