bos@1: \chapter{Managing change with Mercurial Queues} bos@1: \label{chap:mq} bos@1: bos@1: \section{The patch management problem} bos@1: \label{sec:mq:patch-mgmt} bos@1: bos@1: Here is a common scenario: you need to install a software package from bos@1: source, but you find a bug that you must fix in the source before you bos@1: can start using the package. You make your changes, forget about the bos@1: package for a while, and a few months later you need to upgrade to a bos@1: newer version of the package. If the newer version of the package bos@1: still has the bug, you must extract your fix from the older source bos@1: tree and apply it against the newer version. This is a tedious task, bos@1: and it's easy to make mistakes. bos@1: bos@1: This is a simple case of the ``patch management'' problem. You have bos@1: an ``upstream'' source tree that you can't change; you need to make bos@1: some local changes on top of the upstream tree; and you'd like to be bos@1: able to keep those changes separate, so that you can apply them to bos@1: newer versions of the upstream source. bos@1: bos@1: The patch management problem arises in many situations. Probably the bos@1: most visible is that a user of an open source software project will bos@3: contribute a bug fix or new feature to the project's maintainers in the bos@1: form of a patch. bos@1: bos@1: Distributors of operating systems that include open source software bos@1: often need to make changes to the packages they distribute so that bos@1: they will build properly in their environments. bos@1: bos@1: When you have few changes to maintain, it is easy to manage a single bos@235: patch using the standard \command{diff} and \command{patch} programs bos@15: (see section~\ref{sec:mq:patch} for a discussion of these tools). timonator@285: Once the number of changes grows, it starts to make sense to maintain bos@1: patches as discrete ``chunks of work,'' so that for example a single bos@1: patch will contain only one bug fix (the patch might modify several bos@1: files, but it's doing ``only one thing''), and you may have a number bos@1: of such patches for different bugs you need fixed and local changes bos@3: you require. In this situation, if you submit a bug fix patch to the bos@1: upstream maintainers of a package and they include your fix in a bos@1: subsequent release, you can simply drop that single patch when you're bos@1: updating to the newer release. bos@1: bos@1: Maintaining a single patch against an upstream tree is a little bos@1: tedious and error-prone, but not difficult. However, the complexity bos@1: of the problem grows rapidly as the number of patches you have to bos@1: maintain increases. With more than a tiny number of patches in hand, bos@1: understanding which ones you have applied and maintaining them moves bos@1: from messy to overwhelming. bos@1: bos@1: Fortunately, Mercurial includes a powerful extension, Mercurial Queues bos@1: (or simply ``MQ''), that massively simplifies the patch management bos@1: problem. bos@1: bos@1: \section{The prehistory of Mercurial Queues} bos@1: \label{sec:mq:history} bos@1: bos@1: During the late 1990s, several Linux kernel developers started to bos@1: maintain ``patch series'' that modified the behaviour of the Linux bos@1: kernel. Some of these series were focused on stability, some on bos@1: feature coverage, and others were more speculative. bos@1: bos@1: The sizes of these patch series grew rapidly. In 2002, Andrew Morton bos@1: published some shell scripts he had been using to automate the task of bos@1: managing his patch queues. Andrew was successfully using these bos@1: scripts to manage hundreds (sometimes thousands) of patches on top of bos@1: the Linux kernel. bos@1: bos@1: \subsection{A patchwork quilt} bos@1: \label{sec:mq:quilt} bos@1: bos@1: In early 2003, Andreas Gruenbacher and Martin Quinson borrowed the bos@2: approach of Andrew's scripts and published a tool called ``patchwork bos@2: quilt''~\cite{web:quilt}, or simply ``quilt'' bos@2: (see~\cite{gruenbacher:2005} for a paper describing it). Because bos@2: quilt substantially automated patch management, it rapidly gained a bos@2: large following among open source software developers. bos@1: bos@1: Quilt manages a \emph{stack of patches} on top of a directory tree. bos@28: To begin, you tell quilt to manage a directory tree, and tell it which bos@28: files you want to manage; it stores away the names and contents of bos@28: those files. To fix a bug, you create a new patch (using a single bos@28: command), edit the files you need to fix, then ``refresh'' the patch. bos@1: bos@1: The refresh step causes quilt to scan the directory tree; it updates bos@1: the patch with all of the changes you have made. You can create bos@1: another patch on top of the first, which will track the changes bos@1: required to modify the tree from ``tree with one patch applied'' to bos@1: ``tree with two patches applied''. bos@1: bos@1: You can \emph{change} which patches are applied to the tree. If you bos@1: ``pop'' a patch, the changes made by that patch will vanish from the bos@1: directory tree. Quilt remembers which patches you have popped, bos@1: though, so you can ``push'' a popped patch again, and the directory bos@1: tree will be restored to contain the modifications in the patch. Most bos@1: importantly, you can run the ``refresh'' command at any time, and the bos@1: topmost applied patch will be updated. This means that you can, at bos@1: any time, change both which patches are applied and what bos@1: modifications those patches make. bos@1: bos@1: Quilt knows nothing about revision control tools, so it works equally bos@287: well on top of an unpacked tarball or a Subversion working copy. bos@1: bos@1: \subsection{From patchwork quilt to Mercurial Queues} bos@1: \label{sec:mq:quilt-mq} bos@1: bos@1: In mid-2005, Chris Mason took the features of quilt and wrote an bos@1: extension that he called Mercurial Queues, which added quilt-like bos@1: behaviour to Mercurial. bos@1: bos@1: The key difference between quilt and MQ is that quilt knows nothing bos@1: about revision control systems, while MQ is \emph{integrated} into bos@1: Mercurial. Each patch that you push is represented as a Mercurial bos@1: changeset. Pop a patch, and the changeset goes away. bos@1: bos@1: Because quilt does not care about revision control tools, it is still bos@1: a tremendously useful piece of software to know about for situations bos@1: where you cannot use Mercurial and MQ. bos@19: bos@50: \section{The huge advantage of MQ} bos@50: bos@50: I cannot overstate the value that MQ offers through the unification of bos@50: patches and revision control. bos@50: gb@66: A major reason that patches have persisted in the free software and bos@50: open source world---in spite of the availability of increasingly bos@50: capable revision control tools over the years---is the \emph{agility} bos@50: they offer. bos@50: bos@50: Traditional revision control tools make a permanent, irreversible bos@50: record of everything that you do. While this has great value, it's bos@50: also somewhat stifling. If you want to perform a wild-eyed bos@50: experiment, you have to be careful in how you go about it, or you risk bos@50: leaving unneeded---or worse, misleading or destabilising---traces of bos@50: your missteps and errors in the permanent revision record. bos@50: bos@50: By contrast, MQ's marriage of distributed revision control with bos@50: patches makes it much easier to isolate your work. Your patches live bos@50: on top of normal revision history, and you can make them disappear or bos@50: reappear at will. If you don't like a patch, you can drop it. If a bos@50: patch isn't quite as you want it to be, simply fix it---as many times bos@50: as you need to, until you have refined it into the form you desire. bos@50: bos@50: As an example, the integration of patches with revision control makes bos@50: understanding patches and debugging their effects---and their bos@50: interplay with the code they're based on---\emph{enormously} easier. bos@50: Since every applied patch has an associated changeset, you can use bos@50: \hgcmdargs{log}{\emph{filename}} to see which changesets and patches bos@282: affected a file. You can use the \hgext{bisect} command to bos@50: binary-search through all changesets and applied patches to see where bos@50: a bug got introduced or fixed. You can use the \hgcmd{annotate} bos@50: command to see which changeset or patch modified a particular line of bos@50: a source file. And so on. bos@50: bos@19: \section{Understanding patches} bos@26: \label{sec:mq:patch} bos@19: bos@19: Because MQ doesn't hide its patch-oriented nature, it is helpful to bos@19: understand what patches are, and a little about the tools that work bos@19: with them. bos@19: bos@19: The traditional Unix \command{diff} command compares two files, and bos@19: prints a list of differences between them. The \command{patch} command bos@19: understands these differences as \emph{modifications} to make to a bos@19: file. Take a look at figure~\ref{ex:mq:diff} for a simple example of bos@19: these commands in action. bos@19: bos@19: \begin{figure}[ht] bos@46: \interaction{mq.dodiff.diff} bos@19: \caption{Simple uses of the \command{diff} and \command{patch} commands} bos@19: \label{ex:mq:diff} bos@19: \end{figure} bos@19: bos@19: The type of file that \command{diff} generates (and \command{patch} bos@19: takes as input) is called a ``patch'' or a ``diff''; there is no bos@19: difference between a patch and a diff. (We'll use the term ``patch'', bos@19: since it's more commonly used.) bos@19: bos@19: A patch file can start with arbitrary text; the \command{patch} bos@19: command ignores this text, but MQ uses it as the commit message when bos@19: creating changesets. To find the beginning of the patch content, bos@19: \command{patch} searches for the first line that starts with the bos@19: string ``\texttt{diff~-}''. bos@19: bos@19: MQ works with \emph{unified} diffs (\command{patch} can accept several bos@19: other diff formats, but MQ doesn't). A unified diff contains two bos@19: kinds of header. The \emph{file header} describes the file being bos@19: modified; it contains the name of the file to modify. When bos@19: \command{patch} sees a new file header, it looks for a file with that bos@19: name to start modifying. bos@19: bos@19: After the file header comes a series of \emph{hunks}. Each hunk bos@19: starts with a header; this identifies the range of line numbers within bos@19: the file that the hunk should modify. Following the header, a hunk bos@19: starts and ends with a few (usually three) lines of text from the bos@19: unmodified file; these are called the \emph{context} for the hunk. If bos@19: there's only a small amount of context between successive hunks, bos@19: \command{diff} doesn't print a new hunk header; it just runs the hunks bos@19: together, with a few lines of context between modifications. bos@19: bos@19: Each line of context begins with a space character. Within the hunk, bos@19: a line that begins with ``\texttt{-}'' means ``remove this line,'' bos@19: while a line that begins with ``\texttt{+}'' means ``insert this bos@19: line.'' For example, a line that is modified is represented by one bos@19: deletion and one insertion. bos@19: gb@66: We will return to some of the more subtle aspects of patches later (in bos@26: section~\ref{sec:mq:adv-patch}), but you should have enough information bos@19: now to use MQ. bos@19: bos@2: \section{Getting started with Mercurial Queues} bos@2: \label{sec:mq:start} bos@1: bos@3: Because MQ is implemented as an extension, you must explicitly enable bos@3: before you can use it. (You don't need to download anything; MQ ships bos@3: with the standard Mercurial distribution.) To enable MQ, edit your bos@4: \tildefile{.hgrc} file, and add the lines in figure~\ref{ex:mq:config}. bos@2: bos@12: \begin{figure}[ht] bos@4: \begin{codesample4} bos@4: [extensions] bos@4: hgext.mq = bos@4: \end{codesample4} bos@4: \label{ex:mq:config} bos@4: \caption{Contents to add to \tildefile{.hgrc} to enable the MQ extension} bos@4: \end{figure} bos@3: bos@3: Once the extension is enabled, it will make a number of new commands bos@7: available. To verify that the extension is working, you can use bos@233: \hgcmd{help} to see if the \hgxcmd{mq}{qinit} command is now available; see bos@7: the example in figure~\ref{ex:mq:enabled}. bos@3: bos@12: \begin{figure}[ht] bos@4: \interaction{mq.qinit-help.help} bos@4: \caption{How to verify that MQ is enabled} bos@4: \label{ex:mq:enabled} bos@4: \end{figure} bos@1: bos@8: You can use MQ with \emph{any} Mercurial repository, and its commands bos@8: only operate within that repository. To get started, simply prepare bos@233: the repository using the \hgxcmd{mq}{qinit} command (see bos@7: figure~\ref{ex:mq:qinit}). This command creates an empty directory bos@16: called \sdirname{.hg/patches}, where MQ will keep its metadata. As bos@233: with many Mercurial commands, the \hgxcmd{mq}{qinit} command prints nothing bos@7: if it succeeds. bos@7: bos@12: \begin{figure}[ht] bos@7: \interaction{mq.tutorial.qinit} bos@7: \caption{Preparing a repository for use with MQ} bos@7: \label{ex:mq:qinit} bos@7: \end{figure} bos@7: bos@12: \begin{figure}[ht] bos@7: \interaction{mq.tutorial.qnew} bos@7: \caption{Creating a new patch} bos@7: \label{ex:mq:qnew} bos@7: \end{figure} bos@7: bos@8: \subsection{Creating a new patch} bos@8: bos@233: To begin work on a new patch, use the \hgxcmd{mq}{qnew} command. This bos@7: command takes one argument, the name of the patch to create. MQ will bos@16: use this as the name of an actual file in the \sdirname{.hg/patches} bos@7: directory, as you can see in figure~\ref{ex:mq:qnew}. bos@7: bos@16: Also newly present in the \sdirname{.hg/patches} directory are two bos@16: other files, \sfilename{series} and \sfilename{status}. The bos@16: \sfilename{series} file lists all of the patches that MQ knows about bos@8: for this repository, with one patch per line. Mercurial uses the bos@16: \sfilename{status} file for internal book-keeping; it tracks all of the bos@7: patches that MQ has \emph{applied} in this repository. bos@7: bos@7: \begin{note} bos@16: You may sometimes want to edit the \sfilename{series} file by hand; bos@7: for example, to change the sequence in which some patches are bos@16: applied. However, manually editing the \sfilename{status} file is bos@7: almost always a bad idea, as it's easy to corrupt MQ's idea of what bos@7: is happening. bos@7: \end{note} bos@7: bos@8: Once you have created your new patch, you can edit files in the bos@8: working directory as you usually would. All of the normal Mercurial bos@8: commands, such as \hgcmd{diff} and \hgcmd{annotate}, work exactly as bos@8: they did before. bos@19: bos@8: \subsection{Refreshing a patch} bos@8: bos@8: When you reach a point where you want to save your work, use the bos@233: \hgxcmd{mq}{qrefresh} command (figure~\ref{ex:mq:qnew}) to update the patch bos@8: you are working on. This command folds the changes you have made in bos@8: the working directory into your patch, and updates its corresponding bos@8: changeset to contain those changes. bos@8: bos@12: \begin{figure}[ht] bos@8: \interaction{mq.tutorial.qrefresh} bos@8: \caption{Refreshing a patch} bos@8: \label{ex:mq:qrefresh} bos@8: \end{figure} bos@8: bos@233: You can run \hgxcmd{mq}{qrefresh} as often as you like, so it's a good way bos@13: to ``checkpoint'' your work. Refresh your patch at an opportune bos@8: time; try an experiment; and if the experiment doesn't work out, bos@8: \hgcmd{revert} your modifications back to the last time you refreshed. bos@8: bos@12: \begin{figure}[ht] bos@8: \interaction{mq.tutorial.qrefresh2} bos@8: \caption{Refresh a patch many times to accumulate changes} bos@8: \label{ex:mq:qrefresh2} bos@8: \end{figure} bos@8: bos@8: \subsection{Stacking and tracking patches} bos@8: bos@8: Once you have finished working on a patch, or need to work on another, bos@233: you can use the \hgxcmd{mq}{qnew} command again to create a new patch. bos@8: Mercurial will apply this patch on top of your existing patch. See bos@8: figure~\ref{ex:mq:qnew2} for an example. Notice that the patch bos@8: contains the changes in our prior patch as part of its context (you bos@8: can see this more clearly in the output of \hgcmd{annotate}). bos@8: bos@12: \begin{figure}[ht] bos@8: \interaction{mq.tutorial.qnew2} bos@8: \caption{Stacking a second patch on top of the first} bos@8: \label{ex:mq:qnew2} bos@8: \end{figure} bos@8: bos@233: So far, with the exception of \hgxcmd{mq}{qnew} and \hgxcmd{mq}{qrefresh}, we've bos@27: been careful to only use regular Mercurial commands. However, MQ bos@27: provides many commands that are easier to use when you are thinking bos@27: about patches, as illustrated in figure~\ref{ex:mq:qseries}: bos@8: bos@8: \begin{itemize} bos@233: \item The \hgxcmd{mq}{qseries} command lists every patch that MQ knows bos@8: about in this repository, from oldest to newest (most recently bos@8: \emph{created}). bos@233: \item The \hgxcmd{mq}{qapplied} command lists every patch that MQ has bos@8: \emph{applied} in this repository, again from oldest to newest (most bos@8: recently applied). bos@8: \end{itemize} bos@8: bos@12: \begin{figure}[ht] bos@8: \interaction{mq.tutorial.qseries} bos@233: \caption{Understanding the patch stack with \hgxcmd{mq}{qseries} and bos@233: \hgxcmd{mq}{qapplied}} bos@8: \label{ex:mq:qseries} bos@8: \end{figure} bos@8: bos@8: \subsection{Manipulating the patch stack} bos@8: bos@8: The previous discussion implied that there must be a difference bos@11: between ``known'' and ``applied'' patches, and there is. MQ can bos@11: manage a patch without it being applied in the repository. bos@8: bos@8: An \emph{applied} patch has a corresponding changeset in the bos@8: repository, and the effects of the patch and changeset are visible in bos@8: the working directory. You can undo the application of a patch using bos@233: the \hgxcmd{mq}{qpop} command. MQ still \emph{knows about}, or manages, a bos@12: popped patch, but the patch no longer has a corresponding changeset in bos@12: the repository, and the working directory does not contain the changes bos@12: made by the patch. Figure~\ref{fig:mq:stack} illustrates the bos@12: difference between applied and tracked patches. bos@12: bos@12: \begin{figure}[ht] bos@12: \centering jeffpc@35: \grafix{mq-stack} bos@12: \caption{Applied and unapplied patches in the MQ patch stack} bos@12: \label{fig:mq:stack} bos@8: \end{figure} bos@8: bos@233: You can reapply an unapplied, or popped, patch using the \hgxcmd{mq}{qpush} bos@8: command. This creates a new changeset to correspond to the patch, and bos@8: the patch's changes once again become present in the working bos@233: directory. See figure~\ref{ex:mq:qpop} for examples of \hgxcmd{mq}{qpop} bos@233: and \hgxcmd{mq}{qpush} in action. Notice that once we have popped a patch bos@233: or two patches, the output of \hgxcmd{mq}{qseries} remains the same, while bos@233: that of \hgxcmd{mq}{qapplied} has changed. bos@8: bos@12: \begin{figure}[ht] bos@12: \interaction{mq.tutorial.qpop} bos@12: \caption{Modifying the stack of applied patches} bos@12: \label{ex:mq:qpop} bos@11: \end{figure} bos@11: bos@27: \subsection{Pushing and popping many patches} bos@27: bos@233: While \hgxcmd{mq}{qpush} and \hgxcmd{mq}{qpop} each operate on a single patch at bos@27: a time by default, you can push and pop many patches in one go. The bos@234: \hgxopt{mq}{qpush}{-a} option to \hgxcmd{mq}{qpush} causes it to push all bos@234: unapplied patches, while the \hgxopt{mq}{qpop}{-a} option to \hgxcmd{mq}{qpop} bos@27: causes it to pop all applied patches. (For some more ways to push and bos@27: pop many patches, see section~\ref{sec:mq:perf} below.) bos@27: bos@27: \begin{figure}[ht] bos@27: \interaction{mq.tutorial.qpush-a} bos@27: \caption{Pushing all unapplied patches} bos@27: \label{ex:mq:qpush-a} bos@27: \end{figure} bos@27: bos@27: \subsection{Safety checks, and overriding them} bos@27: bos@27: Several MQ commands check the working directory before they do bos@27: anything, and fail if they find any modifications. They do this to bos@27: ensure that you won't lose any changes that you have made, but not yet bos@27: incorporated into a patch. Figure~\ref{ex:mq:add} illustrates this; bos@233: the \hgxcmd{mq}{qnew} command will not create a new patch if there are bos@27: outstanding changes, caused in this case by the \hgcmd{add} of bos@27: \filename{file3}. bos@27: bos@27: \begin{figure}[ht] bos@27: \interaction{mq.tutorial.add} bos@27: \caption{Forcibly creating a patch} bos@27: \label{ex:mq:add} bos@27: \end{figure} bos@27: bos@27: Commands that check the working directory all take an ``I know what bos@27: I'm doing'' option, which is always named \option{-f}. The exact bos@27: meaning of \option{-f} depends on the command. For example, bos@234: \hgcmdargs{qnew}{\hgxopt{mq}{qnew}{-f}} will incorporate any outstanding bos@27: changes into the new patch it creates, but bos@234: \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-f}} will revert modifications to any bos@27: files affected by the patch that it is popping. Be sure to read the bos@27: documentation for a command's \option{-f} option before you use it! bos@8: bos@13: \subsection{Working on several patches at once} bos@13: bos@233: The \hgxcmd{mq}{qrefresh} command always refreshes the \emph{topmost} bos@13: applied patch. This means that you can suspend work on one patch (by bos@13: refreshing it), pop or push to make a different patch the top, and bos@13: work on \emph{that} patch for a while. bos@13: bos@13: Here's an example that illustrates how you can use this ability. bos@13: Let's say you're developing a new feature as two patches. The first bos@18: is a change to the core of your software, and the second---layered on bos@18: top of the first---changes the user interface to use the code you just bos@13: added to the core. If you notice a bug in the core while you're bos@13: working on the UI patch, it's easy to fix the core. Simply bos@233: \hgxcmd{mq}{qrefresh} the UI patch to save your in-progress changes, and bos@233: \hgxcmd{mq}{qpop} down to the core patch. Fix the core bug, bos@233: \hgxcmd{mq}{qrefresh} the core patch, and \hgxcmd{mq}{qpush} back to the UI bos@13: patch to continue where you left off. bos@13: bos@19: \section{More about patches} bos@19: \label{sec:mq:adv-patch} bos@19: bos@19: MQ uses the GNU \command{patch} command to apply patches, so it's bos@26: helpful to know a few more detailed aspects of how \command{patch} bos@26: works, and about patches themselves. bos@26: bos@26: \subsection{The strip count} bos@26: bos@26: If you look at the file headers in a patch, you will notice that the bos@26: pathnames usually have an extra component on the front that isn't bos@26: present in the actual path name. This is a holdover from the way that bos@26: people used to generate patches (people still do this, but it's bos@26: somewhat rare with modern revision control tools). bos@26: bos@26: Alice would unpack a tarball, edit her files, then decide that she bos@26: wanted to create a patch. So she'd rename her working directory, bos@26: unpack the tarball again (hence the need for the rename), and use the bos@26: \cmdopt{diff}{-r} and \cmdopt{diff}{-N} options to \command{diff} to bos@26: recursively generate a patch between the unmodified directory and the bos@26: modified one. The result would be that the name of the unmodified bos@26: directory would be at the front of the left-hand path in every file bos@26: header, and the name of the modified directory would be at the front bos@26: of the right-hand path. bos@26: bos@26: Since someone receiving a patch from the Alices of the net would be bos@26: unlikely to have unmodified and modified directories with exactly the bos@26: same names, the \command{patch} command has a \cmdopt{patch}{-p} bos@26: option that indicates the number of leading path name components to bos@26: strip when trying to apply a patch. This number is called the bos@26: \emph{strip count}. bos@26: bos@26: An option of ``\texttt{-p1}'' means ``use a strip count of one''. If bos@26: \command{patch} sees a file name \filename{foo/bar/baz} in a file bos@26: header, it will strip \filename{foo} and try to patch a file named bos@26: \filename{bar/baz}. (Strictly speaking, the strip count refers to the bos@26: number of \emph{path separators} (and the components that go with them bos@26: ) to strip. A strip count of one will turn \filename{foo/bar} into bos@26: \filename{bar}, but \filename{/foo/bar} (notice the extra leading bos@26: slash) into \filename{foo/bar}.) bos@26: bos@26: The ``standard'' strip count for patches is one; almost all patches bos@26: contain one leading path name component that needs to be stripped. bos@26: Mercurial's \hgcmd{diff} command generates path names in this form, bos@26: and the \hgcmd{import} command and MQ expect patches to have a strip bos@26: count of one. bos@26: bos@26: If you receive a patch from someone that you want to add to your patch bos@26: queue, and the patch needs a strip count other than one, you cannot bos@233: just \hgxcmd{mq}{qimport} the patch, because \hgxcmd{mq}{qimport} does not yet bos@26: have a \texttt{-p} option (see~\bug{311}). Your best bet is to bos@233: \hgxcmd{mq}{qnew} a patch of your own, then use \cmdargs{patch}{-p\emph{N}} bos@26: to apply their patch, followed by \hgcmd{addremove} to pick up any bos@233: files added or removed by the patch, followed by \hgxcmd{mq}{qrefresh}. bos@26: This complexity may become unnecessary; see~\bug{311} for details. bos@26: \subsection{Strategies for applying a patch} bos@14: bos@14: When \command{patch} applies a hunk, it tries a handful of bos@14: successively less accurate strategies to try to make the hunk apply. bos@14: This falling-back technique often makes it possible to take a patch bos@14: that was generated against an old version of a file, and apply it bos@14: against a newer version of that file. bos@14: bos@14: First, \command{patch} tries an exact match, where the line numbers, bos@14: the context, and the text to be modified must apply exactly. If it bos@14: cannot make an exact match, it tries to find an exact match for the bos@14: context, without honouring the line numbering information. If this bos@14: succeeds, it prints a line of output saying that the hunk was applied, bos@14: but at some \emph{offset} from the original line number. bos@14: bos@14: If a context-only match fails, \command{patch} removes the first and bos@14: last lines of the context, and tries a \emph{reduced} context-only bos@14: match. If the hunk with reduced context succeeds, it prints a message bos@14: saying that it applied the hunk with a \emph{fuzz factor} (the number bos@14: after the fuzz factor indicates how many lines of context bos@14: \command{patch} had to trim before the patch applied). bos@14: bos@14: When neither of these techniques works, \command{patch} prints a bos@14: message saying that the hunk in question was rejected. It saves bos@17: rejected hunks (also simply called ``rejects'') to a file with the bos@17: same name, and an added \sfilename{.rej} extension. It also saves an bos@17: unmodified copy of the file with a \sfilename{.orig} extension; the bos@17: copy of the file without any extensions will contain any changes made bos@17: by hunks that \emph{did} apply cleanly. If you have a patch that bos@17: modifies \filename{foo} with six hunks, and one of them fails to bos@17: apply, you will have: an unmodified \filename{foo.orig}, a bos@17: \filename{foo.rej} containing one hunk, and \filename{foo}, containing taavi@320: the changes made by the five successful hunks. bos@14: bos@25: \subsection{Some quirks of patch representation} bos@25: bos@25: There are a few useful things to know about how \command{patch} works bos@25: with files. bos@25: \begin{itemize} bos@25: \item This should already be obvious, but \command{patch} cannot bos@25: handle binary files. bos@25: \item Neither does it care about the executable bit; it creates new bos@25: files as readable, but not executable. bos@25: \item \command{patch} treats the removal of a file as a diff between bos@25: the file to be removed and the empty file. So your idea of ``I bos@25: deleted this file'' looks like ``every line of this file was bos@25: deleted'' in a patch. bos@25: \item It treats the addition of a file as a diff between the empty bos@25: file and the file to be added. So in a patch, your idea of ``I bos@25: added this file'' looks like ``every line of this file was added''. bos@25: \item It treats a renamed file as the removal of the old name, and the bos@25: addition of the new name. This means that renamed files have a big bos@25: footprint in patches. (Note also that Mercurial does not currently bos@25: try to infer when files have been renamed or copied in a patch.) bos@25: \item \command{patch} cannot represent empty files, so you cannot use bos@25: a patch to represent the notion ``I added this empty file to the bos@25: tree''. bos@25: \end{itemize} bos@14: \subsection{Beware the fuzz} bos@14: bos@14: While applying a hunk at an offset, or with a fuzz factor, will often bos@14: be completely successful, these inexact techniques naturally leave bos@14: open the possibility of corrupting the patched file. The most common bos@14: cases typically involve applying a patch twice, or at an incorrect bos@233: location in the file. If \command{patch} or \hgxcmd{mq}{qpush} ever bos@14: mentions an offset or fuzz factor, you should make sure that the bos@14: modified files are correct afterwards. bos@14: bos@14: It's often a good idea to refresh a patch that has applied with an bos@14: offset or fuzz factor; refreshing the patch generates new context bos@14: information that will make it apply cleanly. I say ``often,'' not bos@14: ``always,'' because sometimes refreshing a patch will make it fail to bos@14: apply against a different revision of the underlying files. In some bos@14: cases, such as when you're maintaining a patch that must sit on top of bos@14: multiple versions of a source tree, it's acceptable to have a patch bos@14: apply with some fuzz, provided you've verified the results of the bos@14: patching process in such cases. bos@14: bos@15: \subsection{Handling rejection} bos@15: bos@233: If \hgxcmd{mq}{qpush} fails to apply a patch, it will print an error bos@16: message and exit. If it has left \sfilename{.rej} files behind, it is bos@15: usually best to fix up the rejected hunks before you push more patches bos@15: or do any further work. bos@15: bos@15: If your patch \emph{used to} apply cleanly, and no longer does because bos@15: you've changed the underlying code that your patches are based on, bos@17: Mercurial Queues can help; see section~\ref{sec:mq:merge} for details. bos@15: bos@15: Unfortunately, there aren't any great techniques for dealing with bos@16: rejected hunks. Most often, you'll need to view the \sfilename{.rej} bos@15: file and edit the target file, applying the rejected hunks by hand. bos@15: bos@16: If you're feeling adventurous, Neil Brown, a Linux kernel hacker, bos@16: wrote a tool called \command{wiggle}~\cite{web:wiggle}, which is more bos@16: vigorous than \command{patch} in its attempts to make a patch apply. bos@15: bos@15: Another Linux kernel hacker, Chris Mason (the author of Mercurial bos@254: Queues), wrote a similar tool called bos@254: \command{mpatch}~\cite{web:mpatch}, which takes a simple approach to bos@254: automating the application of hunks rejected by \command{patch}. The bos@254: \command{mpatch} command can help with four common reasons that a hunk bos@254: may be rejected: bos@15: bos@15: \begin{itemize} bos@15: \item The context in the middle of a hunk has changed. bos@15: \item A hunk is missing some context at the beginning or end. bos@18: \item A large hunk might apply better---either entirely or in bos@18: part---if it was broken up into smaller hunks. bos@15: \item A hunk removes lines with slightly different content than those bos@15: currently present in the file. bos@15: \end{itemize} bos@15: bos@254: If you use \command{wiggle} or \command{mpatch}, you should be doubly bos@55: careful to check your results when you're done. In fact, bos@254: \command{mpatch} enforces this method of double-checking the tool's bos@55: output, by automatically dropping you into a merge program when it has bos@55: done its job, so that you can verify its work and finish off any bos@55: remaining merges. bos@15: bos@17: \section{Getting the best performance out of MQ} bos@27: \label{sec:mq:perf} bos@17: bos@17: MQ is very efficient at handling a large number of patches. I ran bos@17: some performance experiments in mid-2006 for a talk that I gave at the bos@17: 2006 EuroPython conference~\cite{web:europython}. I used as my data bos@17: set the Linux 2.6.17-mm1 patch series, which consists of 1,738 gb@66: patches. I applied these on top of a Linux kernel repository bos@17: containing all 27,472 revisions between Linux 2.6.12-rc2 and Linux bos@17: 2.6.17. bos@17: bos@17: On my old, slow laptop, I was able to bos@234: \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} all 1,738 patches in 3.5 minutes, bos@234: and \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} them all in 30 seconds. (On a bos@50: newer laptop, the time to push all patches dropped to two minutes.) I bos@233: could \hgxcmd{mq}{qrefresh} one of the biggest patches (which made 22,779 bos@17: lines of changes to 287 files) in 6.6 seconds. bos@17: bos@17: Clearly, MQ is well suited to working in large trees, but there are a bos@17: few tricks you can use to get the best performance of it. bos@17: bos@17: First of all, try to ``batch'' operations together. Every time you bos@233: run \hgxcmd{mq}{qpush} or \hgxcmd{mq}{qpop}, these commands scan the working bos@17: directory once to make sure you haven't made some changes and then bos@233: forgotten to run \hgxcmd{mq}{qrefresh}. On a small tree, the time that bos@17: this scan takes is unnoticeable. However, on a medium-sized tree bos@17: (containing tens of thousands of files), it can take a second or more. bos@17: bos@233: The \hgxcmd{mq}{qpush} and \hgxcmd{mq}{qpop} commands allow you to push and pop bos@17: multiple patches at a time. You can identify the ``destination bos@233: patch'' that you want to end up at. When you \hgxcmd{mq}{qpush} with a bos@17: destination specified, it will push patches until that patch is at the bos@233: top of the applied stack. When you \hgxcmd{mq}{qpop} to a destination, MQ bos@50: will pop patches until the destination patch is at the top. bos@17: bos@17: You can identify a destination patch using either the name of the bos@17: patch, or by number. If you use numeric addressing, patches are bos@17: counted from zero; this means that the first patch is zero, the second bos@17: is one, and so on. bos@17: bos@15: \section{Updating your patches when the underlying code changes} bos@15: \label{sec:mq:merge} bos@15: bos@17: It's common to have a stack of patches on top of an underlying bos@17: repository that you don't modify directly. If you're working on bos@17: changes to third-party code, or on a feature that is taking longer to bos@17: develop than the rate of change of the code beneath, you will often bos@17: need to sync up with the underlying code, and fix up any hunks in your bos@17: patches that no longer apply. This is called \emph{rebasing} your bos@17: patch series. bos@17: bos@234: The simplest way to do this is to \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} bos@17: your patches, then \hgcmd{pull} changes into the underlying bos@234: repository, and finally \hgcmdargs{qpush}{\hgxopt{mq}{qpop}{-a}} your bos@17: patches again. MQ will stop pushing any time it runs across a patch bos@17: that fails to apply during conflicts, allowing you to fix your bos@233: conflicts, \hgxcmd{mq}{qrefresh} the affected patch, and continue pushing bos@17: until you have fixed your entire stack. bos@17: bos@17: This approach is easy to use and works well if you don't expect bos@17: changes to the underlying code to affect how well your patches apply. bos@17: If your patch stack touches code that is modified frequently or bos@17: invasively in the underlying repository, however, fixing up rejected bos@17: hunks by hand quickly becomes tiresome. bos@17: bos@17: It's possible to partially automate the rebasing process. If your bos@17: patches apply cleanly against some revision of the underlying repo, MQ bos@17: can use this information to help you to resolve conflicts between your bos@17: patches and a different revision. bos@17: bos@17: The process is a little involved. bos@17: \begin{enumerate} bos@17: \item To begin, \hgcmdargs{qpush}{-a} all of your patches on top of bos@17: the revision where you know that they apply cleanly. bos@17: \item Save a backup copy of your patch directory using bos@234: \hgcmdargs{qsave}{\hgxopt{mq}{qsave}{-e} \hgxopt{mq}{qsave}{-c}}. This prints bos@17: the name of the directory that it has saved the patches in. It will bos@17: save the patches to a directory called bos@17: \sdirname{.hg/patches.\emph{N}}, where \texttt{\emph{N}} is a small bos@17: integer. It also commits a ``save changeset'' on top of your bos@17: applied patches; this is for internal book-keeping, and records the bos@17: states of the \sfilename{series} and \sfilename{status} files. bos@17: \item Use \hgcmd{pull} to bring new changes into the underlying bos@17: repository. (Don't run \hgcmdargs{pull}{-u}; see below for why.) bos@17: \item Update to the new tip revision, using bos@17: \hgcmdargs{update}{\hgopt{update}{-C}} to override the patches you bos@17: have pushed. bos@234: \item Merge all patches using \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m} bos@234: \hgxopt{mq}{qpush}{-a}}. The \hgxopt{mq}{qpush}{-m} option to \hgxcmd{mq}{qpush} bos@17: tells MQ to perform a three-way merge if the patch fails to apply. bos@17: \end{enumerate} bos@17: bos@234: During the \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-m}}, each patch in the bos@17: \sfilename{series} file is applied normally. If a patch applies with bos@233: fuzz or rejects, MQ looks at the queue you \hgxcmd{mq}{qsave}d, and bos@17: performs a three-way merge with the corresponding changeset. This bos@17: merge uses Mercurial's normal merge machinery, so it may pop up a GUI bos@17: merge tool to help you to resolve problems. bos@17: bos@17: When you finish resolving the effects of a patch, MQ refreshes your bos@17: patch based on the result of the merge. bos@17: bos@17: At the end of this process, your repository will have one extra head bos@17: from the old patch queue, and a copy of the old patch queue will be in bos@17: \sdirname{.hg/patches.\emph{N}}. You can remove the extra head using bos@234: \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a} \hgxopt{mq}{qpop}{-n} patches.\emph{N}} bos@17: or \hgcmd{strip}. You can delete \sdirname{.hg/patches.\emph{N}} once bos@17: you are sure that you no longer need it as a backup. bos@13: bos@50: \section{Identifying patches} bos@50: bos@50: MQ commands that work with patches let you refer to a patch either by bos@50: using its name or by a number. By name is obvious enough; pass the bos@233: name \filename{foo.patch} to \hgxcmd{mq}{qpush}, for example, and it will bos@55: push patches until \filename{foo.patch} is applied. bos@55: bos@55: As a shortcut, you can refer to a patch using both a name and a bos@55: numeric offset; \texttt{foo.patch-2} means ``two patches before bos@55: \texttt{foo.patch}'', while \texttt{bar.patch+4} means ``four patches bos@55: after \texttt{bar.patch}''. bos@50: bos@50: Referring to a patch by index isn't much different. The first patch bos@233: printed in the output of \hgxcmd{mq}{qseries} is patch zero (yes, it's one bos@50: of those start-at-zero counting systems); the second is patch one; and mmazur@311: so on. bos@50: bos@50: MQ also makes it easy to work with patches when you are using normal bos@50: Mercurial commands. Every command that accepts a changeset ID will bos@50: also accept the name of an applied patch. MQ augments the tags bos@50: normally in the repository with an eponymous one for each applied bos@50: patch. In addition, the special tags \index{tags!special tag bos@50: names!\texttt{qbase}}\texttt{qbase} and \index{tags!special tag bos@50: names!\texttt{qtip}}\texttt{qtip} identify the ``bottom-most'' and bos@50: topmost applied patches, respectively. bos@50: bos@50: These additions to Mercurial's normal tagging capabilities make bos@50: dealing with patches even more of a breeze. bos@50: \begin{itemize} bos@50: \item Want to patchbomb a mailing list with your latest series of bos@50: changes? bos@50: \begin{codesample4} bos@50: hg email qbase:qtip bos@50: \end{codesample4} bos@231: (Don't know what ``patchbombing'' is? See bos@231: section~\ref{sec:hgext:patchbomb}.) bos@50: \item Need to see all of the patches since \texttt{foo.patch} that bos@50: have touched files in a subdirectory of your tree? bos@50: \begin{codesample4} bos@50: hg log -r foo.patch:qtip \emph{subdir} bos@50: \end{codesample4} bos@50: \end{itemize} bos@50: bos@50: Because MQ makes the names of patches available to the rest of bos@50: Mercurial through its normal internal tag machinery, you don't need to bos@50: type in the entire name of a patch when you want to identify it by bos@50: name. bos@50: bos@50: \begin{figure}[ht] bos@155: \interaction{mq.id.output} bos@50: \caption{Using MQ's tag features to work with patches} bos@50: \label{ex:mq:id} bos@50: \end{figure} bos@50: bos@50: Another nice consequence of representing patch names as tags is that bos@50: when you run the \hgcmd{log} command, it will display a patch's name bos@50: as a tag, simply as part of its normal output. This makes it easy to bos@50: visually distinguish applied patches from underlying ``normal'' bos@50: revisions. Figure~\ref{ex:mq:id} shows a few normal Mercurial bos@50: commands in use with applied patches. bos@50: bos@26: \section{Useful things to know about} bos@26: bos@26: There are a number of aspects of MQ usage that don't fit tidily into bos@26: sections of their own, but that are good to know. Here they are, in bos@26: one place. bos@26: bos@26: \begin{itemize} bos@233: \item Normally, when you \hgxcmd{mq}{qpop} a patch and \hgxcmd{mq}{qpush} it bos@26: again, the changeset that represents the patch after the pop/push bos@26: will have a \emph{different identity} than the changeset that bos@224: represented the hash beforehand. See bos@224: section~\ref{sec:mqref:cmd:qpush} for information as to why this is. bos@26: \item It's not a good idea to \hgcmd{merge} changes from another bos@26: branch with a patch changeset, at least if you want to maintain the bos@26: ``patchiness'' of that changeset and changesets below it on the bos@26: patch stack. If you try to do this, it will appear to succeed, but bos@26: MQ will become confused. bos@26: \end{itemize} bos@50: bos@16: \section{Managing patches in a repository} bos@106: \label{sec:mq:repo} bos@16: bos@16: Because MQ's \sdirname{.hg/patches} directory resides outside a bos@16: Mercurial repository's working directory, the ``underlying'' Mercurial bos@16: repository knows nothing about the management or presence of patches. bos@16: bos@16: This presents the interesting possibility of managing the contents of bos@16: the patch directory as a Mercurial repository in its own right. This bos@16: can be a useful way to work. For example, you can work on a patch for bos@233: a while, \hgxcmd{mq}{qrefresh} it, then \hgcmd{commit} the current state of bos@16: the patch. This lets you ``roll back'' to that version of the patch bos@16: later on. bos@16: bos@26: You can then share different versions of the same patch stack among bos@26: multiple underlying repositories. I use this when I am developing a bos@26: Linux kernel feature. I have a pristine copy of my kernel sources for bos@26: each of several CPU architectures, and a cloned repository under each bos@26: that contains the patches I am working on. When I want to test a bos@26: change on a different architecture, I push my current patches to the bos@26: patch repository associated with that kernel tree, pop and push all of bos@26: my patches, and build and test that kernel. bos@16: bos@16: Managing patches in a repository makes it possible for multiple bos@16: developers to work on the same patch series without colliding with bos@16: each other, all on top of an underlying source base that they may or bos@16: may not control. bos@16: bos@17: \subsection{MQ support for patch repositories} bos@16: bos@16: MQ helps you to work with the \sdirname{.hg/patches} directory as a bos@16: repository; when you prepare a repository for working with patches bos@234: using \hgxcmd{mq}{qinit}, you can pass the \hgxopt{mq}{qinit}{-c} option to bos@16: create the \sdirname{.hg/patches} directory as a Mercurial repository. bos@16: bos@16: \begin{note} bos@234: If you forget to use the \hgxopt{mq}{qinit}{-c} option, you can simply go bos@16: into the \sdirname{.hg/patches} directory at any time and run bos@16: \hgcmd{init}. Don't forget to add an entry for the bos@17: \sfilename{status} file to the \sfilename{.hgignore} file, though bos@104: bos@234: (\hgcmdargs{qinit}{\hgxopt{mq}{qinit}{-c}} does this for you bos@17: automatically); you \emph{really} don't want to manage the bos@17: \sfilename{status} file. bos@16: \end{note} bos@16: bos@16: As a convenience, if MQ notices that the \dirname{.hg/patches} bos@16: directory is a repository, it will automatically \hgcmd{add} every bos@16: patch that you create and import. bos@16: faheem@283: MQ provides a shortcut command, \hgxcmd{mq}{qcommit}, that runs bos@16: \hgcmd{commit} in the \sdirname{.hg/patches} directory. This saves faheem@283: some bothersome typing. faheem@283: faheem@283: Finally, as a convenience to manage the patch directory, you can faheem@283: define the alias \command{mq} on Unix systems. For example, on Linux faheem@283: systems using the \command{bash} shell, you can include the following faheem@283: snippet in your \tildefile{.bashrc}. faheem@283: faheem@283: \begin{codesample2} faheem@283: alias mq=`hg -R \$(hg root)/.hg/patches' faheem@283: \end{codesample2} faheem@283: faheem@283: You can then issue commands of the form \cmdargs{mq}{pull} from faheem@283: the main repository. bos@16: bos@16: \subsection{A few things to watch out for} bos@16: bos@16: MQ's support for working with a repository full of patches is limited bos@16: in a few small respects. bos@16: bos@16: MQ cannot automatically detect changes that you make to the patch bos@16: directory. If you \hgcmd{pull}, manually edit, or \hgcmd{update} bos@16: changes to patches or the \sfilename{series} file, you will have to bos@234: \hgcmdargs{qpop}{\hgxopt{mq}{qpop}{-a}} and then bos@234: \hgcmdargs{qpush}{\hgxopt{mq}{qpush}{-a}} in the underlying repository to bos@17: see those changes show up there. If you forget to do this, you can bos@17: confuse MQ's idea of which patches are applied. bos@16: bos@26: \section{Third party tools for working with patches} bos@19: \label{sec:mq:tools} bos@16: bos@16: Once you've been working with patches for a while, you'll find bos@16: yourself hungry for tools that will help you to understand and bos@16: manipulate the patches you're dealing with. bos@16: bos@16: The \command{diffstat} command~\cite{web:diffstat} generates a bos@16: histogram of the modifications made to each file in a patch. It bos@18: provides a good way to ``get a sense of'' a patch---which files it bos@16: affects, and how much change it introduces to each file and as a bos@16: whole. (I find that it's a good idea to use \command{diffstat}'s bos@241: \cmdopt{diffstat}{-p} option as a matter of course, as otherwise it bos@241: will try to do clever things with prefixes of file names that bos@241: inevitably confuse at least me.) bos@16: bos@19: \begin{figure}[ht] bos@19: \interaction{mq.tools.tools} bos@19: \caption{The \command{diffstat}, \command{filterdiff}, and \command{lsdiff} commands} bos@19: \label{ex:mq:tools} bos@19: \end{figure} bos@19: bos@16: The \package{patchutils} package~\cite{web:patchutils} is invaluable. bos@16: It provides a set of small utilities that follow the ``Unix bos@16: philosophy;'' each does one useful thing with a patch. The bos@16: \package{patchutils} command I use most is \command{filterdiff}, which bos@16: extracts subsets from a patch file. For example, given a patch that bos@16: modifies hundreds of files across dozens of directories, a single bos@16: invocation of \command{filterdiff} can generate a smaller patch that bos@106: only touches files whose names match a particular glob pattern. See bos@106: section~\ref{mq-collab:tips:interdiff} for another example. bos@16: bos@19: \section{Good ways to work with patches} bos@19: bos@19: Whether you are working on a patch series to submit to a free software bos@19: or open source project, or a series that you intend to treat as a bos@19: sequence of regular changesets when you're done, you can use some bos@19: simple techniques to keep your work well organised. bos@19: bos@19: Give your patches descriptive names. A good name for a patch might be bos@19: \filename{rework-device-alloc.patch}, because it will immediately give bos@19: you a hint what the purpose of the patch is. Long names shouldn't be bos@19: a problem; you won't be typing the names often, but you \emph{will} be bos@233: running commands like \hgxcmd{mq}{qapplied} and \hgxcmd{mq}{qtop} over and over. bos@19: Good naming becomes especially important when you have a number of bos@19: patches to work with, or if you are juggling a number of different bos@19: tasks and your patches only get a fraction of your attention. bos@19: bos@233: Be aware of what patch you're working on. Use the \hgxcmd{mq}{qtop} bos@19: command and skim over the text of your patches frequently---for bos@19: example, using \hgcmdargs{tip}{\hgopt{tip}{-p}})---to be sure of where bos@233: you stand. I have several times worked on and \hgxcmd{mq}{qrefresh}ed a bos@19: patch other than the one I intended, and it's often tricky to migrate bos@19: changes into the right patch after making them in the wrong one. bos@19: bos@19: For this reason, it is very much worth investing a little time to bos@19: learn how to use some of the third-party tools I described in bos@19: section~\ref{sec:mq:tools}, particularly \command{diffstat} and bos@19: \command{filterdiff}. The former will give you a quick idea of what bos@19: changes your patch is making, while the latter makes it easy to splice bos@19: hunks selectively out of one patch and into another. bos@19: bos@19: \section{MQ cookbook} bos@19: bos@19: \subsection{Manage ``trivial'' patches} bos@19: bos@19: Because the overhead of dropping files into a new Mercurial repository bos@19: is so low, it makes a lot of sense to manage patches this way even if bos@19: you simply want to make a few changes to a source tarball that you bos@19: downloaded. bos@19: bos@19: Begin by downloading and unpacking the source tarball, bos@19: and turning it into a Mercurial repository. bos@19: \interaction{mq.tarball.download} bos@19: bos@19: Continue by creating a patch stack and making your changes. bos@19: \interaction{mq.tarball.qinit} bos@19: bos@19: Let's say a few weeks or months pass, and your package author releases bos@19: a new version. First, bring their changes into the repository. bos@19: \interaction{mq.tarball.newsource} bos@19: The pipeline starting with \hgcmd{locate} above deletes all files in bos@19: the working directory, so that \hgcmd{commit}'s bos@19: \hgopt{commit}{--addremove} option can actually tell which files have bos@19: really been removed in the newer version of the source. bos@19: bos@19: Finally, you can apply your patches on top of the new tree. bos@19: \interaction{mq.tarball.repush} bos@19: bos@19: \subsection{Combining entire patches} bos@19: \label{sec:mq:combine} bos@19: bos@233: MQ provides a command, \hgxcmd{mq}{qfold} that lets you combine entire bos@55: patches. This ``folds'' the patches you name, in the order you name bos@55: them, into the topmost applied patch, and concatenates their bos@55: descriptions onto the end of its description. The patches that you bos@55: fold must be unapplied before you fold them. bos@55: bos@55: The order in which you fold patches matters. If your topmost applied bos@233: patch is \texttt{foo}, and you \hgxcmd{mq}{qfold} \texttt{bar} and bos@55: \texttt{quux} into it, you will end up with a patch that has the same bos@55: effect as if you applied first \texttt{foo}, then \texttt{bar}, bos@55: followed by \texttt{quux}. bos@19: bos@19: \subsection{Merging part of one patch into another} bos@19: bos@19: Merging \emph{part} of one patch into another is more difficult than bos@19: combining entire patches. bos@19: bos@19: If you want to move changes to entire files, you can use bos@19: \command{filterdiff}'s \cmdopt{filterdiff}{-i} and bos@19: \cmdopt{filterdiff}{-x} options to choose the modifications to snip bos@19: out of one patch, concatenating its output onto the end of the patch bos@19: you want to merge into. You usually won't need to modify the patch bos@19: you've merged the changes from. Instead, MQ will report some rejected bos@233: hunks when you \hgxcmd{mq}{qpush} it (from the hunks you moved into the bos@233: other patch), and you can simply \hgxcmd{mq}{qrefresh} the patch to drop bos@19: the duplicate hunks. bos@19: bos@19: If you have a patch that has multiple hunks modifying a file, and you bos@19: only want to move a few of those hunks, the job becomes more messy, bos@19: but you can still partly automate it. Use \cmdargs{lsdiff}{-nvv} to bos@19: print some metadata about the patch. bos@19: \interaction{mq.tools.lsdiff} bos@19: bos@19: This command prints three different kinds of number: bos@19: \begin{itemize} bos@26: \item (in the first column) a \emph{file number} to identify each file bos@26: modified in the patch; bos@26: \item (on the next line, indented) the line number within a modified bos@26: file where a hunk starts; and bos@26: \item (on the same line) a \emph{hunk number} to identify that hunk. bos@19: \end{itemize} bos@19: bos@19: You'll have to use some visual inspection, and reading of the patch, bos@19: to identify the file and hunk numbers you'll want, but you can then bos@19: pass them to to \command{filterdiff}'s \cmdopt{filterdiff}{--files} bos@19: and \cmdopt{filterdiff}{--hunks} options, to select exactly the file bos@19: and hunk you want to extract. bos@19: bos@19: Once you have this hunk, you can concatenate it onto the end of your bos@19: destination patch and continue with the remainder of bos@19: section~\ref{sec:mq:combine}. bos@26: bos@26: \section{Differences between quilt and MQ} bos@26: bos@26: If you are already familiar with quilt, MQ provides a similar command bos@26: set. There are a few differences in the way that it works. bos@26: bos@26: You will already have noticed that most quilt commands have MQ bos@26: counterparts that simply begin with a ``\texttt{q}''. The exceptions bos@26: are quilt's \texttt{add} and \texttt{remove} commands, the bos@26: counterparts for which are the normal Mercurial \hgcmd{add} and bos@26: \hgcmd{remove} commands. There is no MQ equivalent of the quilt bos@26: \texttt{edit} command. bos@50: bos@1: %%% Local Variables: bos@1: %%% mode: latex bos@1: %%% TeX-master: "00book" bos@1: %%% End: