changeset 26:1bc6c1f0192a

More MQ content. Skeletal preface.
author Bryan O'Sullivan <bos@serpentine.com>
date Tue, 11 Jul 2006 23:48:25 -0700
parents 9d5b6d303ef5
children 535e87792eb1
files en/00book.tex en/99defs.tex en/Makefile en/mq.tex en/preface.tex
diffstat 5 files changed, 216 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/en/00book.tex	Sun Jul 09 23:18:39 2006 -0700
+++ b/en/00book.tex	Tue Jul 11 23:48:25 2006 -0700
@@ -1,3 +1,5 @@
+% The use of oneside here is a temporary hack; \marginpar entries
+% don't show up on odd pages of PDF output without it.  Sigh.
 \documentclass[oneside]{book}
 \usepackage{enumerate}
 \usepackage{fullpage}
@@ -32,6 +34,7 @@
 
 \pagenumbering{arabic}
 
+\include{preface}
 \include{intro}
 \include{mq}
 
--- a/en/99defs.tex	Sun Jul 09 23:18:39 2006 -0700
+++ b/en/99defs.tex	Tue Jul 11 23:48:25 2006 -0700
@@ -1,3 +1,4 @@
+\newcommand{\bug}[1]{\index{Mercurial issue!no.~#1}\href{http://www.selenic.com/mercurial/bts/issue#1}{Mercurial issue no.~#1}}
 \newcommand{\tildefile}[1]{\texttt{\~{}/#1}}
 \newcommand{\filename}[1]{\texttt{#1}}
 \newcommand{\dirname}[1]{\texttt{#1}}
@@ -6,7 +7,7 @@
 \newcommand{\hgext}[1]{\index{\texttt{#1} extension}\texttt{#1}}
 \newcommand{\hgcmd}[1]{\index{\texttt{#1} command}``\texttt{hg #1}''}
 \newcommand{\command}[1]{\index{\texttt{#1} command}\texttt{#1}}
-\newcommand{\cmdargs}[2]{\index{\texttt{#1} command}\texttt{#1 #2}}
+\newcommand{\cmdargs}[2]{\index{\texttt{#1} command}``\texttt{#1 #2}''}
 \newcommand{\hgcmdargs}[2]{\index{\texttt{#1} command}``\texttt{hg #1 #2}''}
 \newcommand{\hgopt}[2]{\index{\texttt{#1} command!\texttt{#2} option}\texttt{#2}}
 \newcommand{\cmdopt}[2]{\index{\texttt{#1} command!\texttt{#2} option}\texttt{#2}}
--- a/en/Makefile	Sun Jul 09 23:18:39 2006 -0700
+++ b/en/Makefile	Tue Jul 11 23:48:25 2006 -0700
@@ -6,6 +6,7 @@
 	00book.tex \
 	99book.bib \
 	99defs.tex \
+	preface.tex \
 	intro.tex \
 	mq.tex \
 	build_id.tex
@@ -38,6 +39,7 @@
 	cd $(dir $@) && makeindex $(basename $(notdir $@))
 	TEXINPUTS=$(dir $<): pdflatex $(call latex-options,$@) $< || (rm -f $@; exit 1)
 	TEXINPUTS=$(dir $<): pdflatex $(call latex-options,$@) $< || (rm -f $@; exit 1)
+	if grep 'Reference.*undefined' $(@:.pdf=.log); then exit 1; fi
 endef
 
 pdf/hgbook.pdf: $(sources) $(image-sources:%.svg=%_pdf.png) examples
--- a/en/mq.tex	Sun Jul 09 23:18:39 2006 -0700
+++ b/en/mq.tex	Tue Jul 11 23:48:25 2006 -0700
@@ -128,6 +128,7 @@
 where you cannot use Mercurial and MQ.
 
 \section{Understanding patches}
+\label{sec:mq:patch}
 
 Because MQ doesn't hide its patch-oriented nature, it is helpful to
 understand what patches are, and a little about the tools that work
@@ -179,7 +180,7 @@
 deletion and one insertion.
 
 We will return to ome of the more subtle aspects of patches later (in
-section~\ref{ex:mq:adv-patch}), but you should have enough information
+section~\ref{sec:mq:adv-patch}), but you should have enough information
 now to use MQ.
 
 \section{Getting started with Mercurial Queues}
@@ -380,8 +381,58 @@
 \label{sec:mq:adv-patch}
 
 MQ uses the GNU \command{patch} command to apply patches, so it's
-helpful to know about a few more detailed aspects of how
-\command{patch} works.
+helpful to know a few more detailed aspects of how \command{patch}
+works, and about patches themselves.
+
+\subsection{The strip count}
+
+If you look at the file headers in a patch, you will notice that the
+pathnames usually have an extra component on the front that isn't
+present in the actual path name.  This is a holdover from the way that
+people used to generate patches (people still do this, but it's
+somewhat rare with modern revision control tools).  
+
+Alice would unpack a tarball, edit her files, then decide that she
+wanted to create a patch.  So she'd rename her working directory,
+unpack the tarball again (hence the need for the rename), and use the
+\cmdopt{diff}{-r} and \cmdopt{diff}{-N} options to \command{diff} to
+recursively generate a patch between the unmodified directory and the
+modified one.  The result would be that the name of the unmodified
+directory would be at the front of the left-hand path in every file
+header, and the name of the modified directory would be at the front
+of the right-hand path.
+
+Since someone receiving a patch from the Alices of the net would be
+unlikely to have unmodified and modified directories with exactly the
+same names, the \command{patch} command has a \cmdopt{patch}{-p}
+option that indicates the number of leading path name components to
+strip when trying to apply a patch.  This number is called the
+\emph{strip count}.
+
+An option of ``\texttt{-p1}'' means ``use a strip count of one''.  If
+\command{patch} sees a file name \filename{foo/bar/baz} in a file
+header, it will strip \filename{foo} and try to patch a file named
+\filename{bar/baz}.  (Strictly speaking, the strip count refers to the
+number of \emph{path separators} (and the components that go with them
+) to strip.  A strip count of one will turn \filename{foo/bar} into
+\filename{bar}, but \filename{/foo/bar} (notice the extra leading
+slash) into \filename{foo/bar}.)
+
+The ``standard'' strip count for patches is one; almost all patches
+contain one leading path name component that needs to be stripped.
+Mercurial's \hgcmd{diff} command generates path names in this form,
+and the \hgcmd{import} command and MQ expect patches to have a strip
+count of one.
+
+If you receive a patch from someone that you want to add to your patch
+queue, and the patch needs a strip count other than one, you cannot
+just \hgcmd{qimport} the patch, because \hgcmd{qimport} does not yet
+have a \texttt{-p} option (see~\bug{311}).  Your best bet is to
+\hgcmd{qnew} a patch of your own, then use \cmdargs{patch}{-p\emph{N}}
+to apply their patch, followed by \hgcmd{addremove} to pick up any
+files added or removed by the patch, followed by \hgcmd{qrefresh}.
+This complexity may become unnecessary; see~\bug{311} for details.
+\subsection{Strategies for applying a patch}
 
 When \command{patch} applies a hunk, it tries a handful of
 successively less accurate strategies to try to make the hunk apply.
@@ -604,6 +655,24 @@
 or \hgcmd{strip}.  You can delete \sdirname{.hg/patches.\emph{N}} once
 you are sure that you no longer need it as a backup.
 
+\section{Useful things to know about}
+
+There are a number of aspects of MQ usage that don't fit tidily into
+sections of their own, but that are good to know.  Here they are, in
+one place.
+
+\begin{itemize}
+\item Normally, when you \hgcmd{qpop} a patch and \hgcmd{qpush} it
+  again, the changeset that represents the patch after the pop/push
+  will have a \emph{different identity} than the changeset that
+  represented the hash beforehand.  See section~\ref{sec:mq:cmd:qpush}
+  for information as to why this is.
+\item It's not a good idea to \hgcmd{merge} changes from another
+  branch with a patch changeset, at least if you want to maintain the
+  ``patchiness'' of that changeset and changesets below it on the
+  patch stack.  If you try to do this, it will appear to succeed, but
+  MQ will become confused.
+\end{itemize}
 \section{Managing patches in a repository}
 
 Because MQ's \sdirname{.hg/patches} directory resides outside a
@@ -617,14 +686,14 @@
 the patch.  This lets you ``roll back'' to that version of the patch
 later on.
 
-In addition, you can then share different versions of the same patch
-stack among multiple underlying repositories.  I use this when I am
-developing a Linux kernel feature.  I have a pristine copy of my
-kernel sources for each of several CPU architectures, and a cloned
-repository under each that contains the patches I am working on.  When
-I want to test a change on a different architecture, I push my current
-patches to the patch repository associated with that kernel tree, pop
-and push all of my patches, and build and test that kernel.
+You can then share different versions of the same patch stack among
+multiple underlying repositories.  I use this when I am developing a
+Linux kernel feature.  I have a pristine copy of my kernel sources for
+each of several CPU architectures, and a cloned repository under each
+that contains the patches I am working on.  When I want to test a
+change on a different architecture, I push my current patches to the
+patch repository associated with that kernel tree, pop and push all of
+my patches, and build and test that kernel.
 
 Managing patches in a repository makes it possible for multiple
 developers to work on the same patch series without colliding with
@@ -669,7 +738,7 @@
 see those changes show up there.  If you forget to do this, you can
 confuse MQ's idea of which patches are applied.
 
-\section{Commands for working with patches}
+\section{Third party tools for working with patches}
 \label{sec:mq:tools}
 
 Once you've been working with patches for a while, you'll find
@@ -801,9 +870,11 @@
 
 This command prints three different kinds of number:
 \begin{itemize}
-\item a \emph{file number} to identify each file modified in the patch;
-\item the line number within a modified file that a hunk starts at; and
-\item a \emph{hunk number} to identify that hunk.
+\item (in the first column) a \emph{file number} to identify each file
+  modified in the patch;
+\item (on the next line, indented) the line number within a modified
+  file where a hunk starts; and
+\item (on the same line) a \emph{hunk number} to identify that hunk.
 \end{itemize}
 
 You'll have to use some visual inspection, and reading of the patch,
@@ -815,6 +886,18 @@
 Once you have this hunk, you can concatenate it onto the end of your
 destination patch and continue with the remainder of
 section~\ref{sec:mq:combine}.
+
+\section{Differences between quilt and MQ}
+
+If you are already familiar with quilt, MQ provides a similar command
+set.  There are a few differences in the way that it works.
+
+You will already have noticed that most quilt commands have MQ
+counterparts that simply begin with a ``\texttt{q}''.  The exceptions
+are quilt's \texttt{add} and \texttt{remove} commands, the
+counterparts for which are the normal Mercurial \hgcmd{add} and
+\hgcmd{remove} commands.  There is no MQ equivalent of the quilt
+\texttt{edit} command.
 \section{MQ command reference}
 \label{sec:mq:cmdref}
 
@@ -953,6 +1036,7 @@
 This will become the topmost applied patch if you run \hgcmd{qpop}.
 
 \subsection{\hgcmd{qpush}---push patches onto the stack}
+\label{sec:mq:cmd:qpush}
 
 The \hgcmd{qpush} command adds patches onto the applied stack.  By
 default, it adds only one patch.
@@ -960,7 +1044,7 @@
 This command creates a new changeset to represent each applied patch,
 and updates the working directory to apply the effects of the patches.
 
-The data used when creating a changeset are as follows:
+The default data used when creating a changeset are as follows:
 \begin{itemize}
 \item The commit date and time zone are the current date and time
   zone.  Because these data are used to compute the identity of a
@@ -973,6 +1057,8 @@
   before the first diff header.  If there is no such text, a default
   commit message is used that identifies the name of the patch.
 \end{itemize}
+If a patch contains a Mercurial patch header (XXX add link), the
+information in the patch header overrides these defaults.
 
 Options:
 \begin{itemize}
@@ -1016,15 +1102,87 @@
 changeset to differ from the previous changeset that identified the
 patch.
 
+\subsection{\hgcmd{qrestore}---restore saved queue state}
+
+XXX No idea what this does.
+
+\subsection{\hgcmd{qsave}---save current queue state}
+
+XXX Likewise.
+
+\subsection{\hgcmd{qseries}---print the entire patch series}
+
+The \hgcmd{qseries} command prints the entire patch series from the
+\sfilename{series} file.  It prints only patch names, not empty lines
+or comments.  It prints in order from first to be applied to last.
+
+\subsection{\hgcmd{qtop}---print the name of the current patch}
+
+The \hgcmd{qtop} prints the name of the topmost currently applied
+patch.
+
+\subsection{\hgcmd{qunapplied}---print patches not yet applied}
+
+The \hgcmd{qunapplied} command prints the names of patches from the
+\sfilename{series} file that are not yet applied.  It prints them in
+order from the next patch that will be pushed to the last.
+
+\subsection{\hgcmd{qversion}}
+
+The \hgcmd{qversion} command prints the version of MQ that is in use.
+
+\subsection{\hgcmd{strip}---remove a revision and descendants}
+
+The \hgcmd{strip} command removes a revision, and all of its
+descendants, from the repository.  It undoes the effects of the
+removed revisions from the repository, and updates the working
+directory to the first parent of the removed revision.
+
+The \hgcmd{strip} command saves a backup of the removed changesets in
+a bundle, so that they can be reapplied if removed in error.
+
+Options:
+\begin{itemize}
+\item[\hgopt{strip}{-b}] Save unrelated changesets that are intermixed
+  with the stripped changesets in the backup bundle.
+\item[\hgopt{strip}{-f}] If a branch has multiple heads, remove all
+  heads. XXX This should be renamed, and use \texttt{-f} to strip revs
+  when there are pending changes.
+\item[\hgopt{strip}{-n}] Do not save a backup bundle.
+\end{itemize}
 \section{MQ file reference}
 
 
 \subsection{The \sfilename{series} file}
 
+The \sfilename{series} file contains a list of the names of all
+patches that MQ can apply.  It is represented as a list of names, with
+one name saved per line.  Leading and trailing white space in each
+line are ignored.
 
+Lines may contain comments.  A comment begins with the ``\texttt{\#}''
+character, and extends to the end of the line.  Empty lines, and lines
+that contain only comments, are ignored.
+
+You will often need to edit the \sfilename{series} file by hand, hence
+the support for comments and empty lines noted above.  For example,
+you can comment out a patch temporarily, and \hgcmd{qpush} will skip
+over that patch when applying patches.  You can also change the order
+in which patches are applied by reordering their entries in the
+\sfilename{series} file.
+
+Placing the \sfilename{series} file under revision control is also
+supported; it is a good idea to place all of the patches that it
+refers to under revision control, as well.  If you create a patch
+directory using the \hgopt{qinit}{-c} option to \hgcmd{qinit}, this
+will be done for you automatically.
 \subsection{The \sfilename{status} file}
 
-
+The \sfilename{status} file contains the names and changeset hashes of
+all patches that MQ currently has applied.  Unlike the
+\sfilename{series} file, this file is not intended for editing.  You
+should not place this file under revision control, or modify it in any
+way.  It is used by MQ strictly for internal book-keeping.
 
 %%% Local Variables: 
 %%% mode: latex
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/en/preface.tex	Tue Jul 11 23:48:25 2006 -0700
@@ -0,0 +1,34 @@
+\chapter*{Preface}
+\addcontentsline{toc}{chapter}{Preface}
+\label{chap:preface}
+
+Distributed revision control is a relatively new territory, and has
+thus far grown due to people's willingness to strike out into
+ill-charted territory.
+
+I am writing a book about distributed revision control because I
+believe that it is an important subject that deserves a field guide.
+I chose to write about Mercurial because it is the easiest tool to
+learn the terrain with, and yet it scales to the demands of real,
+challenging environments where many other revision control tools fail.
+
+\section{This book is a work in progress}
+
+I am releasing this book while I am still writing it, in the hope that
+it will prove useful to others.  I also hope that readers will
+contribute as they see fit.
+
+\section{Colophon---this book is Free}
+
+This book is licensed under the Open Publication License, and is
+produced entirely using Free Software tools.  It is typeset with
+\LaTeX{}; illustrations are drawn and rendered with
+\href{http://www.inkscape.org/}{Inkscape}.
+
+The complete source code for this book is published as a Mercurial
+repository, at \url{http://hg.serpentine.com/mercurial/book}.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "00book"
+%%% End: