hgbook

diff es/hook.tex @ 441:4e0684e824e1

translated up to the tutorial on using hooks
author jerojasro@abu.no-ip.org
date Mon Dec 08 11:16:54 2008 -0500 (2008-12-08)
parents 05bfbe50e7e4
children 606295a87ff2
line diff
     1.1 --- a/es/hook.tex	Fri Dec 05 22:09:05 2008 -0500
     1.2 +++ b/es/hook.tex	Mon Dec 08 11:16:54 2008 -0500
     1.3 @@ -126,124 +126,136 @@
     1.4  global para definir los ganchos que verán todos los usuarios. Sin
     1.5  embargo, este enfoque tiene sus límites; vea más abajo.
     1.6  
     1.7 -\subsection{Hooks can be overridden}
     1.8 -
     1.9 -Mercurial allows you to override a hook definition by redefining the
    1.10 -hook.  You can disable it by setting its value to the empty string, or
    1.11 -change its behaviour as you wish.
    1.12 -
    1.13 -If you deploy a system-~or site-wide \hgrc\ file that defines some
    1.14 -hooks, you should thus understand that your users can disable or
    1.15 -override those hooks.
    1.16 -
    1.17 -\subsection{Ensuring that critical hooks are run}
    1.18 -
    1.19 -Sometimes you may want to enforce a policy that you do not want others
    1.20 -to be able to work around.  For example, you may have a requirement
    1.21 -that every changeset must pass a rigorous set of tests.  Defining this
    1.22 -requirement via a hook in a site-wide \hgrc\ won't work for remote
    1.23 -users on laptops, and of course local users can subvert it at will by
    1.24 -overriding the hook.
    1.25 -
    1.26 -Instead, you can set up your policies for use of Mercurial so that
    1.27 -people are expected to propagate changes through a well-known
    1.28 -``canonical'' server that you have locked down and configured
    1.29 -appropriately.
    1.30 -
    1.31 -One way to do this is via a combination of social engineering and
    1.32 -technology.  Set up a restricted-access account; users can push
    1.33 -changes over the network to repositories managed by this account, but
    1.34 -they cannot log into the account and run normal shell commands.  In
    1.35 -this scenario, a user can commit a changeset that contains any old
    1.36 -garbage they want.
    1.37 -
    1.38 -When someone pushes a changeset to the server that everyone pulls
    1.39 -from, the server will test the changeset before it accepts it as
    1.40 -permanent, and reject it if it fails to pass the test suite.  If
    1.41 -people only pull changes from this filtering server, it will serve to
    1.42 -ensure that all changes that people pull have been automatically
    1.43 -vetted.
    1.44 -
    1.45 -\section{Care with \texttt{pretxn} hooks in a shared-access repository}
    1.46 -
    1.47 -If you want to use hooks to do some automated work in a repository
    1.48 -that a number of people have shared access to, you need to be careful
    1.49 -in how you do this.
    1.50 -
    1.51 -Mercurial only locks a repository when it is writing to the
    1.52 -repository, and only the parts of Mercurial that write to the
    1.53 -repository pay attention to locks.  Write locks are necessary to
    1.54 -prevent multiple simultaneous writers from scribbling on each other's
    1.55 -work, corrupting the repository.
    1.56 -
    1.57 -Because Mercurial is careful with the order in which it reads and
    1.58 -writes data, it does not need to acquire a lock when it wants to read
    1.59 -data from the repository.  The parts of Mercurial that read from the
    1.60 -repository never pay attention to locks.  This lockless reading scheme
    1.61 -greatly increases performance and concurrency.
    1.62 -
    1.63 -With great performance comes a trade-off, though, one which has the
    1.64 -potential to cause you trouble unless you're aware of it.  To describe
    1.65 -this requires a little detail about how Mercurial adds changesets to a
    1.66 -repository and reads those changes.
    1.67 -
    1.68 -When Mercurial \emph{writes} metadata, it writes it straight into the
    1.69 -destination file.  It writes file data first, then manifest data
    1.70 -(which contains pointers to the new file data), then changelog data
    1.71 -(which contains pointers to the new manifest data).  Before the first
    1.72 -write to each file, it stores a record of where the end of the file
    1.73 -was in its transaction log.  If the transaction must be rolled back,
    1.74 -Mercurial simply truncates each file back to the size it was before the
    1.75 -transaction began.
    1.76 -
    1.77 -When Mercurial \emph{reads} metadata, it reads the changelog first,
    1.78 -then everything else.  Since a reader will only access parts of the
    1.79 -manifest or file metadata that it can see in the changelog, it can
    1.80 -never see partially written data.
    1.81 -
    1.82 -Some controlling hooks (\hook{pretxncommit} and
    1.83 -\hook{pretxnchangegroup}) run when a transaction is almost complete.
    1.84 -All of the metadata has been written, but Mercurial can still roll the
    1.85 -transaction back and cause the newly-written data to disappear.
    1.86 -
    1.87 -If one of these hooks runs for long, it opens a window of time during
    1.88 -which a reader can see the metadata for changesets that are not yet
    1.89 -permanent, and should not be thought of as ``really there''.  The
    1.90 -longer the hook runs, the longer that window is open.
    1.91 -
    1.92 -\subsection{The problem illustrated}
    1.93 -
    1.94 -In principle, a good use for the \hook{pretxnchangegroup} hook would
    1.95 -be to automatically build and test incoming changes before they are
    1.96 -accepted into a central repository.  This could let you guarantee that
    1.97 -nobody can push changes to this repository that ``break the build''.
    1.98 -But if a client can pull changes while they're being tested, the
    1.99 -usefulness of the test is zero; an unsuspecting someone can pull
   1.100 -untested changes, potentially breaking their build.
   1.101 -
   1.102 -The safest technological answer to this challenge is to set up such a
   1.103 -``gatekeeper'' repository as \emph{unidirectional}.  Let it take
   1.104 -changes pushed in from the outside, but do not allow anyone to pull
   1.105 -changes from it (use the \hook{preoutgoing} hook to lock it down).
   1.106 -Configure a \hook{changegroup} hook so that if a build or test
   1.107 -succeeds, the hook will push the new changes out to another repository
   1.108 -that people \emph{can} pull from.
   1.109 -
   1.110 -In practice, putting a centralised bottleneck like this in place is
   1.111 -not often a good idea, and transaction visibility has nothing to do
   1.112 -with the problem.  As the size of a project---and the time it takes to
   1.113 -build and test---grows, you rapidly run into a wall with this ``try
   1.114 -before you buy'' approach, where you have more changesets to test than
   1.115 -time in which to deal with them.  The inevitable result is frustration
   1.116 -on the part of all involved.
   1.117 -
   1.118 -An approach that scales better is to get people to build and test
   1.119 -before they push, then run automated builds and tests centrally
   1.120 -\emph{after} a push, to be sure all is well.  The advantage of this
   1.121 -approach is that it does not impose a limit on the rate at which the
   1.122 -repository can accept changes.
   1.123 -
   1.124 -\section{A short tutorial on using hooks}
   1.125 +\subsection{Es posible hacer caso omiso de los ganchos}
   1.126 +
   1.127 +Mercurial le permite hacer caso omiso de la deficinión de un gancho,
   1.128 +a través de la redefinición del mismo. Usted puede deshabilitar el
   1.129 +gancho fijando su valor como una cadena vacía, o cambiar su
   1.130 +comportamiento como desee.
   1.131 +
   1.132 +Si usted instala un fichero \hgrc\ a nivel de sistema o sitio completo
   1.133 +que define algunos ganchos, debe entender que sus usuarios pueden
   1.134 +deshabilitar o hacer caso omiso de los mismos.
   1.135 +
   1.136 +\subsection{Asegurarse de que ganchos críticos sean ejecutados}
   1.137 +
   1.138 +Algunas veces usted puede querer hacer respetar una política, y no
   1.139 +permitir que los demás sean capaces de evitarla. Por ejemplo, usted
   1.140 +puede tener como requerimiento que cada conjunto de cambios debe pasar
   1.141 +un riguroso conjunto de pruebas. Definir este requerimientos a través
   1.142 +de un gancho en un fichero \hgrc\ global no servirá con usuarios
   1.143 +remotos en computadoras portátiles, y por supuesto que los usuarios
   1.144 +locales pueden evitar esto a voluntad haciendo caso omiso del gancho.
   1.145 +
   1.146 +En vez de eso, usted puede definir las políticas para usar Mercurial
   1.147 +de tal forma que se espere que los usuarios propaguen los cambios a
   1.148 +través de un servidor ``canónico'' bien conocido que usted ha
   1.149 +asegurado y configurado apropiadamente.
   1.150 +
   1.151 +Una manera de hacer esto es a través de una combinación de ingeniería
   1.152 +socual y tecnología. Cree una cuenta de acceso restringido; los
   1.153 +usuarios pueden empujar cambios a través de la red a los repositorios
   1.154 +administrados por esta cuenta, pero no podrán ingresar a dicha cuenta
   1.155 +para ejecutar órdenes en el intérprete de comandos. En este escenario,
   1.156 +un usuario puede enviar un conjunto de cambios que contenga la
   1.157 +porquería que él desee.
   1.158 +
   1.159 +Cuando alguien empuja un conjunto de cambios al servidor del que todos
   1.160 +jalan, el servidor probará el conjunto de cambios antes de aceptarlo
   1.161 +como permanente, y lo rechazará si no logra pasar el conjunto de
   1.162 +pruebas. Si la gente sólo jala cambios desde este servidor de filtro,
   1.163 +servirá para asegurarse de que todos los cambios que la gente jala han
   1.164 +sido examinados automáticamente
   1.165 +
   1.166 +\section{Precauciones con ganchos \texttt{pretxn} en un repositorio de
   1.167 +acceso compartido}
   1.168 +
   1.169 +Si usted desea usar ganchos para llevar a cabo automáticamente algún
   1.170 +trabajo en un repositorio al que varias personas tienen acceso
   1.171 +compartido, debe tener cuidado con la forma de hacerlo.
   1.172 +
   1.173 +Mercurial sólo bloquea un repositorio cuando está escribiendo al
   1.174 +mismo, y sólo las partes de Mercurial que escriben al repositorio le
   1.175 +prestan atención a los bloqueos. Los bloqueos de escritura son
   1.176 +necesarios para evitar que múltiples escritores simultáneos
   1.177 +interfieran entre sí, corrompiendo el repositorio.
   1.178 +
   1.179 +Ya que Mercurial tiene cuidado con el orden en que lee y escribe
   1.180 +datos, no necesita adquirir un bloqueo cuando desea leer datos del
   1.181 +repositorio. Las partes de Mercurial que leen del repositorio nunca le
   1.182 +prestan atención a los bloqueos. Este esquema de lectura libre de
   1.183 +bloqueos incremententa en gran medida el desempeño y la concurrencia.
   1.184 +
   1.185 +Sin embargo, para tener un gran desempeño es necesario hacer
   1.186 +sacrificios, uno de los cuales tiene el potencial de causarle
   1.187 +problemas a menos de que usted esté consciente de él. Describirlo
   1.188 +requiere algo de detalle respecto a cómo Mercurial añade conjuntos de
   1.189 +cambios al repositorio y cómo lee esos cambios de vuelta.
   1.190 +
   1.191 +Cuando Mercurial \emph{escribe} metadatos, los escribe directamente en
   1.192 +el fichero de destino. Primero escribe los datos del fichero, luego
   1.193 +los datos del manifiesto (que contienen punteros a los nuevos datos
   1.194 +del fichero), luego datos de la bitácora de cambios (que contienen
   1.195 +punteros a los nuevos datos del manifiesto). Antes de la primera
   1.196 +escritura a cada fichero, se guarda un registro de dónde estaba el
   1.197 +final de fichero en su registro de transacciones. Si la transacción
   1.198 +debe ser deshecha, Mercurial simplemente trunca cada fichero de vuelta
   1.199 +al tamaño que tenía antes de que empezara la transacción.
   1.200 +
   1.201 +Cuando Mercurial \emph{lee} metadatos, lee la bitácora de cambios
   1.202 +primero, y luego todo lo demás. Como un lector sólo accederá a las
   1.203 +partes del manifiesto o de los metadatos de fichero que él puede ver
   1.204 +en la bitácora de cambios, nunca puede ver datos parcialmente
   1.205 +escritos.
   1.206 +
   1.207 +Algunos ganchos de control (\hook{pretxncommit} y
   1.208 +\hook{pretxnchangegroup}) se ejecutan cuando una transacción está casi
   1.209 +completa. Todos los metadatos han sido escritos, pero Mercurial aún
   1.210 +puede deshacer la transacción y hacer que los datos recién escritos
   1.211 +desaparezcan.
   1.212 +
   1.213 +Si alguno de estos ganchos permanece en ejecución por mucho tiempo,
   1.214 +abre una ventana de tiempo en la que un lector puede ver los metadatos
   1.215 +de conjuntos de cambios que aún no son permanentes y que no debería
   1.216 +considerarse que estén ``realmante ahí''. Entre más tiempo tome la
   1.217 +ejecución del gancho, más tiempo estará abierta esta ventana.
   1.218 +
   1.219 +\subsection{Ilustración del problema}
   1.220 +
   1.221 +En principio, un buen uso del gancho \hook{pretxnchangegroup} sería
   1.222 +ensamblar y probar automáticamente todos los cambios entrantes antes
   1.223 +de que sean aceptados en un repositorio central. Esto le permitiría a
   1.224 +usted garantizar que nadie pueda empujar cambios que ``rompan el
   1.225 +ensamblaje''. Pero si un cliente puede jalar cambios mientras están
   1.226 +siendo probados, la utilidad de esta prueba es nula; alguien confiado
   1.227 +puede jalar cambios sin probar, lo que potencialmente podría romper su
   1.228 +proceso de ensamblaje.
   1.229 +
   1.230 +La respuesta técnica más segura frente a este retos es montar dicho
   1.231 +repositorio ``guardián'' como \emph{unidireccional}. Permita que
   1.232 +reciba cambios desde el exterior, pero no permita que nadie jale
   1.233 +cambios de él (use el gancho \hook{preoutgoing} para bloquear esto).
   1.234 +Configure un gancho \hook{changegroup} para que si el ensamblaje o
   1.235 +prueba tiene éxito, el gancho empuje los nuevos cambios a otro
   1.236 +repositorio del que la gente \emph{pueda} jalar.
   1.237 +
   1.238 +En la práctica, montar un cuello de botella centralizado como éste a
   1.239 +menudo no es una buena idea, y la visibilidad de las transacciones no
   1.240 +tiene nada que ver con el problema. A medida que el tamaño de un
   1.241 +proyecto---y el tiempo que toma ensamblarlo y probarlo---crece, usted
   1.242 +se acerca rápidamente a un límite con este enfoque ``pruebe antes de
   1.243 +comprar'', en el que tiene más conjuntos de cambios a probar que
   1.244 +tiempo para ocuparse de ellos. El resultado inevitable es frustración
   1.245 +para todos los que estén involucrados.
   1.246 +
   1.247 +Una aproximación que permite manejar mejor el crecimiento es hacer que
   1.248 +la gente ensamble y pruebe antes de empujar, y ejecutar el ensamble y
   1.249 +pruebas automáticas centralmente \emph{después} de empujar, para
   1.250 +asegurarse de que todo esté bien. La ventaja de este enfoque es que no
   1.251 +impone un límite a la rata en la que un repositorio puede aceptar
   1.252 +cambios.
   1.253 +
   1.254 +\section{Tutorial corto de uso de ganchos}
   1.255  \label{sec:hook:simple}
   1.256  
   1.257  It is easy to write a Mercurial hook.  Let's start with a hook that