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