
igor@412: \chapter{Colaborar con otros}
igor@402: \label{cha:collab}
igor@402: 
igor@412: Debido a su naturaleza descentralizada, Mercurial no impone política
igor@412: alguna de cómo deben trabajar los grupos de personas. Sin embargo, si
jerojasro@414: usted es nuevo al control distribuido de versiones, es bueno tener
igor@412: herramientas y ejemplos a la mano al pensar en posibles modelos de
igor@412: flujo de trabajo.
igor@412: 
igor@412: \section{La interfaz web de Mercurial}
igor@412: 
igor@412: Mercurial tiene una poderosa interfaz web que provee bastantes
igor@412: capacidades útiles.
igor@412: 
igor@412: Para uso interactivo, la interfaz le permite visualizar uno o varios
igor@412: repositorios. Puede ver la historia de un repositorio, examinar cada
igor@412: cambio(comentarios y diferencias), y ver los contenidos de cada
igor@412: directorio y fichero.
igor@412: 
igor@412: Adicionalmente la interfaz provee feeds de RSS de los cambios de los
igor@412: repositorios. Que le permite ``subscribirse''a un repositorio usando
igor@412: su herramienta de lectura de feeds favorita, y ser notificado
igor@412: automáticamente de la actividad en el repositorio tan pronto como
igor@412: sucede. Me gusta mucho más este modelo que el estar suscrito a una
igor@412: lista de correo a la cual se envían las notificaciones, dado que no
igor@412: requiere configuración adicional de parte de quien sea que está
igor@412: administrando el repositorio.
igor@412: 
igor@412: La interfaz web también permite clonar repositorios a los usuarios
igor@412: remotos, jalar cambios, y (cuando el servidor está configurado para
igor@412: permitirlo) publicar cambios en el mismo.  El protocolo de tunneling
igor@412: de Mercurial comprime datos agresivamente, de forma que trabaja
igor@412: eficientemente incluso con conexiones de red con poco ancho de banda.
igor@412: 
igor@412: La forma más sencilla de iniciarse con la interfaz web es usar su
igor@412: navegador para visitar un repositorio existente, como por ejemplo el
igor@412: repositorio principal de Mercurial \url{http://www.selenic.com/repo/hg?style=gitweb}.
igor@412: 
igor@412: Si está interesado en proveer una interfaz web a sus propios
igor@412: repositorios, Mercurial provee dos formas de hacerlo.  La primera es
igor@412: usando la orden \hgcmd{serve}, que está enfocada a servir ``de forma
igor@412: liviana'' y por intervalos cortos.  Para más detalles de cómo usar
igor@412: esta orden vea la sección~\ref{sec:collab:serve} más adelante. Si
igor@412: tiene un repositorio que desea hacer permanente, Mercurial tiene
igor@412: soporte embebido del \command{ssh} para publicar cambios con seguridad
igor@412: al repositorio central, como se documenta en la
igor@412: sección~\ref{sec:collab:ssh}.  Es muy usual que se publique una copia
igor@412: de sólo lectura en el repositorio que está corriendo sobre HTTP usando
igor@412: CGI, como en la sección~\ref{sec:collab:cgi}.  Publicar sobre HTTP
igor@412: satisface las necesidades de la gente que no tiene permisos de
igor@412: publicación y de aquellos que quieren usar navegadores web para
igor@412: visualizar la historia del repositorio.
igor@412: 
igor@412: \subsection{Trabajo con muchas ramas}
igor@412: 
igor@412: Los proyectos de cierta talla tienden naturlamente a progresar de
igor@412: forma simultánea en varios frentes. En el caso del software, es común
igor@412: que un proyecto tenga versiones periódicas oficiales. Una versión
igor@412: puede entrar a ``modo mantenimiento'' por un tiempo después de su
igor@412: primera publicación; las versiones de mantenimiento tienden a contener
igor@412: solamente arreglos de fallos, pero no nuevas características. En
igor@412: paralelo con las versiones de mantenimiento puede haber una o muchas
igor@412: versiones futuras pueden estar en desarrollo. La gente usa normalmente
igor@412: la palabra ``rama'' para referirse a una de las direcciones
igor@412: ligeramente distintas en las cuales procede el desarrollo.
igor@412: 
igor@412: Mercurial está especialmente preparado para administrar un buen número
igor@412: de ramas simultáneas pero no idénticas. Cada ``dirección de
igor@412: desarrollo'' puede vivir en su propio repositorio central, y puede
igor@412: mezclar los cambios de una a otra de acuerdo con las necesidades. Dado
igor@412: que los repositorios son independientes, uno del otro, los cambios
igor@412: inestables de una rama de desarrollo nunca afectarán una rama estable
igor@412: a menos que alguien explícitamente mezcle los cambios.
igor@412: 
igor@412: A continuación un ejemplo de cómo podría hacerse esto en la
igor@412: práctica. Digamos que tiene una ``rama principal'' en un servidor
igor@412: central.
igor@402: \interaction{branching.init}
igor@412: Alguien lo clona, hace cambios locales, los prueba, y los publica allí
igor@412: mismo.
igor@412: 
igor@412: Una vez que la rama principal alcanza una estado de versión se puede
igor@412: usar la orden \hgcmd{tag} para dar un nombre permanente a la revisión.
igor@402: \interaction{branching.tag}
igor@412: Digamos que en la rama principal ocurre más desarrollo.
igor@402: \interaction{branching.main}
igor@412: Cuando se usa la etiqueta con que se identificó la versión, la gente
igor@412: puede clonar el repositorio en cualquier momento en el futuro
igor@412: empleando \hgcmd{update} para obtener una copia del directorio de
igor@412: trabajo exacta como cuando se creó la etiqueta de la revisión que se
igor@412: consignó.
igor@402: \interaction{branching.update}
igor@402: 
igor@412: Adicionalmente, justo después de que la rama principal se etiquete,
igor@412: alguien puede clonarla en el servidor a una nueva rama ``estable'',
igor@412: también en el servidor.
igor@402: \interaction{branching.clone}
igor@402: 
igor@412: Alguien que requiera hacer un cambio en la rama estable puede clonar
igor@412: \emph{ese} repositorio, hacer sus cambios, consignar y publicarlos
igor@412: posteriormente al inicial.
igor@402: \interaction{branching.stable}
igor@412: Puesto que los repositorios de Mercurial son independientes, y que
igor@412: Mercurial no mueve los cambios de un lado a otro automáticamente, las
igor@412: ramas estable y principal están \emph{aisladas} la una de la otra.
igor@412: Los cambios que haga en la rama principal no ``se filtran'' a la rama
igor@412: estable o vice versa.
igor@412: 
igor@412: Es usual que los arreglos de fallos de la rama estable deban hacerse
igor@412: aparecer en la rama principal también.  En lugar de reescribir el
igor@412: arreglo del fallo en la rama principal, puede jalar y mezclar los
igor@412: cambios de la rama estable a la principal, Mercurial traerá tales
igor@412: arreglos por usted.
igor@402: \interaction{branching.merge}
igor@412: La rama principal contendtrá aún los cambios que no están en la
igor@412: estable y contendrá además todos los arreglos de fallos de la rama
igor@412: estable.  La rama estable permanece incólume a tales cambios.
igor@402: 
igor@417: \subsection{Ramas de Características}
igor@417: 
igor@417: En proyectos grandes, una forma efectiva de administrar los cambios es
igor@417: dividir el equipo en grupos más pequeños. Cada grupo tiene una rama
igor@417: compartida, clonada de una rama ``principal'' que conforma el proyecto
igor@417: completo.   Aquellos que trabajan en ramas individuales típicamente
igor@417: están aislados de los desarrollos de otras ramas.
igor@402: 
igor@402: \begin{figure}[ht]
igor@402:   \centering
igor@402:   \grafix{feature-branches}
igor@417:   \caption{Ramas de Características}
igor@402:   \label{fig:collab:feature-branches}
igor@402: \end{figure}
igor@402: 
igor@417: Cuando una rama particular alcanza un estado deseado, alguien del
igor@417: equipo de características jala y fusiona de la rama principal hacia
igor@417: la rama de características y publica posteriormente a la rama principal.
igor@417: 
igor@417: \subsection{El tren de publicación}
igor@417: 
igor@417: Algunos proyectos se organizan al estilo``tren'': Una versión se
igor@417: planifica para ser liberada cada cierto tiempo, y las características
igor@417: que estén listas cuando ha llegado el momento ``tren'', se incorporan.
igor@417: 
igor@417: Este modelo tiene cierta similitud a las ramas de características. La
igor@417: diferencia es que cuando una característica pierde el tren, alguien en
igor@417: el equipo de características jala y fusiona los cambios que se fueron
igor@417: en la versión liberada hacia la rama de característica, y el trabajo
igor@417: continúa sobre lo fusionado para que la característica logre estar en
igor@417: la próxima versión.
igor@417: 
igor@417: \subsection{El modelo del kernel linux}
igor@417: 
igor@417: El desarrollo del Kernel Linux tiene una estructura jerárquica
igor@417: bastante horizontal, rodeada de una nube de caos aparente. Dado que la
igor@417: mayoría de desarrolladores usan \command{git}, una herramienta distribuida
igor@417: de control de versiones con capacidades similares a Mercurial, resulta
igor@417: de utilidad describir la forma en que el trabajo fluye en tal
igor@417: ambiente; si le gustan las ideas, la aproximación se traduce bien
igor@417: entre Git y Mercurial.
igor@417: 
igor@417: En el centro de la comunidad está Linus Torvalds, el creador de Linux.
igor@417: Él publica un único repositorio que es considerado el árbol
igor@417: ``oficial'' actual por la comunidad completa de
igor@417: desarrolladores. Cualquiera puede clonar el árbol de Linus, pero él es
igor@417: muy selectivo acerca de los árboles de los cuales jala.
igor@417: 
igor@417: Linux tiene varios ``lugartenientes confiables''.  Como regla, él jala
igor@417: todos los cambios que ellos publican, en la mayoría de los casos sin
igor@417: siquiera revisarlos.  Algunos de sus lugartenientes generalmente
igor@417: aceptan ser los ``mantenedores'', responsables de subsistemas
igor@417: específicos dentro del kernel.  Si un hacker cualquiera desea hacer un
igor@417: cambio a un subsistema y busca que termine en el árbol de Linus, debe
igor@417: encontrar quien es el mantenedor del subsistema y solicitarle que
igor@417: tenga en cuenta su cambio.  Si el mantenedor revisa los cambios y está
igor@417: de acuerdo en tomarlos, estos pasarán al árbol de Linus de acuerdo a
igor@417: lo expuesto.
igor@417: 
igor@417: Cada lugarteniente tiene su forma particular de revisar, aceptar y
igor@417: publicar los cambios; y para decidir cuando hacerlos presentes a
igor@417: Linus.  Adicionalmente existen varias ramas conocidas que mucha gente
igor@417: usa para propósitos distintos. Por ejemplo, pocas personas mantienen
igor@417: repositorios ``estables'' de versiones anteriores del kernel, a los
igor@417: cuales aplican arreglos de fallos críticos necesarios. Algunos
igor@417: mantenedores publican varios árboles: uno para cambios
igor@417: experimentales; uno para cambios que van a ofrecer al mantenedor
igor@417: principal; y así sucesivamente. Otros publican un solo árbol.
igor@417: 
igor@417: Este modelo tiene dos características notables. La primera es que son
igor@417: de ``jalar exclusivamente''.  Usted debe solicitar, convencer o
igor@417: incluso rogar a otro desarrollador para que tome sus cabmios, porque
igor@417: casi no hay árboles en los cuales más de una persona pueda publicar, y
igor@417: no hay forma de publicar cambios en un árbol que otra persona controla.
igor@417: 
igor@417: El segundo está basado en reputación y meritocracia.  Si usted es un
igor@417: desconocido, Linus probablemente ignorará sus cambios, sin siquiera
igor@417: responderle.  Pero un mantenedor de un subsistema probablemente los
igor@417: revisara, y los acogerá en caso de que aprueben su criterio de
igor@417: aplicabilidad.  A medida que usted ofrezca ``mejores'' cambios a un
igor@417: mantenedor, habrá más posibilidad de que se confie en su juicio y se
igor@417: acepten los cambios.   Si usted es reconocido y matiene una rama
igor@417: durante bastante tiempo para algo que Linus no ha aceptado, personas
igor@417: con intereses similares pueden jalar sus cambios regularmente para
igor@417: estar al día con su trabajo.
igor@417: 
igor@417: La reputación y meritocracia no necesariamente es transversal entre
igor@417: ``personas'' de diferentes subsistemas.  Si usted es respetado pero es
igor@417: un hacker en almacenamiento y trata de arreglar un fallo de redes,
igor@417: tal cambio puede recibir un nivel de escrutinio de un mantenedor de
igor@417: redes comparable con el que se le haría a un completo extraño.
igor@417: 
igor@417: Personas que vienen de proyectos con un ordenamiento distinto, sienten
igor@417: que el proceso comparativamente caótico del Kernel Linux es
igor@417: completamente lunático.  Es objeto de los caprichos individuales; la
igor@417: gente desecha cambios cuando lo desean; y la fase de desarrollo es
igor@417: alucinante. A pesar de eso Linux es una pieza de software exitosa y
igor@417: bien reconocida.
igor@417: 
igor@417: \subsection{Solamente jalar frente a colaboración pública}
igor@417: 
igor@417: Una fuente perpetua de discusiones en la comunidad de código abierto
igor@417: yace en el modelo de desarrollo en el cual la gente solamente jala
igor@417: cambios de otros ``es mejor que'' uno  en el cual muchas personas
igor@417: pueden publicar cambios a un repositorio compartido.
igor@417: 
igor@417: Tícamente los partidarios del modelo de publicar usan las herramientas
igor@417: que se apegan a este modelo.  Si usted usa una herramienta
igor@417: centralizada de control de versiones como Subversion, no hay forma de
igor@417: elegir qué modelo va a usar: La herramienta le ofrece publicación
igor@417: compartida, y si desea hacer cualquier otra cosa, va a tener que
igor@417: aplicar una aproximación artificial (tal como aplicar parches a mano).
igor@417: 
igor@417: Una buena herramienta distribuida de control de versiones, tal como
igor@417: Mercurial soportará los dos modelos.   Usted y sus colaboradores
igor@417: pueden estructurar cómo trabajarán juntos basados en sus propias
igor@417: necesidades y preferencias,  sin depender de las peripecias que la
igor@417: herramienta les obligue a hacer.
igor@417: 
igor@417: \subsection{Cuando la colaboración encuentra la administración ramificada}
igor@417: 
igor@417: Una vez que usted y su equipo configurar algunos repositorios
igor@417: compartidos y comienzan a propagar cambios entre sus repositorios
igor@417: locales y compartidos, comenzará a encarar un reto relacionado, pero
igor@417: un poco distinto:  Administrar las direcciones en las cuales su equipo
igor@417: puede moverse.   A pesar de que está intimamente ligado acerca de cómo
igor@417: interactúa su equipo, es lo suficientemente denso para ameritar un
igor@417: tratamiento en el capítulo~\ref{chap:branch}.
igor@417: 
igor@417: \section{Aspectos técnicos de la colaboración}
igor@417: 
igor@417: Lo que resta del capítulo lo dedicamos a las cuestiones de servir
igor@417: datos a sus colaboradores.
igor@417: 
igor@417: \section{Compartir informalmente con \hgcmd{serve}}
igor@402: \label{sec:collab:serve}
igor@402: 
igor@417: La orden \hgcmd{serve} de Mercurial satisface de forma espectacular
igor@417: las necesidades de un grupo pequeño, acoplado y de corto
igor@417: tiempo.  Se constituye en una demostración de cómo se siente usar los
igor@417: comandos usando la red.
igor@417: 
igor@417: Ejecute \hgcmd{serve} dentro de un repositorio, y en pocos segundos
igor@417: iniciará un servidor HTTP especializado; aceptará conexiones desde
igor@417: cualquier cliente y servirá datos de este repositorio mientrs lo
igor@417: mantenga funcionando. Todo el que sepa el URL del servidor que ha
igor@417: iniciado, y que puede comunicarse con su computador por la red, puede
igor@417: usar un navegador web o Mercurial para leer datos del repositorio. Un
igor@417: URL para una instancia de \hgcmd{serve} ejecutándose en un portátil
igor@417: debería lucir algo \Verb|http://my-laptop.local:8000/|.
igor@417: 
igor@417: La orden \hgcmd{serve} \emph{no} es un servidor web de propósito
igor@417: general. Solamente puede hacer dos cosas:
igor@402: \begin{itemize}
igor@417: \item Permitir que se pueda visualizar la historia del repositorio que
igor@417:   está sirviendo desde navegadores web.
igor@417: \item Hablar el protocolo de conexión de Mercurial para que puedan hacer
igor@417:   \hgcmd{clone} o \hgcmd{pull} (jalar) cambios de tal repositorio.
igor@402: \end{itemize}
igor@417: En particular, \hgcmd{serve} no permitirá que los usuarios remotos
igor@417: puedan \emph{modificar} su repositorio.  Es de tipo solo lectura.
igor@417: 
igor@417: Si está comenzando con Mercurial, no hay nada que le impida usar
igor@417: \hgcmd{serve} para servir un repositorio en su propio computador, y
igor@417: usar posteriormente órdenes como \hgcmd{clone}, \hgcmd{incoming}, para
igor@417: comunicarse con el servidor como si el repositorio estuviera alojado
igor@417: remotamente. Lo que además puede ayudarle a adecuarse rápidamente para
igor@417: usar comandos en repositorios alojados en la red.
igor@417: 
igor@417: \subsection{Cuestiones adicionales para tener en cuenta}
igor@417: 
igor@417: Dado que permite lectura sin autenticación a todos sus clientes,
igor@417: debería usar \hgcmd{serve} exclusivamente en ambientes en los cuáles
igor@417: no tenga problema en que otros vean, o en los cuales tenga control
igor@417: completo acerca de quien puede acceder a su red y jalar cambios de su
igor@417: repositorio.
igor@417: 
igor@417: La orden \hgcmd{serve} no tiene conocimiento acerca de programas
igor@417: cortafuegos que puedan estar instalados en su sistema o en su red. No
igor@417: puede detectar o controlar sus cortafuegos.  Si otras personas no
igor@417: pueden acceder a su instancia \hgcmd{serve}, lo siguiente que debería hacer
igor@417: (\emph{después} de asegurarse que tienen el URL correcto) es verificar
igor@417: su configuración de cortafuegos.
igor@417: 
igor@417: De forma predeterminada, \hgcmd{serve} escucha conexiones entrantes en
igor@417: el puerto~8000.  Si otro proceso está escuchando en tal puerto, usted
igor@417: podrá especificar un puerto distinto para escuchar con la opción
igor@417: \hgopt{serve}{-p} .
igor@417: 
igor@417: Normalmente, cuando se inicia \hgcmd{serve}, no imprime nada, lo cual
igor@417: puede ser desconcertante.  Si desea confirmar que en efecto está
igor@417: ejecutándose correctamente, y darse cuenta qué URL debería enviar a
igor@417: sus colaboradores, inícielo con la opción \hggopt{-v}.
igor@402: 
igor@402: \section{Using the Secure Shell (ssh) protocol}
igor@402: \label{sec:collab:ssh}
igor@402: 
igor@402: You can pull and push changes securely over a network connection using
igor@402: the Secure Shell (\texttt{ssh}) protocol.  To use this successfully,
igor@402: you may have to do a little bit of configuration on the client or
igor@402: server sides.
igor@402: 
igor@402: If you're not familiar with ssh, it's a network protocol that lets you
igor@402: securely communicate with another computer.  To use it with Mercurial,
igor@402: you'll be setting up one or more user accounts on a server so that
igor@402: remote users can log in and execute commands.
igor@402: 
igor@402: (If you \emph{are} familiar with ssh, you'll probably find some of the
igor@402: material that follows to be elementary in nature.)
igor@402: 
igor@402: \subsection{How to read and write ssh URLs}
igor@402: 
igor@402: An ssh URL tends to look like this:
igor@402: \begin{codesample2}
igor@402:   ssh://bos@hg.serpentine.com:22/hg/hgbook
igor@402: \end{codesample2}
igor@402: \begin{enumerate}
igor@402: \item The ``\texttt{ssh://}'' part tells Mercurial to use the ssh
igor@402:   protocol.
igor@402: \item The ``\texttt{bos@}'' component indicates what username to log
igor@402:   into the server as.  You can leave this out if the remote username
igor@402:   is the same as your local username.
igor@402: \item The ``\texttt{hg.serpentine.com}'' gives the hostname of the
igor@402:   server to log into.
igor@402: \item The ``:22'' identifies the port number to connect to the server
igor@402:   on.  The default port is~22, so you only need to specify this part
igor@402:   if you're \emph{not} using port~22.
igor@402: \item The remainder of the URL is the local path to the repository on
igor@402:   the server.
igor@402: \end{enumerate}
igor@402: 
igor@402: There's plenty of scope for confusion with the path component of ssh
igor@402: URLs, as there is no standard way for tools to interpret it.  Some
igor@402: programs behave differently than others when dealing with these paths.
igor@402: This isn't an ideal situation, but it's unlikely to change.  Please
igor@402: read the following paragraphs carefully.
igor@402: 
igor@402: Mercurial treats the path to a repository on the server as relative to
igor@402: the remote user's home directory.  For example, if user \texttt{foo}
igor@402: on the server has a home directory of \dirname{/home/foo}, then an ssh
igor@402: URL that contains a path component of \dirname{bar}
igor@402: \emph{really} refers to the directory \dirname{/home/foo/bar}.
igor@402: 
igor@402: If you want to specify a path relative to another user's home
igor@402: directory, you can use a path that starts with a tilde character
igor@402: followed by the user's name (let's call them \texttt{otheruser}), like
igor@402: this.
igor@402: \begin{codesample2}
igor@402:   ssh://server/~otheruser/hg/repo
igor@402: \end{codesample2}
igor@402: 
igor@402: And if you really want to specify an \emph{absolute} path on the
igor@402: server, begin the path component with two slashes, as in this example.
igor@402: \begin{codesample2}
igor@402:   ssh://server//absolute/path
igor@402: \end{codesample2}
igor@402: 
igor@402: \subsection{Finding an ssh client for your system}
igor@402: 
igor@402: Almost every Unix-like system comes with OpenSSH preinstalled.  If
igor@402: you're using such a system, run \Verb|which ssh| to find out if
igor@402: the \command{ssh} command is installed (it's usually in
igor@402: \dirname{/usr/bin}).  In the unlikely event that it isn't present,
igor@402: take a look at your system documentation to figure out how to install
igor@402: it.
igor@402: 
igor@402: On Windows, you'll first need to choose download a suitable ssh
igor@402: client.  There are two alternatives.
igor@402: \begin{itemize}
igor@402: \item Simon Tatham's excellent PuTTY package~\cite{web:putty} provides
igor@402:   a complete suite of ssh client commands.
igor@402: \item If you have a high tolerance for pain, you can use the Cygwin
igor@402:   port of OpenSSH.
igor@402: \end{itemize}
igor@402: In either case, you'll need to edit your \hgini\ file to tell
igor@402: Mercurial where to find the actual client command.  For example, if
igor@402: you're using PuTTY, you'll need to use the \command{plink} command as
igor@402: a command-line ssh client.
igor@402: \begin{codesample2}
igor@402:   [ui]
igor@402:   ssh = C:/path/to/plink.exe -ssh -i "C:/path/to/my/private/key"
igor@402: \end{codesample2}
igor@402: 
igor@402: \begin{note}
igor@402:   The path to \command{plink} shouldn't contain any whitespace
igor@402:   characters, or Mercurial may not be able to run it correctly (so
igor@402:   putting it in \dirname{C:\\Program Files} is probably not a good
igor@402:   idea).
igor@402: \end{note}
igor@402: 
igor@402: \subsection{Generating a key pair}
igor@402: 
igor@402: To avoid the need to repetitively type a password every time you need
igor@402: to use your ssh client, I recommend generating a key pair.  On a
igor@402: Unix-like system, the \command{ssh-keygen} command will do the trick.
igor@402: On Windows, if you're using PuTTY, the \command{puttygen} command is
igor@402: what you'll need.
igor@402: 
igor@402: When you generate a key pair, it's usually \emph{highly} advisable to
igor@402: protect it with a passphrase.  (The only time that you might not want
igor@402: to do this id when you're using the ssh protocol for automated tasks
igor@402: on a secure network.)
igor@402: 
igor@402: Simply generating a key pair isn't enough, however.  You'll need to
igor@402: add the public key to the set of authorised keys for whatever user
igor@402: you're logging in remotely as.  For servers using OpenSSH (the vast
igor@402: majority), this will mean adding the public key to a list in a file
igor@402: called \sfilename{authorized\_keys} in their \sdirname{.ssh}
igor@402: directory.
igor@402: 
igor@402: On a Unix-like system, your public key will have a \filename{.pub}
igor@402: extension.  If you're using \command{puttygen} on Windows, you can
igor@402: save the public key to a file of your choosing, or paste it from the
igor@402: window it's displayed in straight into the
igor@402: \sfilename{authorized\_keys} file.
igor@402: 
igor@402: \subsection{Using an authentication agent}
igor@402: 
igor@402: An authentication agent is a daemon that stores passphrases in memory
igor@402: (so it will forget passphrases if you log out and log back in again).
igor@402: An ssh client will notice if it's running, and query it for a
igor@402: passphrase.  If there's no authentication agent running, or the agent
igor@402: doesn't store the necessary passphrase, you'll have to type your
igor@402: passphrase every time Mercurial tries to communicate with a server on
igor@402: your behalf (e.g.~whenever you pull or push changes).
igor@402: 
igor@402: The downside of storing passphrases in an agent is that it's possible
igor@402: for a well-prepared attacker to recover the plain text of your
igor@402: passphrases, in some cases even if your system has been power-cycled.
igor@402: You should make your own judgment as to whether this is an acceptable
igor@402: risk.  It certainly saves a lot of repeated typing.
igor@402: 
igor@402: On Unix-like systems, the agent is called \command{ssh-agent}, and
igor@402: it's often run automatically for you when you log in.  You'll need to
igor@402: use the \command{ssh-add} command to add passphrases to the agent's
igor@402: store.  On Windows, if you're using PuTTY, the \command{pageant}
igor@402: command acts as the agent.  It adds an icon to your system tray that
igor@402: will let you manage stored passphrases.
igor@402: 
igor@402: \subsection{Configuring the server side properly}
igor@402: 
igor@402: Because ssh can be fiddly to set up if you're new to it, there's a
igor@402: variety of things that can go wrong.  Add Mercurial on top, and
igor@402: there's plenty more scope for head-scratching.  Most of these
igor@402: potential problems occur on the server side, not the client side.  The
igor@402: good news is that once you've gotten a configuration working, it will
igor@402: usually continue to work indefinitely.
igor@402: 
igor@402: Before you try using Mercurial to talk to an ssh server, it's best to
igor@402: make sure that you can use the normal \command{ssh} or \command{putty}
igor@402: command to talk to the server first.  If you run into problems with
igor@402: using these commands directly, Mercurial surely won't work.  Worse, it
igor@402: will obscure the underlying problem.  Any time you want to debug
igor@402: ssh-related Mercurial problems, you should drop back to making sure
igor@402: that plain ssh client commands work first, \emph{before} you worry
igor@402: about whether there's a problem with Mercurial.
igor@402: 
igor@402: The first thing to be sure of on the server side is that you can
igor@402: actually log in from another machine at all.  If you can't use
igor@402: \command{ssh} or \command{putty} to log in, the error message you get
igor@402: may give you a few hints as to what's wrong.  The most common problems
igor@402: are as follows.
igor@402: \begin{itemize}
igor@402: \item If you get a ``connection refused'' error, either there isn't an
igor@402:   SSH daemon running on the server at all, or it's inaccessible due to
igor@402:   firewall configuration.
igor@402: \item If you get a ``no route to host'' error, you either have an
igor@402:   incorrect address for the server or a seriously locked down firewall
igor@402:   that won't admit its existence at all.
igor@402: \item If you get a ``permission denied'' error, you may have mistyped
igor@402:   the username on the server, or you could have mistyped your key's
igor@402:   passphrase or the remote user's password.
igor@402: \end{itemize}
igor@402: In summary, if you're having trouble talking to the server's ssh
igor@402: daemon, first make sure that one is running at all.  On many systems
igor@402: it will be installed, but disabled, by default.  Once you're done with
igor@402: this step, you should then check that the server's firewall is
igor@402: configured to allow incoming connections on the port the ssh daemon is
igor@402: listening on (usually~22).  Don't worry about more exotic
igor@402: possibilities for misconfiguration until you've checked these two
igor@402: first.
igor@402: 
igor@402: If you're using an authentication agent on the client side to store
igor@402: passphrases for your keys, you ought to be able to log into the server
igor@402: without being prompted for a passphrase or a password.  If you're
igor@402: prompted for a passphrase, there are a few possible culprits.
igor@402: \begin{itemize}
igor@402: \item You might have forgotten to use \command{ssh-add} or
igor@402:   \command{pageant} to store the passphrase.
igor@402: \item You might have stored the passphrase for the wrong key.
igor@402: \end{itemize}
igor@402: If you're being prompted for the remote user's password, there are
igor@402: another few possible problems to check.
igor@402: \begin{itemize}
igor@402: \item Either the user's home directory or their \sdirname{.ssh}
igor@402:   directory might have excessively liberal permissions.  As a result,
igor@402:   the ssh daemon will not trust or read their
igor@402:   \sfilename{authorized\_keys} file.  For example, a group-writable
igor@402:   home or \sdirname{.ssh} directory will often cause this symptom.
igor@402: \item The user's \sfilename{authorized\_keys} file may have a problem.
igor@402:   If anyone other than the user owns or can write to that file, the
igor@402:   ssh daemon will not trust or read it.
igor@402: \end{itemize}
igor@402: 
igor@402: In the ideal world, you should be able to run the following command
igor@402: successfully, and it should print exactly one line of output, the
igor@402: current date and time.
igor@402: \begin{codesample2}
igor@402:   ssh myserver date
igor@402: \end{codesample2}
igor@402: 
igor@402: If, on your server, you have login scripts that print banners or other
igor@402: junk even when running non-interactive commands like this, you should
igor@402: fix them before you continue, so that they only print output if
igor@402: they're run interactively.  Otherwise these banners will at least
igor@402: clutter up Mercurial's output.  Worse, they could potentially cause
igor@402: problems with running Mercurial commands remotely.  Mercurial makes
igor@402: tries to detect and ignore banners in non-interactive \command{ssh}
igor@402: sessions, but it is not foolproof.  (If you're editing your login
igor@402: scripts on your server, the usual way to see if a login script is
igor@402: running in an interactive shell is to check the return code from the
igor@402: command \Verb|tty -s|.)
igor@402: 
igor@402: Once you've verified that plain old ssh is working with your server,
igor@402: the next step is to ensure that Mercurial runs on the server.  The
igor@402: following command should run successfully:
igor@402: \begin{codesample2}
igor@402:   ssh myserver hg version
igor@402: \end{codesample2}
igor@402: If you see an error message instead of normal \hgcmd{version} output,
igor@402: this is usually because you haven't installed Mercurial to
igor@402: \dirname{/usr/bin}.  Don't worry if this is the case; you don't need
igor@402: to do that.  But you should check for a few possible problems.
igor@402: \begin{itemize}
igor@402: \item Is Mercurial really installed on the server at all?  I know this
igor@402:   sounds trivial, but it's worth checking!
igor@402: \item Maybe your shell's search path (usually set via the \envar{PATH}
igor@402:   environment variable) is simply misconfigured.
igor@402: \item Perhaps your \envar{PATH} environment variable is only being set
igor@402:   to point to the location of the \command{hg} executable if the login
igor@402:   session is interactive.  This can happen if you're setting the path
igor@402:   in the wrong shell login script.  See your shell's documentation for
igor@402:   details.
igor@402: \item The \envar{PYTHONPATH} environment variable may need to contain
igor@402:   the path to the Mercurial Python modules.  It might not be set at
igor@402:   all; it could be incorrect; or it may be set only if the login is
igor@402:   interactive.
igor@402: \end{itemize}
igor@402: 
igor@402: If you can run \hgcmd{version} over an ssh connection, well done!
igor@402: You've got the server and client sorted out.  You should now be able
igor@402: to use Mercurial to access repositories hosted by that username on
igor@402: that server.  If you run into problems with Mercurial and ssh at this
igor@402: point, try using the \hggopt{--debug} option to get a clearer picture
igor@402: of what's going on.
igor@402: 
igor@402: \subsection{Using compression with ssh}
igor@402: 
igor@402: Mercurial does not compress data when it uses the ssh protocol,
igor@402: because the ssh protocol can transparently compress data.  However,
igor@402: the default behaviour of ssh clients is \emph{not} to request
igor@402: compression.
igor@402: 
igor@402: Over any network other than a fast LAN (even a wireless network),
igor@402: using compression is likely to significantly speed up Mercurial's
igor@402: network operations.  For example, over a WAN, someone measured
igor@402: compression as reducing the amount of time required to clone a
igor@402: particularly large repository from~51 minutes to~17 minutes.
igor@402: 
igor@402: Both \command{ssh} and \command{plink} accept a \cmdopt{ssh}{-C}
igor@402: option which turns on compression.  You can easily edit your \hgrc\ to
igor@402: enable compression for all of Mercurial's uses of the ssh protocol.
igor@402: \begin{codesample2}
igor@402:   [ui]
igor@402:   ssh = ssh -C
igor@402: \end{codesample2}
igor@402: 
igor@402: If you use \command{ssh}, you can configure it to always use
igor@402: compression when talking to your server.  To do this, edit your
igor@402: \sfilename{.ssh/config} file (which may not yet exist), as follows.
igor@402: \begin{codesample2}
igor@402:   Host hg
igor@402:     Compression yes
igor@402:     HostName hg.example.com
igor@402: \end{codesample2}
igor@402: This defines an alias, \texttt{hg}.  When you use it on the
igor@402: \command{ssh} command line or in a Mercurial \texttt{ssh}-protocol
igor@402: URL, it will cause \command{ssh} to connect to \texttt{hg.example.com}
igor@402: and use compression.  This gives you both a shorter name to type and
igor@402: compression, each of which is a good thing in its own right.
igor@402: 
igor@402: \section{Serving over HTTP using CGI}
igor@402: \label{sec:collab:cgi}
igor@402: 
igor@402: Depending on how ambitious you are, configuring Mercurial's CGI
igor@402: interface can take anything from a few moments to several hours.
igor@402: 
igor@402: We'll begin with the simplest of examples, and work our way towards a
igor@402: more complex configuration.  Even for the most basic case, you're
igor@402: almost certainly going to need to read and modify your web server's
igor@402: configuration.
igor@402: 
igor@402: \begin{note}
igor@402:   Configuring a web server is a complex, fiddly, and highly
igor@402:   system-dependent activity.  I can't possibly give you instructions
igor@402:   that will cover anything like all of the cases you will encounter.
igor@402:   Please use your discretion and judgment in following the sections
igor@402:   below.  Be prepared to make plenty of mistakes, and to spend a lot
igor@402:   of time reading your server's error logs.
igor@402: \end{note}
igor@402: 
igor@402: \subsection{Web server configuration checklist}
igor@402: 
igor@402: Before you continue, do take a few moments to check a few aspects of
igor@402: your system's setup.
igor@402: 
igor@402: \begin{enumerate}
igor@402: \item Do you have a web server installed at all?  Mac OS X ships with
igor@402:   Apache, but many other systems may not have a web server installed.
igor@402: \item If you have a web server installed, is it actually running?  On
igor@402:   most systems, even if one is present, it will be disabled by
igor@402:   default.
igor@402: \item Is your server configured to allow you to run CGI programs in
igor@402:   the directory where you plan to do so?  Most servers default to
igor@402:   explicitly disabling the ability to run CGI programs.
igor@402: \end{enumerate}
igor@402: 
igor@402: If you don't have a web server installed, and don't have substantial
igor@402: experience configuring Apache, you should consider using the
igor@402: \texttt{lighttpd} web server instead of Apache.  Apache has a
igor@402: well-deserved reputation for baroque and confusing configuration.
igor@402: While \texttt{lighttpd} is less capable in some ways than Apache, most
igor@402: of these capabilities are not relevant to serving Mercurial
igor@402: repositories.  And \texttt{lighttpd} is undeniably \emph{much} easier
igor@402: to get started with than Apache.
igor@402: 
igor@402: \subsection{Basic CGI configuration}
igor@402: 
igor@402: On Unix-like systems, it's common for users to have a subdirectory
igor@402: named something like \dirname{public\_html} in their home directory,
igor@402: from which they can serve up web pages.  A file named \filename{foo}
igor@402: in this directory will be accessible at a URL of the form
igor@402: \texttt{http://www.example.com/\~username/foo}.
igor@402: 
igor@402: To get started, find the \sfilename{hgweb.cgi} script that should be
igor@402: present in your Mercurial installation.  If you can't quickly find a
igor@402: local copy on your system, simply download one from the master
igor@402: Mercurial repository at
igor@402: \url{http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi}.
igor@402: 
igor@402: You'll need to copy this script into your \dirname{public\_html}
igor@402: directory, and ensure that it's executable.
igor@402: \begin{codesample2}
igor@402:   cp .../hgweb.cgi ~/public_html
igor@402:   chmod 755 ~/public_html/hgweb.cgi
igor@402: \end{codesample2}
igor@402: The \texttt{755} argument to \command{chmod} is a little more general
igor@402: than just making the script executable: it ensures that the script is
igor@402: executable by anyone, and that ``group'' and ``other'' write
igor@402: permissions are \emph{not} set.  If you were to leave those write
igor@402: permissions enabled, Apache's \texttt{suexec} subsystem would likely
igor@402: refuse to execute the script.  In fact, \texttt{suexec} also insists
igor@402: that the \emph{directory} in which the script resides must not be
igor@402: writable by others.
igor@402: \begin{codesample2}
igor@402:   chmod 755 ~/public_html
igor@402: \end{codesample2}
igor@402: 
igor@402: \subsubsection{What could \emph{possibly} go wrong?}
igor@402: \label{sec:collab:wtf}
igor@402: 
igor@402: Once you've copied the CGI script into place, go into a web browser,
igor@402: and try to open the URL \url{http://myhostname/~myuser/hgweb.cgi},
igor@402: \emph{but} brace yourself for instant failure.  There's a high
igor@402: probability that trying to visit this URL will fail, and there are
igor@402: many possible reasons for this.  In fact, you're likely to stumble
igor@402: over almost every one of the possible errors below, so please read
igor@402: carefully.  The following are all of the problems I ran into on a
igor@402: system running Fedora~7, with a fresh installation of Apache, and a
igor@402: user account that I created specially to perform this exercise.
igor@402: 
igor@402: Your web server may have per-user directories disabled.  If you're
igor@402: using Apache, search your config file for a \texttt{UserDir}
igor@402: directive.  If there's none present, per-user directories will be
igor@402: disabled.  If one exists, but its value is \texttt{disabled}, then
igor@402: per-user directories will be disabled.  Otherwise, the string after
igor@402: \texttt{UserDir} gives the name of the subdirectory that Apache will
igor@402: look in under your home directory, for example \dirname{public\_html}.
igor@402: 
igor@402: Your file access permissions may be too restrictive.  The web server
igor@402: must be able to traverse your home directory and directories under
igor@402: your \dirname{public\_html} directory, and read files under the latter
igor@402: too.  Here's a quick recipe to help you to make your permissions more
igor@402: appropriate.
igor@402: \begin{codesample2}
igor@402:   chmod 755 ~
igor@402:   find ~/public_html -type d -print0 | xargs -0r chmod 755
igor@402:   find ~/public_html -type f -print0 | xargs -0r chmod 644
igor@402: \end{codesample2}
igor@402: 
igor@402: The other possibility with permissions is that you might get a
igor@402: completely empty window when you try to load the script.  In this
igor@402: case, it's likely that your access permissions are \emph{too
igor@402:   permissive}.  Apache's \texttt{suexec} subsystem won't execute a
igor@402: script that's group-~or world-writable, for example.
igor@402: 
igor@402: Your web server may be configured to disallow execution of CGI
igor@402: programs in your per-user web directory.  Here's Apache's
igor@402: default per-user configuration from my Fedora system.
igor@402: \begin{codesample2}
igor@402:   <Directory /home/*/public_html>
igor@402:       AllowOverride FileInfo AuthConfig Limit
igor@402:       Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
igor@402:       <Limit GET POST OPTIONS>
igor@402:           Order allow,deny
igor@402:           Allow from all
igor@402:       </Limit>
igor@402:       <LimitExcept GET POST OPTIONS>
igor@402:           Order deny,allow
igor@402:           Deny from all
igor@402:       </LimitExcept>
igor@402:   </Directory>
igor@402: \end{codesample2}
igor@402: If you find a similar-looking \texttt{Directory} group in your Apache
igor@402: configuration, the directive to look at inside it is \texttt{Options}.
igor@402: Add \texttt{ExecCGI} to the end of this list if it's missing, and
igor@402: restart the web server.
igor@402: 
igor@402: If you find that Apache serves you the text of the CGI script instead
igor@402: of executing it, you may need to either uncomment (if already present)
igor@402: or add a directive like this.
igor@402: \begin{codesample2}
igor@402:   AddHandler cgi-script .cgi
igor@402: \end{codesample2}
igor@402: 
igor@402: The next possibility is that you might be served with a colourful
igor@402: Python backtrace claiming that it can't import a
igor@402: \texttt{mercurial}-related module.  This is actually progress!  The
igor@402: server is now capable of executing your CGI script.  This error is
igor@402: only likely to occur if you're running a private installation of
igor@402: Mercurial, instead of a system-wide version.  Remember that the web
igor@402: server runs the CGI program without any of the environment variables
igor@402: that you take for granted in an interactive session.  If this error
igor@402: happens to you, edit your copy of \sfilename{hgweb.cgi} and follow the
igor@402: directions inside it to correctly set your \envar{PYTHONPATH}
igor@402: environment variable.
igor@402: 
igor@402: Finally, you are \emph{certain} to by served with another colourful
igor@402: Python backtrace: this one will complain that it can't find
igor@402: \dirname{/path/to/repository}.  Edit your \sfilename{hgweb.cgi} script
igor@402: and replace the \dirname{/path/to/repository} string with the complete
igor@402: path to the repository you want to serve up.
igor@402: 
igor@402: At this point, when you try to reload the page, you should be
igor@402: presented with a nice HTML view of your repository's history.  Whew!
igor@402: 
igor@402: \subsubsection{Configuring lighttpd}
igor@402: 
igor@402: To be exhaustive in my experiments, I tried configuring the
igor@402: increasingly popular \texttt{lighttpd} web server to serve the same
igor@402: repository as I described with Apache above.  I had already overcome
igor@402: all of the problems I outlined with Apache, many of which are not
igor@402: server-specific.  As a result, I was fairly sure that my file and
igor@402: directory permissions were good, and that my \sfilename{hgweb.cgi}
igor@402: script was properly edited.
igor@402: 
igor@402: Once I had Apache running, getting \texttt{lighttpd} to serve the
igor@402: repository was a snap (in other words, even if you're trying to use
igor@402: \texttt{lighttpd}, you should read the Apache section).  I first had
igor@402: to edit the \texttt{mod\_access} section of its config file to enable
igor@402: \texttt{mod\_cgi} and \texttt{mod\_userdir}, both of which were
igor@402: disabled by default on my system.  I then added a few lines to the end
igor@402: of the config file, to configure these modules.
igor@402: \begin{codesample2}
igor@402:   userdir.path = "public_html"
igor@402:   cgi.assign = ( ".cgi" => "" )
igor@402: \end{codesample2}
igor@402: With this done, \texttt{lighttpd} ran immediately for me.  If I had
igor@402: configured \texttt{lighttpd} before Apache, I'd almost certainly have
igor@402: run into many of the same system-level configuration problems as I did
igor@402: with Apache.  However, I found \texttt{lighttpd} to be noticeably
igor@402: easier to configure than Apache, even though I've used Apache for over
igor@402: a decade, and this was my first exposure to \texttt{lighttpd}.
igor@402: 
igor@402: \subsection{Sharing multiple repositories with one CGI script}
igor@402: 
igor@402: The \sfilename{hgweb.cgi} script only lets you publish a single
igor@402: repository, which is an annoying restriction.  If you want to publish
igor@402: more than one without wracking yourself with multiple copies of the
igor@402: same script, each with different names, a better choice is to use the
igor@402: \sfilename{hgwebdir.cgi} script.
igor@402: 
igor@402: The procedure to configure \sfilename{hgwebdir.cgi} is only a little
igor@402: more involved than for \sfilename{hgweb.cgi}.  First, you must obtain
igor@402: a copy of the script.  If you don't have one handy, you can download a
igor@402: copy from the master Mercurial repository at
igor@402: \url{http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi}.
igor@402: 
igor@402: You'll need to copy this script into your \dirname{public\_html}
igor@402: directory, and ensure that it's executable.
igor@402: \begin{codesample2}
igor@402:   cp .../hgwebdir.cgi ~/public_html
igor@402:   chmod 755 ~/public_html ~/public_html/hgwebdir.cgi
igor@402: \end{codesample2}
igor@402: With basic configuration out of the way, try to visit
igor@402: \url{http://myhostname/~myuser/hgwebdir.cgi} in your browser.  It
igor@402: should display an empty list of repositories.  If you get a blank
igor@402: window or error message, try walking through the list of potential
igor@402: problems in section~\ref{sec:collab:wtf}.
igor@402: 
igor@402: The \sfilename{hgwebdir.cgi} script relies on an external
igor@402: configuration file.  By default, it searches for a file named
igor@402: \sfilename{hgweb.config} in the same directory as itself.  You'll need
igor@402: to create this file, and make it world-readable.  The format of the
igor@402: file is similar to a Windows ``ini'' file, as understood by Python's
igor@402: \texttt{ConfigParser}~\cite{web:configparser} module.
igor@402: 
igor@402: The easiest way to configure \sfilename{hgwebdir.cgi} is with a
igor@402: section named \texttt{collections}.  This will automatically publish
igor@402: \emph{every} repository under the directories you name.  The section
igor@402: should look like this:
igor@402: \begin{codesample2}
igor@402:   [collections]
igor@402:   /my/root = /my/root
igor@402: \end{codesample2}
igor@402: Mercurial interprets this by looking at the directory name on the
igor@402: \emph{right} hand side of the ``\texttt{=}'' sign; finding
igor@402: repositories in that directory hierarchy; and using the text on the
igor@402: \emph{left} to strip off matching text from the names it will actually
igor@402: list in the web interface.  The remaining component of a path after
igor@402: this stripping has occurred is called a ``virtual path''.
igor@402: 
igor@402: Given the example above, if we have a repository whose local path is
igor@402: \dirname{/my/root/this/repo}, the CGI script will strip the leading
igor@402: \dirname{/my/root} from the name, and publish the repository with a
igor@402: virtual path of \dirname{this/repo}.  If the base URL for our CGI
igor@402: script is \url{http://myhostname/~myuser/hgwebdir.cgi}, the complete
igor@402: URL for that repository will be
igor@402: \url{http://myhostname/~myuser/hgwebdir.cgi/this/repo}.
igor@402: 
igor@402: If we replace \dirname{/my/root} on the left hand side of this example
igor@402: with \dirname{/my}, then \sfilename{hgwebdir.cgi} will only strip off
igor@402: \dirname{/my} from the repository name, and will give us a virtual
igor@402: path of \dirname{root/this/repo} instead of \dirname{this/repo}.
igor@402: 
igor@402: The \sfilename{hgwebdir.cgi} script will recursively search each
igor@402: directory listed in the \texttt{collections} section of its
igor@402: configuration file, but it will \texttt{not} recurse into the
igor@402: repositories it finds.
igor@402: 
igor@402: The \texttt{collections} mechanism makes it easy to publish many
igor@402: repositories in a ``fire and forget'' manner.  You only need to set up
igor@402: the CGI script and configuration file one time.  Afterwards, you can
igor@402: publish or unpublish a repository at any time by simply moving it
igor@402: into, or out of, the directory hierarchy in which you've configured
igor@402: \sfilename{hgwebdir.cgi} to look.
igor@402: 
igor@402: \subsubsection{Explicitly specifying which repositories to publish}
igor@402: 
igor@402: In addition to the \texttt{collections} mechanism, the
igor@402: \sfilename{hgwebdir.cgi} script allows you to publish a specific list
igor@402: of repositories.  To do so, create a \texttt{paths} section, with
igor@402: contents of the following form.
igor@402: \begin{codesample2}
igor@402:   [paths]
igor@402:   repo1 = /my/path/to/some/repo
igor@402:   repo2 = /some/path/to/another
igor@402: \end{codesample2}
igor@402: In this case, the virtual path (the component that will appear in a
igor@402: URL) is on the left hand side of each definition, while the path to
igor@402: the repository is on the right.  Notice that there does not need to be
igor@402: any relationship between the virtual path you choose and the location
igor@402: of a repository in your filesystem.
igor@402: 
igor@402: If you wish, you can use both the \texttt{collections} and
igor@402: \texttt{paths} mechanisms simultaneously in a single configuration
igor@402: file.
igor@402: 
igor@402: \begin{note}
igor@402:   If multiple repositories have the same virtual path,
igor@402:   \sfilename{hgwebdir.cgi} will not report an error.  Instead, it will
igor@402:   behave unpredictably.
igor@402: \end{note}
igor@402: 
igor@402: \subsection{Downloading source archives}
igor@402: 
igor@402: Mercurial's web interface lets users download an archive of any
igor@402: revision.  This archive will contain a snapshot of the working
igor@402: directory as of that revision, but it will not contain a copy of the
igor@402: repository data.
igor@402: 
igor@402: By default, this feature is not enabled.  To enable it, you'll need to
igor@402: add an \rcitem{web}{allow\_archive} item to the \rcsection{web}
igor@402: section of your \hgrc.
igor@402: 
igor@402: \subsection{Web configuration options}
igor@402: 
igor@402: Mercurial's web interfaces (the \hgcmd{serve} command, and the
igor@402: \sfilename{hgweb.cgi} and \sfilename{hgwebdir.cgi} scripts) have a
igor@402: number of configuration options that you can set.  These belong in a
igor@402: section named \rcsection{web}.
igor@402: \begin{itemize}
igor@402: \item[\rcitem{web}{allow\_archive}] Determines which (if any) archive
igor@402:   download mechanisms Mercurial supports.  If you enable this
igor@402:   feature, users of the web interface will be able to download an
igor@402:   archive of whatever revision of a repository they are viewing.
igor@402:   To enable the archive feature, this item must take the form of a
igor@402:   sequence of words drawn from the list below.
igor@402:   \begin{itemize}
igor@402:   \item[\texttt{bz2}] A \command{tar} archive, compressed using
igor@402:     \texttt{bzip2} compression.  This has the best compression ratio,
igor@402:     but uses the most CPU time on the server.
igor@402:   \item[\texttt{gz}] A \command{tar} archive, compressed using
igor@402:     \texttt{gzip} compression.
igor@402:   \item[\texttt{zip}] A \command{zip} archive, compressed using LZW
igor@402:     compression.  This format has the worst compression ratio, but is
igor@402:     widely used in the Windows world.
igor@402:   \end{itemize}
igor@402:   If you provide an empty list, or don't have an
igor@402:   \rcitem{web}{allow\_archive} entry at all, this feature will be
igor@402:   disabled.  Here is an example of how to enable all three supported
igor@402:   formats.
igor@402:   \begin{codesample4}
igor@402:     [web]
igor@402:     allow_archive = bz2 gz zip
igor@402:   \end{codesample4}
igor@402: \item[\rcitem{web}{allowpull}] Boolean.  Determines whether the web
igor@402:   interface allows remote users to \hgcmd{pull} and \hgcmd{clone} this
igor@402:   repository over~HTTP.  If set to \texttt{no} or \texttt{false}, only
igor@402:   the ``human-oriented'' portion of the web interface is available.
igor@402: \item[\rcitem{web}{contact}] String.  A free-form (but preferably
igor@402:   brief) string identifying the person or group in charge of the
igor@402:   repository.  This often contains the name and email address of a
igor@402:   person or mailing list.  It often makes sense to place this entry in
igor@402:   a repository's own \sfilename{.hg/hgrc} file, but it can make sense
igor@402:   to use in a global \hgrc\ if every repository has a single
igor@402:   maintainer.
igor@402: \item[\rcitem{web}{maxchanges}] Integer.  The default maximum number
igor@402:   of changesets to display in a single page of output.
igor@402: \item[\rcitem{web}{maxfiles}] Integer.  The default maximum number
igor@402:   of modified files to display in a single page of output.
igor@402: \item[\rcitem{web}{stripes}] Integer.  If the web interface displays
igor@402:   alternating ``stripes'' to make it easier to visually align rows
igor@402:   when you are looking at a table, this number controls the number of
igor@402:   rows in each stripe.
igor@402: \item[\rcitem{web}{style}] Controls the template Mercurial uses to
igor@402:   display the web interface.  Mercurial ships with two web templates,
igor@402:   named \texttt{default} and \texttt{gitweb} (the latter is much more
igor@402:   visually attractive).  You can also specify a custom template of
igor@402:   your own; see chapter~\ref{chap:template} for details.  Here, you
igor@402:   can see how to enable the \texttt{gitweb} style.
igor@402:   \begin{codesample4}
igor@402:     [web]
igor@402:     style = gitweb
igor@402:   \end{codesample4}
igor@402: \item[\rcitem{web}{templates}] Path.  The directory in which to search
igor@402:   for template files.  By default, Mercurial searches in the directory
igor@402:   in which it was installed.
igor@402: \end{itemize}
igor@402: If you are using \sfilename{hgwebdir.cgi}, you can place a few
igor@402: configuration items in a \rcsection{web} section of the
igor@402: \sfilename{hgweb.config} file instead of a \hgrc\ file, for
igor@402: convenience.  These items are \rcitem{web}{motd} and
igor@402: \rcitem{web}{style}.
igor@402: 
igor@402: \subsubsection{Options specific to an individual repository}
igor@402: 
igor@402: A few \rcsection{web} configuration items ought to be placed in a
igor@402: repository's local \sfilename{.hg/hgrc}, rather than a user's or
igor@402: global \hgrc.
igor@402: \begin{itemize}
igor@402: \item[\rcitem{web}{description}] String.  A free-form (but preferably
igor@402:   brief) string that describes the contents or purpose of the
igor@402:   repository.
igor@402: \item[\rcitem{web}{name}] String.  The name to use for the repository
igor@402:   in the web interface.  This overrides the default name, which is the
igor@402:   last component of the repository's path.
igor@402: \end{itemize}
igor@402: 
igor@402: \subsubsection{Options specific to the \hgcmd{serve} command}
igor@402: 
igor@402: Some of the items in the \rcsection{web} section of a \hgrc\ file are
igor@402: only for use with the \hgcmd{serve} command.
igor@402: \begin{itemize}
igor@402: \item[\rcitem{web}{accesslog}] Path.  The name of a file into which to
igor@402:   write an access log.  By default, the \hgcmd{serve} command writes
igor@402:   this information to standard output, not to a file.  Log entries are
igor@402:   written in the standard ``combined'' file format used by almost all
igor@402:   web servers.
igor@402: \item[\rcitem{web}{address}] String.  The local address on which the
igor@402:   server should listen for incoming connections.  By default, the
igor@402:   server listens on all addresses.
igor@402: \item[\rcitem{web}{errorlog}] Path.  The name of a file into which to
igor@402:   write an error log.  By default, the \hgcmd{serve} command writes this
igor@402:   information to standard error, not to a file.
igor@402: \item[\rcitem{web}{ipv6}] Boolean.  Whether to use the IPv6 protocol.
igor@402:   By default, IPv6 is not used. 
igor@402: \item[\rcitem{web}{port}] Integer.  The TCP~port number on which the
igor@402:   server should listen.  The default port number used is~8000.
igor@402: \end{itemize}
igor@402: 
igor@402: \subsubsection{Choosing the right \hgrc\ file to add \rcsection{web}
igor@402:   items to}
igor@402: 
igor@402: It is important to remember that a web server like Apache or
igor@402: \texttt{lighttpd} will run under a user~ID that is different to yours.
igor@402: CGI scripts run by your server, such as \sfilename{hgweb.cgi}, will
igor@402: usually also run under that user~ID.
igor@402: 
igor@402: If you add \rcsection{web} items to your own personal \hgrc\ file, CGI
igor@402: scripts won't read that \hgrc\ file.  Those settings will thus only
igor@402: affect the behaviour of the \hgcmd{serve} command when you run it.  To
igor@402: cause CGI scripts to see your settings, either create a \hgrc\ file in
igor@402: the home directory of the user ID that runs your web server, or add
igor@402: those settings to a system-wide \hgrc\ file.
igor@402: 
igor@402: 
igor@402: %%% Local Variables: 
igor@402: %%% mode: latex
igor@402: %%% TeX-master: "00book"
igor@402: %%% End: 




