# HG changeset patch # User Bryan O'Sullivan # Date 1240550642 25200 # Node ID ef53d025f4100d5ce4d159aad97b651b43a9d7b4 # Parent 557552d4699ff29a1d4ea18364bb32d46a66cab3 Mention qdelete and qimport -r. diff -r 557552d4699f -r ef53d025f410 en/ch09-hook.xml --- a/en/ch09-hook.xml Tue Apr 21 23:51:47 2009 -0700 +++ b/en/ch09-hook.xml Thu Apr 23 22:24:02 2009 -0700 @@ -147,8 +147,8 @@ incoming), remember that it is the other repository's hooks you should be checking, not your own. + - Hooks do not propagate @@ -178,8 +178,8 @@ filesystem, and use a site-wide ~/.hgrc file to define hooks that all users will see. However, this too has its limits; see below. + - Hooks can be overridden @@ -193,8 +193,8 @@ hooks, you should thus understand that your users can disable or override those hooks. + - Ensuring that critical hooks are run @@ -232,116 +232,7 @@ - - Care with <literal>pretxn</literal> hooks in a - shared-access repository - If you want to use hooks to do some automated work in a - repository that a number of people have shared access to, you - need to be careful in how you do this. - - - Mercurial only locks a repository when it is writing to the - repository, and only the parts of Mercurial that write to the - repository pay attention to locks. Write locks are necessary to - prevent multiple simultaneous writers from scribbling on each - other's work, corrupting the repository. - - - Because Mercurial is careful with the order in which it - reads and writes data, it does not need to acquire a lock when - it wants to read data from the repository. The parts of - Mercurial that read from the repository never pay attention to - locks. This lockless reading scheme greatly increases - performance and concurrency. - - - With great performance comes a trade-off, though, one which - has the potential to cause you trouble unless you're aware of - it. To describe this requires a little detail about how - Mercurial adds changesets to a repository and reads those - changes. - - - When Mercurial writes metadata, it - writes it straight into the destination file. It writes file - data first, then manifest data (which contains pointers to the - new file data), then changelog data (which contains pointers to - the new manifest data). Before the first write to each file, it - stores a record of where the end of the file was in its - transaction log. If the transaction must be rolled back, - Mercurial simply truncates each file back to the size it was - before the transaction began. - - - When Mercurial reads metadata, it reads - the changelog first, then everything else. Since a reader will - only access parts of the manifest or file metadata that it can - see in the changelog, it can never see partially written data. - - - Some controlling hooks (pretxncommit and pretxnchangegroup) run when a - transaction is almost complete. All of the metadata has been - written, but Mercurial can still roll the transaction back and - cause the newly-written data to disappear. - - - If one of these hooks runs for long, it opens a window of - time during which a reader can see the metadata for changesets - that are not yet permanent, and should not be thought of as - really there. The longer the hook runs, the - longer that window is open. - - - - The problem illustrated - - In principle, a good use for the pretxnchangegroup hook would be to - automatically build and test incoming changes before they are - accepted into a central repository. This could let you - guarantee that nobody can push changes to this repository that - break the build. But if a client can pull - changes while they're being tested, the usefulness of the test - is zero; an unsuspecting someone can pull untested changes, - potentially breaking their build. - - - The safest technological answer to this challenge is to - set up such a gatekeeper repository as - unidirectional. Let it take changes - pushed in from the outside, but do not allow anyone to pull - changes from it (use the preoutgoing hook to lock it down). - Configure a changegroup hook so - that if a build or test succeeds, the hook will push the new - changes out to another repository that people - can pull from. - - - In practice, putting a centralised bottleneck like this in - place is not often a good idea, and transaction visibility has - nothing to do with the problem. As the size of a - project&emdash;and the time it takes to build and - test&emdash;grows, you rapidly run into a wall with this - try before you buy approach, where you have - more changesets to test than time in which to deal with them. - The inevitable result is frustration on the part of all - involved. - - - An approach that scales better is to get people to build - and test before they push, then run automated builds and tests - centrally after a push, to be sure all is - well. The advantage of this approach is that it does not - impose a limit on the rate at which the repository can accept - changes. - - - - A short tutorial on using hooks @@ -509,8 +400,8 @@ foo, while the environment variable for an external hook will be named HG_FOO. + - Hook return values and activity control @@ -526,8 +417,8 @@ zero/false means allow, while non-zero/true/exception means deny. + - Writing an external hook @@ -555,8 +446,8 @@ should not rely on environment variables being set to the values you have in your environment when testing the hook. + - Telling Mercurial to use an in-process hook @@ -585,8 +476,8 @@ for the callable object named myhook, and calls it. + - Writing an in-process hook @@ -622,8 +513,8 @@ &interaction.hook.msglen.go; + - Checking for trailing whitespace @@ -838,8 +729,8 @@ forbidding pushes from specific users. - - + + <literal role="hg-ext">bugzilla</literal>&emdash;integration with @@ -1144,8 +1035,8 @@ a valid Bugzilla user name. </para> - </sect3> - </sect2> + </sect3> </sect2> + <sect2> <title><literal role="hg-ext">notify</literal>&emdash;send email notifications @@ -1344,8 +1235,8 @@ APIs normally use. To convert a hash from hex to binary, use the bin function. + - External hook execution @@ -1382,8 +1273,8 @@ have succeeded. If it exits with a non-zero status, it is considered to have failed. + - Finding out where changesets come from @@ -1425,8 +1316,8 @@ being transferred to or from a bundle. + - Where changes are going&emdash;remote repository URLs @@ -1462,7 +1353,6 @@ discovered about the remote client. - @@ -1520,8 +1410,8 @@ role="hook">pretxnchangegroup () + - <literal role="hook">commit</literal>&emdash;after a new changeset is created @@ -1553,8 +1443,8 @@ role="hook">pretxncommit () + - <literal role="hook">incoming</literal>&emdash;after one remote changeset is added @@ -1599,8 +1489,8 @@ role="hook">pretxnchangegroup () + - <literal role="hook">outgoing</literal>&emdash;after changesets are propagated @@ -1646,8 +1536,8 @@ role="hook">preoutgoing () + - <literal role="hook">prechangegroup</literal>&emdash;before starting @@ -1692,8 +1582,8 @@ role="hook">pretxnchangegroup</literal> (<xref linkend="sec:hook:pretxnchangegroup"/>) </para> + </sect2> - </sect2> <sect2 id="sec:hook:precommit"> <title><literal role="hook">precommit</literal>&emdash;before starting to commit a changeset @@ -1732,8 +1622,8 @@ role="hook">pretxncommit () + - <literal role="hook">preoutgoing</literal>&emdash;before starting to propagate changesets @@ -1769,8 +1659,8 @@ role="hook">outgoing () + - <literal role="hook">pretag</literal>&emdash;before tagging a changeset @@ -1811,6 +1701,7 @@ () + <literal role="hook">pretxnchangegroup</literal>&emdash;before @@ -1875,8 +1766,8 @@ role="hook">prechangegroup</literal> (<xref linkend="sec:hook:prechangegroup"/>) </para> + </sect2> - </sect2> <sect2 id="sec:hook:pretxncommit"> <title><literal role="hook">pretxncommit</literal>&emdash;before completing commit of new changeset @@ -1901,8 +1792,8 @@ race conditions if you do not take steps to avoid them. - Parameters to this hook: - + Parameters to this hook: + node: A changeset ID. The changeset ID of the newly committed changeset. @@ -1923,8 +1814,8 @@ role="hook">precommit () + - <literal role="hook">preupdate</literal>&emdash;before updating or merging working directory @@ -1955,8 +1846,8 @@ See also: update () + - <literal role="hook">tag</literal>&emdash;after tagging a changeset @@ -1992,8 +1883,8 @@ See also: pretag () + - <literal role="hook">update</literal>&emdash;after updating or merging working directory diff -r 557552d4699f -r ef53d025f410 en/ch10-template.xml --- a/en/ch10-template.xml Tue Apr 21 23:51:47 2009 -0700 +++ b/en/ch10-template.xml Thu Apr 23 22:24:02 2009 -0700 @@ -56,9 +56,9 @@ file into a location where Mercurial can find it (typically the templates subdirectory of your Mercurial install directory). - + Commands that support styles and templates @@ -125,8 +125,8 @@ braces and text with the expansion of whatever is inside. To print a literal curly brace, you must escape it, as described in . + - Common template keywords @@ -199,8 +199,8 @@ in . &interaction.template.simple.datekeyword; + - Escape sequences @@ -241,8 +241,8 @@ {, or { character, you must escape it. + - Filtering keywords to change their results @@ -410,7 +410,7 @@ bos. -&interaction.template.simple.manyfilters; + &interaction.template.simple.manyfilters; If you try to apply a filter to a piece of data that it @@ -445,10 +445,9 @@ on. For example, using fill68|tabindent gives very different results from tabindent|fill68. - - + From templates to styles @@ -513,9 +512,9 @@ treated as the name of a file; the contents of this file will be read and used as a template body. - + Style files by example @@ -566,8 +565,8 @@ is almost always trivial to visually inspect the offending line in the style file and see what is wrong. + - Uniquely identifying a repository @@ -602,8 +601,8 @@ or other activity, so that you can replay the build later if necessary. + - Mimicking Subversion's output @@ -661,7 +660,6 @@ file points to. If the style file will look too big or cluttered if you insert a literal piece of text, drop it into a template instead. - diff -r 557552d4699f -r ef53d025f410 en/ch11-mq.xml --- a/en/ch11-mq.xml Tue Apr 21 23:51:47 2009 -0700 +++ b/en/ch11-mq.xml Thu Apr 23 22:24:02 2009 -0700 @@ -118,8 +118,8 @@ Quilt knows nothing about revision control tools, so it works equally well on top of an unpacked tarball or a Subversion working copy. + - From patchwork quilt to Mercurial Queues @@ -181,8 +181,8 @@ role="hg-cmd">hg annotate command to see which changeset or patch modified a particular line of a source file. And so on. + - Understanding patches @@ -244,8 +244,8 @@ later (in ), but you should have enough information now to use MQ. + - Getting started with Mercurial Queues @@ -265,14 +265,14 @@ the qinit command is now available. -&interaction.mq.qinit-help.help; + &interaction.mq.qinit-help.help; You can use MQ with any Mercurial repository, and its commands only operate within that repository. To get started, simply prepare the repository using the qinit command. -&interaction.mq.tutorial.qinit; + &interaction.mq.tutorial.qinit; This command creates an empty directory called .hg/patches, where @@ -292,7 +292,7 @@ class="directory">.hg/patches directory, as you can see below. -&interaction.mq.tutorial.qnew; + &interaction.mq.tutorial.qnew; Also newly present in the .hg/patches directory are two @@ -320,8 +320,8 @@ normal Mercurial commands, such as hg diff and hg annotate, work exactly as they did before. + - Refreshing a patch @@ -329,7 +329,7 @@ use the qrefresh command to update the patch you are working on. -&interaction.mq.tutorial.qrefresh; + &interaction.mq.tutorial.qrefresh; This command folds the changes you have made in the working directory into your patch, and updates its @@ -342,9 +342,9 @@ doesn't work out, hg revert your modifications back to the last time you refreshed. -&interaction.mq.tutorial.qrefresh2; + &interaction.mq.tutorial.qrefresh2; + - Stacking and tracking patches @@ -354,7 +354,8 @@ new patch. Mercurial will apply this patch on top of your existing patch. -&interaction.mq.tutorial.qnew2; + &interaction.mq.tutorial.qnew2; + Notice that the patch contains the changes in our prior patch as part of its context (you can see this more clearly in the output of hg @@ -367,7 +368,7 @@ many commands that are easier to use when you are thinking about patches, as illustrated below. -&interaction.mq.tutorial.qseries; + &interaction.mq.tutorial.qseries; The + - Manipulating the patch stack @@ -420,15 +421,16 @@ directory. See below for examples of qpop and qpush in action. -&interaction.mq.tutorial.qpop; + + &interaction.mq.tutorial.qpop; Notice that once we have popped a patch or two patches, the output of qseries remains the same, while that of qapplied has changed. + - Pushing and popping many patches @@ -444,9 +446,9 @@ patches. (For some more ways to push and pop many patches, see below.) -&interaction.mq.tutorial.qpush-a; + &interaction.mq.tutorial.qpush-a; + - Safety checks, and overriding them @@ -460,7 +462,7 @@ case by the hg add of file3. -&interaction.mq.tutorial.add; + &interaction.mq.tutorial.add; Commands that check the working directory all take an I know what I'm doing option, which is always @@ -474,8 +476,8 @@ will revert modifications to any files affected by the patch that it is popping. Be sure to read the documentation for a command's option before you use it! + - Working on several patches at once @@ -499,9 +501,9 @@ the core bug, qrefresh the core patch, and qpush back to the UI patch to continue where you left off. - + More about patches @@ -580,6 +582,7 @@ 311 for details. + Strategies for applying a patch @@ -623,8 +626,8 @@ foo.orig, a foo.rej containing one hunk, and foo, containing the changes made by the five successful hunks. + - Some quirks of patch representation @@ -663,6 +666,7 @@ tree. + Beware the fuzz @@ -686,8 +690,8 @@ on top of multiple versions of a source tree, it's acceptable to have a patch apply with some fuzz, provided you've verified the results of the patching process in such cases. + - Handling rejection @@ -707,15 +711,10 @@ the .rej file and edit the target file, applying the rejected hunks by hand. - If you're feeling adventurous, Neil Brown, a Linux kernel - hacker, wrote a tool called wiggle - web:wiggle, which is more vigorous than - patch in its attempts to make a patch - apply. - - Another Linux kernel hacker, Chris Mason (the author of - Mercurial Queues), wrote a similar tool called - mpatch web:mpatch, + A Linux kernel hacker, Chris Mason (the author + of Mercurial Queues), wrote a tool called + mpatch (http://oss.oracle.com/~mason/mpatch/), which takes a simple approach to automating the application of hunks rejected by patch. The mpatch command can help with four common @@ -736,24 +735,67 @@ content than those currently present in the file. - If you use wiggle or - mpatch, you should be doubly careful to - check your results when you're done. In fact, - mpatch enforces this method of - double-checking the tool's output, by automatically dropping - you into a merge program when it has done its job, so that you - can verify its work and finish off any remaining + If you use mpatch, you + should be doubly careful to check your results when you're + done. In fact, mpatch enforces this method + of double-checking the tool's output, by automatically + dropping you into a merge program when it has done its job, so + that you can verify its work and finish off any remaining merges. - + + + More on patch management + + As you grow familiar with MQ, you will find yourself wanting + to perform other kinds of patch management operations. + + + Deleting unwanted patches + + If you want to get rid of a patch, use the hg qdelete command to delete the + patch file and remove its entry from the patch series. If you + try to delete a patch that is still applied, hg qdelete will refuse. + + &interaction.ch11-qdelete.go; + + + + Converting to and from permanent revisions + + Once you're done working on a patch and want to turn it + into a permanent changeset, use the hg qdelete -r command. Pass a + revision to the option to identify the + patch that you want to turn into a regular changeset; this + patch must already be applied. + + &interaction.ch11-qdelete.convert; + + It is also possible to turn an existing changeset into a + patch, by passing the option to hg qimport. + + &interaction.ch11-qdelete.import; + + Note that it only makes sense to convert a changeset into + a patch if you have not propagated that changeset into any + other repositories. The imported changeset's ID will change + every time you refresh the patch, which will make Mercurial + treat it as unrelated to the original changeset if you have + pushed it somewhere else. + + + Getting the best performance out of MQ MQ is very efficient at handling a large number of patches. I ran some performance experiments in mid-2006 for a talk that I - gave at the 2006 EuroPython conference - web:europython. I used as my data set the + gave at the 2006 EuroPython conference. I used as my data set the Linux 2.6.17-mm1 patch series, which consists of 1,738 patches. I applied these on top of a Linux kernel repository containing all 27,472 revisions between Linux 2.6.12-rc2 and Linux @@ -799,8 +841,8 @@ of the patch, or by number. If you use numeric addressing, patches are counted from zero; this means that the first patch is zero, the second is one, and so on. + - Updating your patches when the underlying code changes @@ -899,8 +941,8 @@ strip. You can delete .hg/patches.N once you are sure that you no longer need it as a backup. + - Identifying patches @@ -963,9 +1005,9 @@ few normal Mercurial commands in use with applied patches. -&interaction.mq.id.output; + &interaction.mq.id.output; + - Useful things to know about @@ -991,8 +1033,8 @@ this, it will appear to succeed, but MQ will become confused. + - Managing patches in a repository @@ -1077,8 +1119,8 @@ You can then issue commands of the form mq pull from the main repository. + - A few things to watch out for @@ -1216,8 +1258,8 @@ tree. &interaction.mq.tarball.repush; + - Combining entire patches @@ -1237,8 +1279,8 @@ you applied first foo, then bar, followed by quux. + - Merging part of one patch into another diff -r 557552d4699f -r ef53d025f410 en/examples/auto-snippets.xml --- a/en/examples/auto-snippets.xml Tue Apr 21 23:51:47 2009 -0700 +++ b/en/examples/auto-snippets.xml Thu Apr 23 22:24:02 2009 -0700 @@ -60,6 +60,9 @@ + + + diff -r 557552d4699f -r ef53d025f410 en/examples/ch11/qdelete --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/en/examples/ch11/qdelete Thu Apr 23 22:24:02 2009 -0700 @@ -0,0 +1,32 @@ +#!/bin/bash + +echo '[extensions]' >> $HGRC +echo 'hgext.mq =' >> $HGRC + +#$ name: go + +hg init myrepo +cd myrepo +hg qinit +hg qnew bad.patch +echo a > a +hg add a +hg qrefresh +hg qdelete bad.patch +hg qpop +hg qdelete bad.patch + +#$ name: convert + +hg qnew good.patch +echo a > a +hg add a +hg qrefresh -m 'Good change' +hg qdelete -r tip +hg qapplied +hg tip --style=compact + +#$ name: import + +hg qimport -r tip +hg qapplied