
jerojasro@343: \chapter{Una gira de Mercurial: lo básico}
jerojasro@343: \label{chap:tour-basic}
jerojasro@343: 
jerojasro@343: \section{Instalar Mercurial en su sistema}
jerojasro@343: \label{sec:tour:install}
jerojasro@343: Hay paquetes binarios precompilados de Mercurial disponibles para cada
jerojasro@343: sistema operativo popular. Esto hace fácil empezar a usar Mercurial
jerojasro@343: en su computador inmediatamente.
jerojasro@343: 
jerojasro@343: \subsection{Linux}
jerojasro@343: 
jerojasro@343: Dado que cada distribución de Linux tiene sus propias herramientas de
jerojasro@343: manejo de paquetes, políticas, y ritmos de desarrollo, es difícil dar
jerojasro@343: un conjunto exhaustivo de instrucciones sobre cómo instalar el paquete
jerojasro@343: de Mercurial. La versión de Mercurial que usted tenga a disposición
jerojasro@343: puede variar dependiendo de qué tan activa sea la persona que mantiene
jerojasro@343: el paquete para su distribución.
jerojasro@343: 
jerojasro@343: Para mantener las cosas simples, me enfocaré en instalar Mercurial
jerojasro@343: desde la línea de comandos en las distribuciones de Linux más
jerojasro@343: populares. La mayoría de estas distribuciones proveen administradores
jerojasro@343: de paquetes gráficos que le permitirán instalar Mercurial con un solo
jerojasro@343: clic; el nombre de paquete a buscar es \texttt{mercurial}.
jerojasro@343: 
jerojasro@343: \begin{itemize}
jerojasro@343: \item[Debian]
jerojasro@343:   \begin{codesample4}
jerojasro@343:     apt-get install mercurial
jerojasro@343:   \end{codesample4}
jerojasro@343: 
jerojasro@343: \item[Fedora Core]
jerojasro@343:   \begin{codesample4}
jerojasro@343:     yum install mercurial
jerojasro@343:   \end{codesample4}
jerojasro@343: 
jerojasro@343: \item[Gentoo]
jerojasro@343:   \begin{codesample4}
jerojasro@343:     emerge mercurial
jerojasro@343:   \end{codesample4}
jerojasro@343: 
jerojasro@343: \item[OpenSUSE]
jerojasro@343:   \begin{codesample4}
jerojasro@343:     yum install mercurial
jerojasro@343:   \end{codesample4}
jerojasro@343: 
jerojasro@343: \item[Ubuntu] El paquete de Mercurial de Ubuntu está basado en el de
jerojasro@343:     Debian. Para instalarlo, ejecute el siguiente comando.
jerojasro@343:   \begin{codesample4}
jerojasro@343:     apt-get install mercurial
jerojasro@343:   \end{codesample4}
jerojasro@343:   El paquete de Mercurial para Ubuntu tiende a atrasarse con respecto
jerojasro@343:   a la versión de Debian por un margen de tiempo considerable
jerojasro@343:   (al momento de escribir esto, 7 meses), lo que en algunos casos
jerojasro@343:   significará que usted puede encontrarse con problemas que ya habrán
jerojasro@343:   sido resueltos en el paquete de Debian.
jerojasro@343: \end{itemize}
jerojasro@343: 
jerojasro@343: \subsection{Solaris}
jerojasro@343: 
jerojasro@343: SunFreeWare, en \url{http://www.sunfreeware.com}, es una buena fuente
jerojasro@343: para un gran número de paquetes compilados para Solaris para las
jerojasro@343: arquitecturas Intel y Sparc de 32 y 64 bits, incluyendo versiones
jerojasro@343: actuales de Mercurial.
jerojasro@343: 
jerojasro@343: \subsection{Mac OS X}
jerojasro@343: 
jerojasro@343: Lee Cantey publica un instalador de Mercurial para Mac OS~X en 
jerojasro@343: \url{http://mercurial.berkwood.com}.  Este paquete funciona en tanto
jerojasro@343: en Macs basados en Intel como basados en PowerPC. Antes de que pueda
jerojasro@343: usarlo, usted debe instalar una versión compatible de Universal
jerojasro@343: MacPython~\cite{web:macpython}. Esto es fácil de hacer; simplemente
jerojasro@343: siga las instrucciones de el sitio de Lee.
jerojasro@343: 
jerojasro@343: También es posible instalar Mercurial usando Fink o MacPorts, dos
jerojasro@343: administradores de paquetes gratuitos y populares para Mac OS X. Si
jerojasro@343: usted tiene Fink, use \command{sudo apt-get install mercurial-py25}.
jerojasro@343: Si usa MacPorts, \command{sudo port install mercurial}.
jerojasro@343: 
jerojasro@343: \subsection{Windows}
jerojasro@343: 
jerojasro@343: Lee Cantey publica un instalador de Mercurial para Windows en
jerojasro@343: \url{http://mercurial.berkwood.com}. Este paquete no tiene
jerojasro@343: % TODO traducción de it just works. Agreed?
jerojasro@343: dependencias externas; ``simplemente funciona''.
jerojasro@343: 
jerojasro@343: \begin{note}
jerojasro@343:     La versión de Windows de Mercurial no convierte automáticamente
jerojasro@343:     los fines de línea entre estilos Windows y Unix. Si usted desea
jerojasro@343:     compartir trabajo con usuarios de Unix, deberá hacer un trabajo
jerojasro@343:     adicional de configuración. XXX Terminar esto.
jerojasro@343: \end{note}
jerojasro@343: 
jerojasro@343: \section{Arrancando}
jerojasro@343: 
jerojasro@343: Para empezar, usaremos el comando \hgcmd{version} para revisar si
jerojasro@343: Mercurial está instalado adecuadamente. La información de la versión
jerojasro@343: que es impresa no es tan importante; lo que nos importa es si imprime
jerojasro@343: algo en absoluto.
jerojasro@343: 
jerojasro@343: \interaction{tour.version}
jerojasro@343: 
jerojasro@343: % TODO builtin-> integrado?
jerojasro@343: \subsection{Ayuda integrada}
jerojasro@343: 
jerojasro@343: Mercurial provee un sistema de ayuda integrada. Esto es invaluable
jerojasro@343: para ésas ocasiones en la que usted está atorado tratando de recordar
jerojasro@343: cómo ejecutar un comando. Si está completamente atorado, simplemente
jerojasro@343: ejecute \hgcmd{help}; esto imprimirá una breve lista de comandos,
jerojasro@343: junto con una descripción de qué hace cada uno. Si usted solicita
jerojasro@343: ayuda sobre un comando específico (como abajo), se imprime información
jerojasro@343: más detallada.
jerojasro@343: \interaction{tour.help}
jerojasro@343: Para un nivel más impresionante de detalle (que usted no va a
jerojasro@343: necesitar usualmente) ejecute \hgcmdargs{help}{\hggopt{-v}}. La opción
jerojasro@343: \hggopt{-v} es la abreviación para \hggopt{--verbose}, y le indica a
jerojasro@343: Mercurial que imprima más información de lo que haría usualmente.
jerojasro@343: 
jerojasro@352: \section{Trabajar con un repositorio}
jerojasro@352: 
jerojasro@352: En Mercurial, todo sucede dentro de un \emph{repositorio}. El
jerojasro@362: repositorio para un proyecto contiene todos los ficheros que
jerojasro@352: ``pertenecen a'' ése proyecto, junto con un registro histórico de los
jerojasro@362: ficheros de ese proyecto.
jerojasro@352: 
jerojasro@352: No hay nada particularmente mágico acerca de un repositorio; es
jerojasro@362: simplemente un árbol de directorios en su sistema de ficheros que
jerojasro@352: Mercurial trata como especial. Usted puede renombrar o borrar un
jerojasro@352: repositorio en el momento que lo desee, usando bien sea la línea de
jerojasro@352: comandos o su explorador de ficheros.
jerojasro@352: 
jerojasro@352: \subsection{Hacer una copia local de un repositorio}
jerojasro@352: 
jerojasro@352: \emph{Copiar} un repositorio es sólo ligeramente especial. Aunque
jerojasro@362: usted podría usar un programa normal de copia de ficheros para hacer
jerojasro@352: una copia del repositorio, es mejor usar el comando integrado que
jerojasro@352: Mercurial ofrece. Este comando se llama \hgcmd{clone}\ndt{Del término
jerojasro@352: ``clonar'' en inglés.}, porque crea una copia idéntica de un
jerojasro@352: repositorio existente.
jerojasro@343: \interaction{tour.clone}
jerojasro@352: Si nuestro clonado tiene éxito, deberíamos tener un directorio local
jerojasro@362: llamado \dirname{hello}. Este directorio contendrá algunos ficheros.
jerojasro@343: \interaction{tour.ls}
jerojasro@362: Estos ficheros tienen el mismo contenido e historial en nuestro
jerojasro@352: repositorio y en el repositorio que clonamos.
jerojasro@352: 
jerojasro@352: Cada repositorio Mercurial está completo, es autocontenido e
jerojasro@362: independiente. Contiene su propia copia de los ficheros y la historia
jerojasro@352: de un proyecto. Un repositorio clonado recuerda la ubicación de la que
jerojasro@352: fue clonado, pero no se comunica con ese repositorio, ni con ningún
jerojasro@352: otro, a menos que usted le indique que lo haga.
jerojasro@352: 
jerojasro@352: Lo que esto significa por ahora es que somos libres de experimentar
jerojasro@355: con nuestro repositorio, con la tranquilidad de saber que es una
jerojasro@355: % TODO figure out what to say instead of sandbox
jerojasro@355: ``caja de arena'' privada que no afectará a nadie más.
jerojasro@355: 
jerojasro@355: \subsection{Qué hay en un repositorio?}
jerojasro@355: 
jerojasro@355: Cuando miramos en detalle dentro de un repositorio, podemos ver que
jerojasro@355: contiene un directorio llamado \dirname{.hg}. Aquí es donde Mercurial
jerojasro@355: mantiene todos los metadatos del repositorio.
jerojasro@343: \interaction{tour.ls-a}
jerojasro@343: 
jerojasro@355: Los contenidos del directorio \dirname{.hg} y sus subdirectorios son
jerojasro@355: exclusivos de Mercurial. Usted es libre de hacer lo que desee con
jerojasro@362: cualquier otro fichero o directorio en el repositorio.
jerojasro@343: 
jerojasro@357: Para introducir algo de terminología, el directorio \dirname{.hg} es
jerojasro@362: el repositorio ``real'', y todos los ficheros y directorios que
jerojasro@357: coexisten con él están en el \emph{directorio de trabajo}. Una forma
jerojasro@357: sencilla de recordar esta distinción es que el \emph{repositorio}
jerojasro@357: % TODO unificar con Igor, si historia o historial
jerojasro@357: contiene el \emph{historial} de su proyecto, mientras que el
jerojasro@357: \emph{directorio de trabajo} contiene una \emph{instantánea} de su
jerojasro@357: proyecto en un punto particular del historial.
jerojasro@357: 
jerojasro@357: \section{Vistazo rápido al historial}
jerojasro@357: 
jerojasro@357: Una de las primeras cosas que se desea hacer con un repositorio nuevo,
jerojasro@357: poco conocido, es conocer su historial. el comando \hgcmd{log} nos
jerojasro@357: permite ver el mismo.
jerojasro@343: \interaction{tour.log}
jerojasro@358: Por defecto este programa imprime un párrafo breve por cada cambio al
jerojasro@358: proyecto que haya sido grabado. Dentro de la terminología de
jerojasro@358: Mercurial, cada uno de estos eventos es llamado \emph{conjuntos de
jerojasro@358: cambios}, porque pueden contener un registro de cambios a varios
jerojasro@362: ficheros.
jerojasro@358: 
jerojasro@358: Los campos de la salida de \hgcmd{log} son los siguientes.
jerojasro@343: \begin{itemize}
jerojasro@358:     \item[\texttt{changeset}]\hspace{-0.5em}\ndt{Conjunto de cambios.} Este campo
jerojasro@358:         tiene un número, seguido por un
jerojasro@358:         % TODO digo mejor seguido por un dos puntos ? string =>
jerojasro@358:         % cadena?
jerojasro@358:         \texttt{:}, seguido por una cadena hexadecimal. Ambos son
jerojasro@358:         \emph{identificadores} para el conjunto de cambios. Hay dos
jerojasro@358:         identificadores porque el número es más corto y más fácil de
jerojasro@358:         recordar que la cadena hexadecimal.
jerojasro@358:         
jerojasro@358: \item[\texttt{user}]\hspace{-0.5em}\ndt{Usuario.} La identidad de la
jerojasro@358:     persona que creó el conjunto de cambios. Este es un campo en el
jerojasro@358:     que se puede almacenar cualquier valor, pero en la mayoría de los
jerojasro@358:     casos contiene el nombre de una persona y su dirección de correo
jerojasro@358:     electrónico.
jerojasro@358:     
jerojasro@362: \item[\texttt{date}]\hspace{-0.5em}\ndt{Fecha.} La fecha y hora en la
jerojasro@362:     que el conjunto de cambios fue creado, y la zona horaria en la que
jerojasro@362:     fue creado. (La fecha y hora son locales a dicha zona horaria;
jerojasro@362:     ambos muestran la fecha y hora para la persona que creó el
jerojasro@362:     changeset).
jerojasro@362:     
jerojasro@362: \item[\texttt{summary}]\hspace{-0.5em}\ndt{Sumario.} 
jerojasro@362:     La primera línea del texto que usó la persona que creó el conjunto
jerojasro@362:     de cambios para describir el mismo.
jerojasro@343: \end{itemize}
jerojasro@362: El texto impreso por \hgcmd{log} es sólo un sumario; omite una gran
jerojasro@362: cantidad de detalles.
jerojasro@362: 
jerojasro@362: La figura~\ref{fig:tour-basic:history} es una representación
jerojasro@362: gráfica del historial del repositorio \dirname{hello}, para hacer más
jerojasro@362: fácil ver en qué dirección está ``fluyendo'' el historial. Volveremos
jerojasro@362: a esto varias veces en este capítulo y en los siguientes.
jerojasro@343: 
jerojasro@343: \begin{figure}[ht]
jerojasro@343:   \centering
jerojasro@343:   \grafix{tour-history}
jerojasro@362:   \caption{Historial gráfico de el repositorio \dirname{hello}}
jerojasro@343:   \label{fig:tour-basic:history}
jerojasro@343: \end{figure}
jerojasro@343: 
jerojasro@362: \subsection{Conjuntos de cambios, revisiones, y comunicándose con
jerojasro@362: otras personas}
jerojasro@362: 
jerojasro@362: %TODO sloppy => desordenado ?  TODO hablar del inglés? o de español?
jerojasro@362: Ya que el inglés es un lenguaje notablemente desordenado, y el área de
jerojasro@362: ciencias de la computación tiene una notable historia de confusión de
jerojasro@362: % TODO insertar ? al revés. no sé cómo en un teclado de estos.
jerojasro@362: términos (porqué usar sólo un término cuando cuatro pueden servir?),
jerojasro@362: el control de revisiones tiene una variedad de frases y palabras que
jerojasro@362: tienen el mismo significado. Si usted habla acerca del historial de
jerojasro@362: Mercurial con alguien, encontrará que la expresión ``conjunto de
jerojasro@362: cambios'' es abreviada a menudo como ``cambio'' o (por escrito)
jerojasro@362: ``cset''\ndt{Abreviatura para la expresión ``changeset'' en inglés.},
jerojasro@362: y algunas veces un se hace referencia a un conjunto de cambios como
jerojasro@362: una ``revisión'' o ``rev''\ndt{De nuevo, como abreviación para el
jerojasro@362: término en inglés para ``revisión'' (``revision'').}.
jerojasro@362: 
jerojasro@362: Si bien no es relevante qué \emph{palabra} use usted para referirse al
jerojasro@362: concepto ``conjunto de cambios'', el \emph{identificador} que usted
jerojasro@362: use para referise a ``un \emph{conjunto de cambios} particular'' es
jerojasro@362: muy importante. Recuerde que el campo \texttt{changeset} en la salida
jerojasro@362: de \hgcmd{log} identifica un conjunto de cambios usando tanto un
jerojasro@362: número como una cadena hexadecimal.
jerojasro@362: 
jerojasro@343: \begin{itemize}
jerojasro@362:     \item El número de revisión \emph{sólo es válido dentro del
jerojasro@362:         repositorio}.
jerojasro@362:     \item Por otro lado, la cadena hexadecimal es el
jerojasro@362:         \emph{identificador permanente e inmutable} que siempre
jerojasro@362:         identificará ése conjunto de cambios en \emph{todas} las
jerojasro@362:         copias del repositorio.
jerojasro@343: \end{itemize}
jerojasro@362: La diferencia es importante. Si usted le envía a alguien un correo
jerojasro@362: electrónico hablando acerca de la ``revisión~33'', hay una
jerojasro@362: probabilidad alta de que la revisión~33 de esa persona \emph{no sea la
jerojasro@362: misma suya}. Esto sucede porque el número de revisión depende de el
jerojasro@362: orden en que llegan los cambios al repositorio, y no hay ninguna
jerojasro@362: garantía de que los mismos cambios llegarán en el mismo orden en
jerojasro@362: diferentes repositorios. Tres cambios dados $a,b,c$ pueden aparecer en
jerojasro@362: un repositorio como $0,1,2$, mientras que en otro aparecen como
jerojasro@362: $1,0,2$.
jerojasro@362: 
jerojasro@362: Mercurial usa los números de revisión simplemente como una abreviación
jerojasro@362: conveniente. Si usted necesita hablar con alguien acerca de un
jerojasro@362: conjunto de cambios, o llevar el registro de un conjunto de cambios
jerojasro@362: por alguna otra razón (por ejemplo, en un reporte de fallo), use el
jerojasro@362: identificador hexadecimal.
jerojasro@343: 
jerojasro@363: \subsection{Ver revisiones específicas}
jerojasro@363: 
jerojasro@363: Para reducir la salida de \hgcmd{log} a una sola revisión, use la  
jerojasro@363: opción \hgopt{log}{-r} (o \hgopt{log}{--rev}).  Puede usar un número
jerojasro@363: de revisión o un identificador hexadecimal de conjunto de cambios, y
jerojasro@363: puede pasar tantas revisiones como desee.
jerojasro@363: 
jerojasro@363: \interaction{tour.log-r}
jerojasro@363: 
jerojasro@363: Si desea ver el historial de varias revisiones sin tener que mencionar
jerojasro@363: cada una de ellas, puede usar la \emph{notación de rango}; esto le
jerojasro@363: permite expresar el concepto ``quiero ver todas las revisiones entre
jerojasro@363: $a$ y $b$, inclusive''.
jerojasro@343: \interaction{tour.log.range}
jerojasro@363: Mercurial también respeta el orden en que usted especifica las
jerojasro@363: revisiones, así que \hgcmdargs{log}{-r 2:4} muestra $2,3,4$ mientras
jerojasro@363: que \hgcmdargs{log}{-r 4:2} muestra $4,3,2$.
jerojasro@363: 
jerojasro@363: \subsection{Información más detallada}
jerojasro@363: Aunque la información presentada por \hgcmd{log} es útil si usted sabe
jerojasro@363: de antemano qué está buscando, puede que necesite ver una descripción
jerojasro@363: completa de el cambio, o una lista de los ficheros que cambiaron, si
jerojasro@363: está tratando de averiguar si un conjunto de cambios dado es el que
jerojasro@363: usted está buscando. La opción \hggopt{-v} (or \hggopt{--verbose}) del
jerojasro@363: comando \hgcmd{log} le da este nivel extra de detalle.
jerojasro@343: \interaction{tour.log-v}
jerojasro@343: 
jerojasro@363: Si desea ver tanto la descripción como el contenido de un cambio,
jerojasro@363: añada la opción \hgopt{log}{-p} (o \hgopt{log}{--patch}). Esto muestra
jerojasro@363: % TODO qué hacemos con diff unificado? convervarlo, por ser la
jerojasro@363: % acepción usual?
jerojasro@363: el contenido de un cambio como un \emph{diff unificado} (si usted
jerojasro@363: nunca ha visto un diff unificado antes, vea la
jerojasro@363: sección~\ref{sec:mq:patch} para un vistazo global).
jerojasro@343: \interaction{tour.log-vp}
jerojasro@343: 
jerojasro@364: \section{Todo acerca de las opciones para comandos}
jerojasro@364: 
jerojasro@364: Tomemos un breve descanso de la tarea de explorar los comandos de
jerojasro@365: Mercurial para hablar de un patrón en la manera en que trabajan; será
jerojasro@364: útil tener esto en mente a medida que avanza nuestra gira.
jerojasro@364: 
jerojasro@365: Mercurial tiene un enfoque directo y consistente en el manejo de las
jerojasro@364: opciones que usted le puede pasar a los comandos. Se siguen las
jerojasro@364: convenciones para opciones que son comunes en sistemas Linux y Unix
jerojasro@364: modernos.
jerojasro@343: \begin{itemize}
jerojasro@364: \item Cada opción tiene un nombre largo. Por ejemplo, el comando
jerojasro@364:     \hgcmd{log} acepta la opción \hgopt{log}{--rev}, como ya hemos
jerojasro@364:     visto.
jerojasro@364: \item Muchas opciones tienen también un nombre corto. En vez de
jerojasro@364:     \hgopt{log}{--rev}, podemos usar \hgopt{log}{-r}.  (El motivo para
jerojasro@364:     que algunas opciones no tengan nombres cortos es que dichas
jerojasro@364:     opciones se usan rara vez.)
jerojasro@364: \item Las opciones largas empiezan con dos guiones (p.ej.~\hgopt{log}{--rev}),
jerojasro@364:     mientras que las opciones cortas empiezan con uno (e.g.~\hgopt{log}{-r}).
jerojasro@364: \item El nombre  y uso de las opciones es consistente en todos los
jerojasro@364:     comandos. Por ejemplo, cada comando que le permite pasar un ID de
jerojasro@364:     conjunto de cambios o un número de revisión acepta tanto la opción
jerojasro@364:     \hgopt{log}{-r} como la \hgopt{log}{--rev}.
jerojasro@343: \end{itemize}
jerojasro@364: En los ejemplos en este libro, uso las opciones cortas en vez de las
jerojasro@364: largas. Esto sólo muestra mis preferencias, así que no le dé
jerojasro@364: significado especial a eso.
jerojasro@364: 
jerojasro@364: Muchos de los comandos que generan salida de algún tipo mostrarán más
jerojasro@364: salida cuando se les pase la opción \hggopt{-v} (o
jerojasro@364: \hggopt{--verbose}\ndt{Prolijo.}), y menos cuando se les pase la opción \hggopt{-q}
jerojasro@364: (o \hggopt{--quiet}\ndt{Silencioso.}).
jerojasro@343: 
jerojasro@366: \section{Hacer y repasar cambios}
jerojasro@366: 
jerojasro@366: Ahora que tenemos una comprensión adecuada sobre cómo revisar el
jerojasro@366: historial en Mercurial, hagamos algunos cambios y veamos cómo
jerojasro@366: examinarlos.
jerojasro@366: 
jerojasro@366: Lo primero que haremos será aislar nuestro experimento en un
jerojasro@366: repositorio propio. Usaremos el comando \hgcmd{clone}, pero no hace
jerojasro@366: falta clonar una copia de el repositorio remoto. Como ya contamos con
jerojasro@366: una copia local del mismo, podemos clonar esa. Esto es mucho más
jerojasro@366: rápido que clonar a través de la red, y en la mayoría de los casos
jerojasro@366: clonar un repositorio local usa menos espacio en disco también.
jerojasro@343: \interaction{tour.reclone}
jerojasro@343: As an aside, it's often good practice to keep a ``pristine'' copy of a
jerojasro@343: remote repository around, which you can then make temporary clones of
jerojasro@343: to create sandboxes for each task you want to work on.  This lets you
jerojasro@343: work on multiple tasks in parallel, each isolated from the others
jerojasro@343: until it's complete and you're ready to integrate it back.  Because
jerojasro@343: local clones are so cheap, there's almost no overhead to cloning and
jerojasro@343: destroying repositories whenever you want.
jerojasro@343: 
jerojasro@343: In our \dirname{my-hello} repository, we have a file
jerojasro@343: \filename{hello.c} that contains the classic ``hello, world'' program.
jerojasro@343: Let's use the ancient and venerable \command{sed} command to edit this
jerojasro@343: file so that it prints a second line of output.  (I'm only using
jerojasro@343: \command{sed} to do this because it's easy to write a scripted example
jerojasro@343: this way.  Since you're not under the same constraint, you probably
jerojasro@343: won't want to use \command{sed}; simply use your preferred text editor to
jerojasro@343: do the same thing.)
jerojasro@343: \interaction{tour.sed}
jerojasro@343: 
jerojasro@343: Mercurial's \hgcmd{status} command will tell us what Mercurial knows
jerojasro@343: about the files in the repository.
jerojasro@343: \interaction{tour.status}
jerojasro@343: The \hgcmd{status} command prints no output for some files, but a line
jerojasro@343: starting with ``\texttt{M}'' for \filename{hello.c}.  Unless you tell
jerojasro@343: it to, \hgcmd{status} will not print any output for files that have
jerojasro@343: not been modified.  
jerojasro@343: 
jerojasro@343: The ``\texttt{M}'' indicates that Mercurial has noticed that we
jerojasro@343: modified \filename{hello.c}.  We didn't need to \emph{inform}
jerojasro@343: Mercurial that we were going to modify the file before we started, or
jerojasro@343: that we had modified the file after we were done; it was able to
jerojasro@343: figure this out itself.
jerojasro@343: 
jerojasro@343: It's a little bit helpful to know that we've modified
jerojasro@343: \filename{hello.c}, but we might prefer to know exactly \emph{what}
jerojasro@343: changes we've made to it.  To do this, we use the \hgcmd{diff}
jerojasro@343: command.
jerojasro@343: \interaction{tour.diff}
jerojasro@343: 
jerojasro@343: \section{Recording changes in a new changeset}
jerojasro@343: 
jerojasro@343: We can modify files, build and test our changes, and use
jerojasro@343: \hgcmd{status} and \hgcmd{diff} to review our changes, until we're
jerojasro@343: satisfied with what we've done and arrive at a natural stopping point
jerojasro@343: where we want to record our work in a new changeset.
jerojasro@343: 
jerojasro@343: The \hgcmd{commit} command lets us create a new changeset; we'll
jerojasro@343: usually refer to this as ``making a commit'' or ``committing''.  
jerojasro@343: 
jerojasro@343: \subsection{Setting up a username}
jerojasro@343: 
jerojasro@343: When you try to run \hgcmd{commit} for the first time, it is not
jerojasro@343: guaranteed to succeed.  Mercurial records your name and address with
jerojasro@343: each change that you commit, so that you and others will later be able
jerojasro@343: to tell who made each change.  Mercurial tries to automatically figure
jerojasro@343: out a sensible username to commit the change with.  It will attempt
jerojasro@343: each of the following methods, in order:
jerojasro@343: \begin{enumerate}
jerojasro@343: \item If you specify a \hgopt{commit}{-u} option to the \hgcmd{commit}
jerojasro@343:   command on the command line, followed by a username, this is always
jerojasro@343:   given the highest precedence.
jerojasro@343: \item If you have set the \envar{HGUSER} environment variable, this is
jerojasro@343:   checked next.
jerojasro@343: \item If you create a file in your home directory called
jerojasro@343:   \sfilename{.hgrc}, with a \rcitem{ui}{username} entry, that will be
jerojasro@343:   used next.  To see what the contents of this file should look like,
jerojasro@343:   refer to section~\ref{sec:tour-basic:username} below.
jerojasro@343: \item If you have set the \envar{EMAIL} environment variable, this
jerojasro@343:   will be used next.
jerojasro@343: \item Mercurial will query your system to find out your local user
jerojasro@343:   name and host name, and construct a username from these components.
jerojasro@343:   Since this often results in a username that is not very useful, it
jerojasro@343:   will print a warning if it has to do this.
jerojasro@343: \end{enumerate}
jerojasro@343: If all of these mechanisms fail, Mercurial will fail, printing an
jerojasro@343: error message.  In this case, it will not let you commit until you set
jerojasro@343: up a username.
jerojasro@343: 
jerojasro@343: You should think of the \envar{HGUSER} environment variable and the
jerojasro@343: \hgopt{commit}{-u} option to the \hgcmd{commit} command as ways to
jerojasro@343: \emph{override} Mercurial's default selection of username.  For normal
jerojasro@343: use, the simplest and most robust way to set a username for yourself
jerojasro@343: is by creating a \sfilename{.hgrc} file; see below for details.
jerojasro@343: 
jerojasro@343: \subsubsection{Creating a Mercurial configuration file}
jerojasro@343: \label{sec:tour-basic:username}
jerojasro@343: 
jerojasro@343: To set a user name, use your favourite editor to create a file called
jerojasro@343: \sfilename{.hgrc} in your home directory.  Mercurial will use this
jerojasro@343: file to look up your personalised configuration settings.  The initial
jerojasro@343: contents of your \sfilename{.hgrc} should look like this.
jerojasro@343: \begin{codesample2}
jerojasro@343:   # This is a Mercurial configuration file.
jerojasro@343:   [ui]
jerojasro@343:   username = Firstname Lastname <email.address@domain.net>
jerojasro@343: \end{codesample2}
jerojasro@343: The ``\texttt{[ui]}'' line begins a \emph{section} of the config file,
jerojasro@343: so you can read the ``\texttt{username = ...}'' line as meaning ``set
jerojasro@343: the value of the \texttt{username} item in the \texttt{ui} section''.
jerojasro@343: A section continues until a new section begins, or the end of the
jerojasro@343: file.  Mercurial ignores empty lines and treats any text from
jerojasro@343: ``\texttt{\#}'' to the end of a line as a comment.
jerojasro@343: 
jerojasro@343: \subsubsection{Choosing a user name}
jerojasro@343: 
jerojasro@343: You can use any text you like as the value of the \texttt{username}
jerojasro@343: config item, since this information is for reading by other people,
jerojasro@343: but for interpreting by Mercurial.  The convention that most people
jerojasro@343: follow is to use their name and email address, as in the example
jerojasro@343: above.
jerojasro@343: 
jerojasro@343: \begin{note}
jerojasro@343:   Mercurial's built-in web server obfuscates email addresses, to make
jerojasro@343:   it more difficult for the email harvesting tools that spammers use.
jerojasro@343:   This reduces the likelihood that you'll start receiving more junk
jerojasro@343:   email if you publish a Mercurial repository on the web.
jerojasro@343: \end{note}
jerojasro@343: 
jerojasro@343: \subsection{Writing a commit message}
jerojasro@343: 
jerojasro@343: When we commit a change, Mercurial drops us into a text editor, to
jerojasro@343: enter a message that will describe the modifications we've made in
jerojasro@343: this changeset.  This is called the \emph{commit message}.  It will be
jerojasro@343: a record for readers of what we did and why, and it will be printed by
jerojasro@343: \hgcmd{log} after we've finished committing.
jerojasro@343: \interaction{tour.commit}
jerojasro@343: 
jerojasro@343: The editor that the \hgcmd{commit} command drops us into will contain
jerojasro@343: an empty line, followed by a number of lines starting with
jerojasro@343: ``\texttt{HG:}''.
jerojasro@343: \begin{codesample2}
jerojasro@343:   \emph{empty line}
jerojasro@343:   HG: changed hello.c
jerojasro@343: \end{codesample2}
jerojasro@343: Mercurial ignores the lines that start with ``\texttt{HG:}''; it uses
jerojasro@343: them only to tell us which files it's recording changes to.  Modifying
jerojasro@343: or deleting these lines has no effect.
jerojasro@343: 
jerojasro@343: \subsection{Writing a good commit message}
jerojasro@343: 
jerojasro@343: Since \hgcmd{log} only prints the first line of a commit message by
jerojasro@343: default, it's best to write a commit message whose first line stands
jerojasro@343: alone.  Here's a real example of a commit message that \emph{doesn't}
jerojasro@343: follow this guideline, and hence has a summary that is not readable.
jerojasro@343: \begin{codesample2}
jerojasro@343:   changeset:   73:584af0e231be
jerojasro@343:   user:        Censored Person <censored.person@example.org>
jerojasro@343:   date:        Tue Sep 26 21:37:07 2006 -0700
jerojasro@343:   summary:     include buildmeister/commondefs.   Add an exports and install
jerojasro@343: \end{codesample2}
jerojasro@343: 
jerojasro@343: As far as the remainder of the contents of the commit message are
jerojasro@343: concerned, there are no hard-and-fast rules.  Mercurial itself doesn't
jerojasro@343: interpret or care about the contents of the commit message, though
jerojasro@343: your project may have policies that dictate a certain kind of
jerojasro@343: formatting.
jerojasro@343: 
jerojasro@343: My personal preference is for short, but informative, commit messages
jerojasro@343: that tell me something that I can't figure out with a quick glance at
jerojasro@343: the output of \hgcmdargs{log}{--patch}.
jerojasro@343: 
jerojasro@343: \subsection{Aborting a commit}
jerojasro@343: 
jerojasro@343: If you decide that you don't want to commit while in the middle of
jerojasro@343: editing a commit message, simply exit from your editor without saving
jerojasro@343: the file that it's editing.  This will cause nothing to happen to
jerojasro@343: either the repository or the working directory.
jerojasro@343: 
jerojasro@343: If we run the \hgcmd{commit} command without any arguments, it records
jerojasro@343: all of the changes we've made, as reported by \hgcmd{status} and
jerojasro@343: \hgcmd{diff}.
jerojasro@343: 
jerojasro@343: \subsection{Admiring our new handiwork}
jerojasro@343: 
jerojasro@343: Once we've finished the commit, we can use the \hgcmd{tip} command to
jerojasro@343: display the changeset we just created.  This command produces output
jerojasro@343: that is identical to \hgcmd{log}, but it only displays the newest
jerojasro@343: revision in the repository.
jerojasro@343: \interaction{tour.tip}
jerojasro@343: We refer to the newest revision in the repository as the tip revision,
jerojasro@343: or simply the tip.
jerojasro@343: 
jerojasro@343: \section{Sharing changes}
jerojasro@343: 
jerojasro@343: We mentioned earlier that repositories in Mercurial are
jerojasro@343: self-contained.  This means that the changeset we just created exists
jerojasro@343: only in our \dirname{my-hello} repository.  Let's look at a few ways
jerojasro@343: that we can propagate this change into other repositories.
jerojasro@343: 
jerojasro@343: \subsection{Pulling changes from another repository}
jerojasro@343: \label{sec:tour:pull}
jerojasro@343: 
jerojasro@343: To get started, let's clone our original \dirname{hello} repository,
jerojasro@343: which does not contain the change we just committed.  We'll call our
jerojasro@343: temporary repository \dirname{hello-pull}.
jerojasro@343: \interaction{tour.clone-pull}
jerojasro@343: 
jerojasro@343: We'll use the \hgcmd{pull} command to bring changes from
jerojasro@343: \dirname{my-hello} into \dirname{hello-pull}.  However, blindly
jerojasro@343: pulling unknown changes into a repository is a somewhat scary
jerojasro@343: prospect.  Mercurial provides the \hgcmd{incoming} command to tell us
jerojasro@343: what changes the \hgcmd{pull} command \emph{would} pull into the
jerojasro@343: repository, without actually pulling the changes in.
jerojasro@343: \interaction{tour.incoming}
jerojasro@343: (Of course, someone could cause more changesets to appear in the
jerojasro@343: repository that we ran \hgcmd{incoming} in, before we get a chance to
jerojasro@343: \hgcmd{pull} the changes, so that we could end up pulling changes that we
jerojasro@343: didn't expect.)
jerojasro@343: 
jerojasro@343: Bringing changes into a repository is a simple matter of running the
jerojasro@343: \hgcmd{pull} command, and telling it which repository to pull from.
jerojasro@343: \interaction{tour.pull}
jerojasro@343: As you can see from the before-and-after output of \hgcmd{tip}, we
jerojasro@343: have successfully pulled changes into our repository.  There remains
jerojasro@343: one step before we can see these changes in the working directory.
jerojasro@343: 
jerojasro@343: \subsection{Updating the working directory}
jerojasro@343: 
jerojasro@343: We have so far glossed over the relationship between a repository and
jerojasro@343: its working directory.  The \hgcmd{pull} command that we ran in
jerojasro@343: section~\ref{sec:tour:pull} brought changes into the repository, but
jerojasro@343: if we check, there's no sign of those changes in the working
jerojasro@343: directory.  This is because \hgcmd{pull} does not (by default) touch
jerojasro@343: the working directory.  Instead, we use the \hgcmd{update} command to
jerojasro@343: do this.
jerojasro@343: \interaction{tour.update}
jerojasro@343: 
jerojasro@343: It might seem a bit strange that \hgcmd{pull} doesn't update the
jerojasro@343: working directory automatically.  There's actually a good reason for
jerojasro@343: this: you can use \hgcmd{update} to update the working directory to
jerojasro@343: the state it was in at \emph{any revision} in the history of the
jerojasro@343: repository.  If you had the working directory updated to an old
jerojasro@343: revision---to hunt down the origin of a bug, say---and ran a
jerojasro@343: \hgcmd{pull} which automatically updated the working directory to a
jerojasro@343: new revision, you might not be terribly happy.
jerojasro@343: 
jerojasro@343: However, since pull-then-update is such a common thing to do,
jerojasro@343: Mercurial lets you combine the two by passing the \hgopt{pull}{-u}
jerojasro@343: option to \hgcmd{pull}.
jerojasro@343: \begin{codesample2}
jerojasro@343:   hg pull -u
jerojasro@343: \end{codesample2}
jerojasro@343: If you look back at the output of \hgcmd{pull} in
jerojasro@343: section~\ref{sec:tour:pull} when we ran it without \hgopt{pull}{-u},
jerojasro@343: you can see that it printed a helpful reminder that we'd have to take
jerojasro@343: an explicit step to update the working directory:
jerojasro@343: \begin{codesample2}
jerojasro@343:   (run 'hg update' to get a working copy)
jerojasro@343: \end{codesample2}
jerojasro@343: 
jerojasro@343: To find out what revision the working directory is at, use the
jerojasro@343: \hgcmd{parents} command.
jerojasro@343: \interaction{tour.parents}
jerojasro@343: If you look back at figure~\ref{fig:tour-basic:history}, you'll see
jerojasro@343: arrows connecting each changeset.  The node that the arrow leads
jerojasro@343: \emph{from} in each case is a parent, and the node that the arrow
jerojasro@343: leads \emph{to} is its child.  The working directory has a parent in
jerojasro@343: just the same way; this is the changeset that the working directory
jerojasro@343: currently contains.
jerojasro@343: 
jerojasro@343: To update the working directory to a particular revision, give a
jerojasro@343: revision number or changeset~ID to the \hgcmd{update} command.
jerojasro@343: \interaction{tour.older}
jerojasro@343: If you omit an explicit revision, \hgcmd{update} will update to the
jerojasro@343: tip revision, as shown by the second call to \hgcmd{update} in the
jerojasro@343: example above.
jerojasro@343: 
jerojasro@343: \subsection{Pushing changes to another repository}
jerojasro@343: 
jerojasro@343: Mercurial lets us push changes to another repository, from the
jerojasro@343: repository we're currently visiting.  As with the example of
jerojasro@343: \hgcmd{pull} above, we'll create a temporary repository to push our
jerojasro@343: changes into.
jerojasro@343: \interaction{tour.clone-push}
jerojasro@343: The \hgcmd{outgoing} command tells us what changes would be pushed
jerojasro@343: into another repository.
jerojasro@343: \interaction{tour.outgoing}
jerojasro@343: And the \hgcmd{push} command does the actual push.
jerojasro@343: \interaction{tour.push}
jerojasro@343: As with \hgcmd{pull}, the \hgcmd{push} command does not update the
jerojasro@343: working directory in the repository that it's pushing changes into.
jerojasro@343: (Unlike \hgcmd{pull}, \hgcmd{push} does not provide a \texttt{-u}
jerojasro@343: option that updates the other repository's working directory.)
jerojasro@343: 
jerojasro@343: What happens if we try to pull or push changes and the receiving
jerojasro@343: repository already has those changes?  Nothing too exciting.
jerojasro@343: \interaction{tour.push.nothing}
jerojasro@343: 
jerojasro@343: \subsection{Sharing changes over a network}
jerojasro@343: 
jerojasro@343: The commands we have covered in the previous few sections are not
jerojasro@343: limited to working with local repositories.  Each works in exactly the
jerojasro@343: same fashion over a network connection; simply pass in a URL instead
jerojasro@343: of a local path.
jerojasro@343: \interaction{tour.outgoing.net}
jerojasro@343: In this example, we can see what changes we could push to the remote
jerojasro@343: repository, but the repository is understandably not set up to let
jerojasro@343: anonymous users push to it.
jerojasro@343: \interaction{tour.push.net}
jerojasro@343: 
jerojasro@343: %%% Local Variables: 
jerojasro@343: %%% mode: latex
jerojasro@343: %%% TeX-master: "00book"
jerojasro@343: %%% End: 




