hgbook
diff en/mq.tex @ 15:b8ac9f312a47
Document wiggle and rej
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Mon Jul 03 17:58:29 2006 -0700 (2006-07-03) |
parents | e2aa527bafa0 |
children | 81454425eee9 |
line diff
1.1 --- a/en/mq.tex Mon Jul 03 17:12:11 2006 -0700 1.2 +++ b/en/mq.tex Mon Jul 03 17:58:29 2006 -0700 1.3 @@ -29,7 +29,8 @@ 1.4 they will build properly in their environments. 1.5 1.6 When you have few changes to maintain, it is easy to manage a single 1.7 -patch using the standard \texttt{diff} and \texttt{patch} programs. 1.8 +patch using the standard \texttt{diff} and \texttt{patch} programs 1.9 +(see section~\ref{sec:mq:patch} for a discussion of these tools). 1.10 Once the number of changes grows, it starts to makes sense to maintain 1.11 patches as discrete ``chunks of work,'' so that for example a single 1.12 patch will contain only one bug fix (the patch might modify several 1.13 @@ -319,32 +320,43 @@ 1.14 patch to continue where you left off. 1.15 1.16 \section{Mercurial Queues and GNU patch} 1.17 +\label{sec:mq:patch} 1.18 1.19 MQ uses the GNU \command{patch} command to apply patches. It will 1.20 help you to understand the data that MQ and \command{patch} work with, 1.21 and a few aspects of how \command{patch} operates. 1.22 1.23 +The \command{diff} command generates a list of modifications by 1.24 +comparing two files. The \command{patch} command applies a list of 1.25 +modifications to a file. The kinds of files that \command{diff} and 1.26 +\command{patch} work with are referred to as both ``diffs'' and 1.27 +``patches;'' there is no difference between a diff and a patch. 1.28 + 1.29 A patch file can start with arbitrary text; MQ uses this text as the 1.30 commit message when creating changesets. It treats the first line 1.31 that starts with the string ``\texttt{diff~-}'' as the separator 1.32 between header and content. 1.33 1.34 -MQ works with \emph{unified diffs} (\command{patch} can accept several 1.35 -other kinds of diff, but MQ doesn't). A unified diff contains two 1.36 +MQ works with \emph{unified} diffs (\command{patch} can accept several 1.37 +other diff formats, but MQ doesn't). A unified diff contains two 1.38 kinds of header. The \emph{file header} describes the file being 1.39 modified; it contains the name of the file to modify. When 1.40 -\command{patch} sees a new file header, it looks for a file of that 1.41 +\command{patch} sees a new file header, it looks for a file with that 1.42 name to start modifying. 1.43 1.44 -After the file header come a series of \emph{hunks}. Each hunk starts 1.45 -with a header; this identifies the range of line numbers within the 1.46 -file that the hunk should modify. Following the header, a hunk starts 1.47 -and ends with a few lines of text from the unmodified file; these are 1.48 -called the \emph{context} for the hunk. Each unmodified line begins 1.49 -with a space characters. Within the hunk, a line that begins with 1.50 -``\texttt{-}'' means ``remove this line,'' while a line that begins 1.51 -with ``\texttt{+}'' means ``insert this line.'' For example, a line 1.52 -that is modified is represented by one deletion and one insertion. 1.53 +After the file header comes a series of \emph{hunks}. Each hunk 1.54 +starts with a header; this identifies the range of line numbers within 1.55 +the file that the hunk should modify. Following the header, a hunk 1.56 +starts and ends with a few (usually three) lines of text from the 1.57 +unmodified file; these are called the \emph{context} for the hunk. 1.58 +Each unmodified line begins with a space characters. Within the hunk, 1.59 +a line that begins with ``\texttt{-}'' means ``remove this line,'' 1.60 +while a line that begins with ``\texttt{+}'' means ``insert this 1.61 +line.'' For example, a line that is modified is represented by one 1.62 +deletion and one insertion. 1.63 + 1.64 +The \command{diff} command runs hunks together when there's not enough 1.65 +context between modifications to justify 1.66 1.67 When \command{patch} applies a hunk, it tries a handful of 1.68 successively less accurate strategies to try to make the hunk apply. 1.69 @@ -369,8 +381,14 @@ 1.70 When neither of these techniques works, \command{patch} prints a 1.71 message saying that the hunk in question was rejected. It saves 1.72 rejected hunks to a file with the same name, and an added 1.73 -\filename{.rej} extension. If \hgcmd{qpush} fails to apply a patch, 1.74 -it will print an error message and exit. 1.75 +\filename{.rej} extension. It also saves an unmodified copy of the 1.76 +file with a \filename{.orig} extension; the copy of the file without 1.77 +any extensions will contain any changes made by hunks that \emph{did} 1.78 +apply cleanly. If you have a patch that modifies \filename{foo} with 1.79 +six hunks, and one of them fails to apply, you will have: an 1.80 +unmodified \filename{foo.orig}, a \filename{foo.rej} containing one 1.81 +hunk, and \filename{foo}, containing the changes made by the five 1.82 +successful five hunks. 1.83 1.84 \subsection{Beware the fuzz} 1.85 1.86 @@ -392,6 +410,48 @@ 1.87 apply with some fuzz, provided you've verified the results of the 1.88 patching process in such cases. 1.89 1.90 +\subsection{Handling rejection} 1.91 + 1.92 +If \hgcmd{qpush} fails to apply a patch, it will print an error 1.93 +message and exit. If it has left \filename{.rej} files behind, it is 1.94 +usually best to fix up the rejected hunks before you push more patches 1.95 +or do any further work. 1.96 + 1.97 +If your patch \emph{used to} apply cleanly, and no longer does because 1.98 +you've changed the underlying code that your patches are based on, 1.99 +Mercurial Queues can help; see section~\ref{seq:mq:merge} for details. 1.100 + 1.101 +Unfortunately, there aren't any great techniques for dealing with 1.102 +rejected hunks. Most often, you'll need to view the \filename{.rej} 1.103 +file and edit the target file, applying the rejected hunks by hand. 1.104 + 1.105 +If you're feeling adventurous, Neil Brown, an Australian Linux kernel 1.106 +hacker, has written a tool called \command{wiggle}~\cite{web:wiggle}, 1.107 +which is more vigorous than \command{patch} in its attempts to make a 1.108 +patch apply. 1.109 + 1.110 +Another Linux kernel hacker, Chris Mason (the author of Mercurial 1.111 +Queues), wrote a similar tool called \command{rej}~\cite{web:rej}, 1.112 +which takes a simple approach to automating the application of hunks 1.113 +rejected by \command{patch}. \command{rej} can help with four common 1.114 +reasons that a hunk may be rejected: 1.115 + 1.116 +\begin{itemize} 1.117 +\item The context in the middle of a hunk has changed. 1.118 +\item A hunk is missing some context at the beginning or end. 1.119 +\item A large hunk might apply better--either entirely or in part--if 1.120 + it was broken up into smaller hunks. 1.121 +\item A hunk removes lines with slightly different content than those 1.122 + currently present in the file. 1.123 +\end{itemize} 1.124 + 1.125 +If you use \command{wiggle} or \command{rej}, you should be doubly 1.126 +careful to check your results when you're done. 1.127 + 1.128 +\section{Updating your patches when the underlying code changes} 1.129 +\label{sec:mq:merge} 1.130 + 1.131 +XXX. 1.132 1.133 %%% Local Variables: 1.134 %%% mode: latex