How to show content of unapplied Mercurial queue patch? - mercurial

From the hg command line interface, is there a way to show the content of an unapplied Mercurial queue patch without having to apply it or having to find the patch file manually in the corresponding queue patch folder from the .hgdirectory?

No, not quite. Unapplied patches from an mq are exactly not part of the repository itself, thus not accessible by the normal mercurial commands.
The (experimental) evolve extension is meant to become the successor of the mq extension. Making use of mercurial's phases, it allows to alter patches and easily evolve (similar to rebase) changesets which are children of the changed changeset. There all changesets, whatever phase, are accessible by all the usual mercurial commands.

Related

Post-clone hook in .hgrc is not always executed?

I have created a post-clone hook in .hg/hgrc. This hook sometimes executed, and sometimes not, depending on which directory hg is called from.
Let the repository be in /path/to/repos/. The post-clone hook is in /path/to/repos/.hg/hgrc.
Cloning from /path/to/repos/, the post-clone hook is executed:
$ pwd
/path/to/repos/
$ hg clone ./ /path/to/myclone/
Cloning from /path/to, the post-clone hook is not executed:
$ pwd
/path/to/
$ hg clone repos myclone
Why is the hgrc in my repository not read/post-clone hook not executed in the latter case?
Regards,
Freddy
I suspect you need to put the hook in your ~/hgrc file, rather than your repo's hgrc.
Hooks do not propagate
i.e.. if you add hook to a repo, then clone the repo, don't expect the hook to be in the new clone.
Here's the main text linked-to from Tom's answer, in case that page eventually changes or goes away:
Hooks do not propagate
In Mercurial, hooks are not revision controlled, and do not propagate
when you clone, or pull from, a repository. The reason for this is
simple: a hook is a completely arbitrary piece of executable code. It
runs under your user identity, with your privilege level, on your
machine.
It would be extremely reckless for any distributed revision control
system to implement revision-controlled hooks, as this would offer an
easily exploitable way to subvert the accounts of users of the
revision control system.
Since Mercurial does not propagate hooks, if you are collaborating
with other people on a common project, you should not assume that they
are using the same Mercurial hooks as you are, or that theirs are
correctly configured. You should document the hooks you expect people
to use.
In a corporate intranet, this is somewhat easier to control, as you
can for example provide a “standard” installation of Mercurial on an
NFS filesystem, and use a site-wide ~/.hgrc file to define hooks that
all users will see. However, this too has its limits...
That last warning may have been referring to the very next section which adds:
If you deploy a system- or site-wide ~/.hgrc file that defines some
hooks, you should thus understand that your users can disable or
override those hooks.

Fold outgoing changesets into a single changeset in mercurial

I want to checkpoint/commit stages (locally) using mercurial, knowing well that these changes would break the build if I pushed them to the remote repository. What I would like to do is fold/collapse/accumulate these changesets into a single changeset that I can push. I do not want the the remote repository to have these intermediate checkpoints in its history. I would like all recorded versions on the remote repository to at least build properly.
Is there any simple way to do this, perhaps an extension. I would have assume that this would be a selling point of a DVCS.
Histedit extension (fold command)
or
MQ extension (qimport + qfold + qfinish cycle) - "Combining entire patches" chapter in chapter Managing change with Mercurial Queues of "Mercurial: The Definitive Guide"

Mercurial: How can I keep stuff locally only?

We have some restrictions on what we are allowed to put in our central Mercurial repository.
Is there some way I can keep stuff in my local Hg repository, without having it pushed to the central one?
Note:
The files might be connected to files in the central repository (branches for example).
Local stuff might later be incorporated in the central repository.
If you're using branches, you can set their visibility to secret. This will prevent them to be pushed.
hg phase --secret --force my-branch
When you want to share, you change their phase to draft and then they will be automatically collected during a push operation.
See hg help phases for more information.
You could also use Mercurial Queues. With MQ, you can work with patches (which are changesets) and update or re-order them based on changes in the official repository. This will also make it easier to incorporate some or all of your changes into the main repository or just discard them later.
Commit to your local repo, then push to the remote repo when you are finished.
You can push to your local repo as well, but from my understanding that is where your current development is?
I think you want Shelve Extension or Attic Extension.
The other option is if your using a newer Hg with better branching you can just fork the central repo somewhere like bitbucket and use that as your repository for your temporary stuff and potentially branch that.
Finally you could also just use .hgignore but that could be problematic later when someone does check in the file with the same name.

Mercurial: enforce "hg pull -u" before "hg commit"

I have in some cases a need to enforce that Mercurial-users have run hg pull -u before any hg commit can be allowed, i.e., hg pull will mean that the incoming queue is empty — and furthermore I also want that the person is using the head version of the branch.
How can I set up such a restriction?
(I am fully aware that this goes against parts of the DVCS design core)
You could ask your developers to install
[hooks]
pre-commit = hg pull -u
in their config files (it should probably be installed in the per-repository .hg/hgrc file since this workflow is repository specific).
This makes Mercurial a little Subversion-like: your developers will only have one outstanding changeset. But note as soon as someone pushes to the server, hg pull -u cannot update to the new branch tip since it will cross branches (topological branches) to do so. So a proper merge will be needed at that point (or a rebase, see hg pull --rebase).
Normally mercurial will NOT let you push an open head to the server without using the -f flag (force). You can write a hook to pull automatically but that can not be enforced server side due to the server not knowing what you have. There is an article on mercurial's website about this scenario:
https://www.mercurial-scm.org/wiki/TipsAndTricks?highlight=%28heads%29#Prevent_a_push_that_would_create_multiple_heads
As Adam says, perhaps what you really need to do is prevent multiple heads (per branch). This is what we do, using the 'forbid_2head' hook from Netbeans (linked from here https://www.mercurial-scm.org/wiki/TipsAndTricks#Prevent_a_push_that_would_create_multiple_heads)
The result is that the hook prevents any push that creates multiple heads on a branch (so one on the anonymous/default branch plus one each on named branches). This effectively forces a pull before commit because you have to pull, get the two heads locally, then merge or rebase to remove it.
note, the hook is on the server/master repo

Can I mark a branch as 'not going to push'?

I use named branches in Mercurial.
In doing so I have created one branch called playground where I can try out various wacky experiments. I never intend to merge this branch into any others and I never want to push it to our main repository.
Since creating it, every time I do a push I am told I have added a new branch and I have to use the --new-branch flag. At this point hg push -b default (or whatever branch I'm pushing) works fine but it's annoying. Is there any way to suppress that message by letting Hg know that I am not interested in pushing that branch ever?
Starting with Mercurial 2.1 (released in February 2012), you can mark your changesets secret to keep them from being pushed to another repository. You use the new hg phase command to do this:
$ hg phase --force --secret .
This mark the current working directory parent revision (.) as being in the secret phase. Secret changesets are local to your repository: they wont be pushed or pulled. Pushing now looks like this:
$ hg push
pushing to /home/mg/tmp/repo
searching for changes
no changes to push but 2 secret changesets
There is no equivalent mechanism in older versions of Mercurial. There your best bet is to create a local clone for the changesets you don't want to push.
Update:
Mercurial 2.1 introduced the hg phase command which allows users to control what change sets are exchanged with remote repositories. #MartinGeisler answer to this question details this method.
Original Answer:
If you want to create a local branch of your code you have a couple options. You can hg clone the repository which will locally create a branch of the entire repository in your filesystem. The other alternative is you can try to use a Mercurial extension like LocalbranchExtension.
There are many ways to branch in Mercurial without using a named branch. Just find a method that suits your needs.
Further reading: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
In addition to the excellent answer above concerning phases, you can also specify 'default-path' (in the [paths] section of your .hgrc) to refer to the local repository:
[paths]
default = ...
default-push = .
This will cause all outgoing changesets to be compared to the specified repository. In this case, comparing outgoing changesets in your local repository TO your local repository results in nothing to push.
You can still pull/update/merge from the main repository, but no push will ever send anything back to that main repository.
If you work on multiple machines/repositories, you can set one up as described above, and configure the others to specify the 'default' path to point to the server that pushes to itself. In this way, the other machines can push/pull to your local central repository, and these changesets will never escape your carefully configured collection of repositories.