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@402: \subsection{Feature branches} igor@402: igor@402: For larger projects, an effective way to manage change is to break up igor@402: a team into smaller groups. Each group has a shared branch of its igor@402: own, cloned from a single ``master'' branch used by the entire igor@402: project. People working on an individual branch are typically quite igor@402: isolated from developments on other branches. igor@402: igor@402: \begin{figure}[ht] igor@402: \centering igor@402: \grafix{feature-branches} igor@402: \caption{Feature branches} igor@402: \label{fig:collab:feature-branches} igor@402: \end{figure} igor@402: igor@402: When a particular feature is deemed to be in suitable shape, someone igor@402: on that feature team pulls and merges from the master branch into the igor@402: feature branch, then pushes back up to the master branch. igor@402: igor@402: \subsection{The release train} igor@402: igor@402: Some projects are organised on a ``train'' basis: a release is igor@402: scheduled to happen every few months, and whatever features are ready igor@402: when the ``train'' is ready to leave are allowed in. igor@402: igor@402: This model resembles working with feature branches. The difference is igor@402: that when a feature branch misses a train, someone on the feature team igor@402: pulls and merges the changes that went out on that train release into igor@402: the feature branch, and the team continues its work on top of that igor@402: release so that their feature can make the next release. igor@402: igor@402: \subsection{The Linux kernel model} igor@402: igor@402: The development of the Linux kernel has a shallow hierarchical igor@402: structure, surrounded by a cloud of apparent chaos. Because most igor@402: Linux developers use \command{git}, a distributed revision control igor@402: tool with capabilities similar to Mercurial, it's useful to describe igor@402: the way work flows in that environment; if you like the ideas, the igor@402: approach translates well across tools. igor@402: igor@402: At the center of the community sits Linus Torvalds, the creator of igor@402: Linux. He publishes a single source repository that is considered the igor@402: ``authoritative'' current tree by the entire developer community. igor@402: Anyone can clone Linus's tree, but he is very choosy about whose trees igor@402: he pulls from. igor@402: igor@402: Linus has a number of ``trusted lieutenants''. As a general rule, he igor@402: pulls whatever changes they publish, in most cases without even igor@402: reviewing those changes. Some of those lieutenants are generally igor@402: agreed to be ``maintainers'', responsible for specific subsystems igor@402: within the kernel. If a random kernel hacker wants to make a change igor@402: to a subsystem that they want to end up in Linus's tree, they must igor@402: find out who the subsystem's maintainer is, and ask that maintainer to igor@402: take their change. If the maintainer reviews their changes and agrees igor@402: to take them, they'll pass them along to Linus in due course. igor@402: igor@402: Individual lieutenants have their own approaches to reviewing, igor@402: accepting, and publishing changes; and for deciding when to feed them igor@402: to Linus. In addition, there are several well known branches that igor@402: people use for different purposes. For example, a few people maintain igor@402: ``stable'' repositories of older versions of the kernel, to which they igor@402: apply critical fixes as needed. Some maintainers publish multiple igor@402: trees: one for experimental changes; one for changes that they are igor@402: about to feed upstream; and so on. Others just publish a single igor@402: tree. igor@402: igor@402: This model has two notable features. The first is that it's ``pull igor@402: only''. You have to ask, convince, or beg another developer to take a igor@402: change from you, because there are almost no trees to which more than igor@402: one person can push, and there's no way to push changes into a tree igor@402: that someone else controls. igor@402: igor@402: The second is that it's based on reputation and acclaim. If you're an igor@402: unknown, Linus will probably ignore changes from you without even igor@402: responding. But a subsystem maintainer will probably review them, and igor@402: will likely take them if they pass their criteria for suitability. igor@402: The more ``good'' changes you contribute to a maintainer, the more igor@402: likely they are to trust your judgment and accept your changes. If igor@402: you're well-known and maintain a long-lived branch for something Linus igor@402: hasn't yet accepted, people with similar interests may pull your igor@402: changes regularly to keep up with your work. igor@402: igor@402: Reputation and acclaim don't necessarily cross subsystem or ``people'' igor@402: boundaries. If you're a respected but specialised storage hacker, and igor@402: you try to fix a networking bug, that change will receive a level of igor@402: scrutiny from a network maintainer comparable to a change from a igor@402: complete stranger. igor@402: igor@402: To people who come from more orderly project backgrounds, the igor@402: comparatively chaotic Linux kernel development process often seems igor@402: completely insane. It's subject to the whims of individuals; people igor@402: make sweeping changes whenever they deem it appropriate; and the pace igor@402: of development is astounding. And yet Linux is a highly successful, igor@402: well-regarded piece of software. igor@402: igor@402: \subsection{Pull-only versus shared-push collaboration} igor@402: igor@402: A perpetual source of heat in the open source community is whether a igor@402: development model in which people only ever pull changes from others igor@402: is ``better than'' one in which multiple people can push changes to a igor@402: shared repository. igor@402: igor@402: Typically, the backers of the shared-push model use tools that igor@402: actively enforce this approach. If you're using a centralised igor@402: revision control tool such as Subversion, there's no way to make a igor@402: choice over which model you'll use: the tool gives you shared-push, igor@402: and if you want to do anything else, you'll have to roll your own igor@402: approach on top (such as applying a patch by hand). igor@402: igor@402: A good distributed revision control tool, such as Mercurial, will igor@402: support both models. You and your collaborators can then structure igor@402: how you work together based on your own needs and preferences, not on igor@402: what contortions your tools force you into. igor@402: igor@402: \subsection{Where collaboration meets branch management} igor@402: igor@402: Once you and your team set up some shared repositories and start igor@402: propagating changes back and forth between local and shared repos, you igor@402: begin to face a related, but slightly different challenge: that of igor@402: managing the multiple directions in which your team may be moving at igor@402: once. Even though this subject is intimately related to how your team igor@402: collaborates, it's dense enough to merit treatment of its own, in igor@402: chapter~\ref{chap:branch}. igor@402: igor@402: \section{The technical side of sharing} igor@402: igor@402: The remainder of this chapter is devoted to the question of serving igor@402: data to your collaborators. igor@402: igor@402: \section{Informal sharing with \hgcmd{serve}} igor@402: \label{sec:collab:serve} igor@402: igor@402: Mercurial's \hgcmd{serve} command is wonderfully suited to small, igor@402: tight-knit, and fast-paced group environments. It also provides a igor@402: great way to get a feel for using Mercurial commands over a network. igor@402: igor@402: Run \hgcmd{serve} inside a repository, and in under a second it will igor@402: bring up a specialised HTTP server; this will accept connections from igor@402: any client, and serve up data for that repository until you terminate igor@402: it. Anyone who knows the URL of the server you just started, and can igor@402: talk to your computer over the network, can then use a web browser or igor@402: Mercurial to read data from that repository. A URL for a igor@402: \hgcmd{serve} instance running on a laptop is likely to look something igor@402: like \Verb|http://my-laptop.local:8000/|. igor@402: igor@402: The \hgcmd{serve} command is \emph{not} a general-purpose web server. igor@402: It can do only two things: igor@402: \begin{itemize} igor@402: \item Allow people to browse the history of the repository it's igor@402: serving, from their normal web browsers. igor@402: \item Speak Mercurial's wire protocol, so that people can igor@402: \hgcmd{clone} or \hgcmd{pull} changes from that repository. igor@402: \end{itemize} igor@402: In particular, \hgcmd{serve} won't allow remote users to \emph{modify} igor@402: your repository. It's intended for read-only use. igor@402: igor@402: If you're getting started with Mercurial, there's nothing to prevent igor@402: you from using \hgcmd{serve} to serve up a repository on your own igor@402: computer, then use commands like \hgcmd{clone}, \hgcmd{incoming}, and igor@402: so on to talk to that server as if the repository was hosted remotely. igor@402: This can help you to quickly get acquainted with using commands on igor@402: network-hosted repositories. igor@402: igor@402: \subsection{A few things to keep in mind} igor@402: igor@402: Because it provides unauthenticated read access to all clients, you igor@402: should only use \hgcmd{serve} in an environment where you either don't igor@402: care, or have complete control over, who can access your network and igor@402: pull data from your repository. igor@402: igor@402: The \hgcmd{serve} command knows nothing about any firewall software igor@402: you might have installed on your system or network. It cannot detect igor@402: or control your firewall software. If other people are unable to talk igor@402: to a running \hgcmd{serve} instance, the second thing you should do igor@402: (\emph{after} you make sure that they're using the correct URL) is igor@402: check your firewall configuration. igor@402: igor@402: By default, \hgcmd{serve} listens for incoming connections on igor@402: port~8000. If another process is already listening on the port you igor@402: want to use, you can specify a different port to listen on using the igor@402: \hgopt{serve}{-p} option. igor@402: igor@402: Normally, when \hgcmd{serve} starts, it prints no output, which can be igor@402: a bit unnerving. If you'd like to confirm that it is indeed running igor@402: correctly, and find out what URL you should send to your igor@402: collaborators, start it with the \hggopt{-v} option. 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: igor@402: AllowOverride FileInfo AuthConfig Limit igor@402: Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec igor@402: igor@402: Order allow,deny igor@402: Allow from all igor@402: igor@402: igor@402: Order deny,allow igor@402: Deny from all igor@402: igor@402: 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: