doc/es_ES.ISO8859-1/articles/p4-primer/article.xml
Gabor Kovesdan a6684b4306 - Reduce the misuse of role attribute; role="directory" should actually be
class="directory"
- Add constraint to enforce this
2013-04-04 11:40:58 +00:00

987 lines
41 KiB
XML

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V4.5-Based Extension//EN"
"../../../share/xml/freebsd45.dtd">
<article lang='es'>
<title><application>Perforce</application> en el contexto del desarrollo de &os;</title>
<articleinfo>
<authorgroup>
<author>
<firstname>Scott</firstname>
<surname>Long</surname>
<affiliation>
<address><email>scottl@FreeBSD.org</email>
</address>
</affiliation>
</author>
</authorgroup>
<legalnotice id="trademarks" role="trademarks">
&tm-attrib.freebsd;
&tm-attrib.cvsup;
&tm-attrib.general;
</legalnotice>
<pubdate>$FreeBSD$</pubdate>
<releaseinfo>$FreeBSD$</releaseinfo>
</articleinfo>
<sect1 id="intro">
<title>Introducción</title>
<para>El proyecto &os; utiliza el sistema de control de versiones
<application>Perforce</application> para gestionar proyectos
experimentales que todavía no están listos para ser
incluidos en el repositorio principal de CVS.</para>
<sect2 id="resources">
<title>Disponibilidad, documentación y recursos</title>
<para>Aunque que el producto <application>Perforce</application>
es un producto comercial, el software cliente que se encarga de
interactuar con el servidor se distribuye libremente. Pueden
descargarse versiones binarias del mismo desde el
sitio web de <application>Perforce</application>:
<ulink url="http://www.perforce.com/perforce/loadprog.html"></ulink>.
</para>
<para>Existe un cliente gráfico, pero la mayoría de la gente
utiliza la aplicación de línea de órdenes,
<command>p4</command>. Este documento trata sobre el uso de
dicha herramienta para la línea de órdenes.</para>
<para>En
<ulink url="http://www.perforce.com/perforce/technical.html"></ulink>
encontrará documentación <quote>online</quote>
detallada.</para>
<para>Se recomienda encarecidamente leer la <quote>guía de
usuario</quote> y el <quote>manual de Perforce</quote>.
La aplicación <application>p4</application> dispone de una extensa
ayuda <quote>online</quote> a la que puede accederse mediante la
orden <command>p4 help</command>.</para>
<para>El servidor &os; <application>Perforce</application> se
encuentra en
<hostid role="fqdn">perforce.freebsd.org</hostid>,
puerto <literal>1666</literal>. Puede navegar por el
repositorio desde
<ulink url="http://perforce.freebsd.org"></ulink>.
Ciertas partes del repositorio se exportan automáticamente hacia
diversos servidores <application>CVSup</application>.</para>
</sect2>
</sect1>
<sect1 id="start">
<title>Los comienzos</title>
<para>El primer paso para utilizar
<application>Perforce</application> consiste en obtener una cuenta
en el servidor. Si ya dispone de una cuenta en
<hostid
role="domainname">FreeBSD.org</hostid>
entre en
<hostid
role="hostname">freefall</hostid>
y ejecute el siguiente comando utilizando una contraseña distinta
del acceso de su &os; o de cualquier otro mecanismo de
autenticación SSH:</para>
<screen>&prompt.user; <userinput>/usr/local/bin/p4newuser</userinput></screen>
<para>Por supuesto si no tiene una cuenta en
<hostid
role="domainname">FreeBSD.org</hostid>
necesitará coordinarse con su mentor.</para>
<para>El siguiente paso consiste en establecer las variables de
entorno que necesita <command>p4</command> y en verificar
que puede conectarse al servidor. Es necesario especificar la variable
<envar>P4PORT</envar> para realizar cualquier operación. Dicha
variable indica el servidor <application>Perforce</application>
con el que se va a trabajar. En el caso del Proyecto &os;, créela
con el siguiente valor:</para>
<screen>&prompt.user; <userinput>export P4PORT=perforce.freebsd.org:1666</userinput></screen>
<note>
<para>Los usuarios con acceso <quote>shell</quote> al
<quote>cluster</quote>
<hostid
role="domainname">FreeBSD.org</hostid>
pueden querer encapsular el protocolo cliente-servidor de
<application>Perforce</application> a través de un
túnel SSH, en cuyo caso la variable de arriba
debería establecerse al valor
<literal>localhost</literal>.</para>
</note>
<para>El servidor &os; también necesita que se establezcan las
variables <envar>P4PASSWD</envar> y <envar>P4USER</envar>. Utilice
el nombre de usuario y la contraseña anteriores del siguiente
modo:</para>
<screen>&prompt.user; <userinput>export P4USER=<replaceable>nombre_de_usuario</replaceable></userinput>
&prompt.user; <userinput>export P4PASSWD=<replaceable>contraseña</replaceable></userinput></screen>
<para>Compruebe que todo funciona mediante la siguiente
orden:</para>
<screen>&prompt.user; <userinput>p4 info</userinput></screen>
<para>A resultas de esta orden debería ver información
referente al servidor. Si no es así compruebe que
la variable <envar>P4PORT</envar> tiene el valor correcto.
</para>
</sect1>
<sect1 id="clients">
<title>Clientes</title>
<para>El sistema <application>Perforce</application> proporciona
acceso al repositorio y mantiene el estado del cliente de forma
individualizada. En términos de
<application>Perforce</application>, un cliente es una
especificación que asocia
<footnote><para>
Este término, que también puede traducirse como
asociar o asignar, suele aparecer en la jerga de la
administración de sistemas como
<quote>mapear</quote>.
</para></footnote>
ficheros y directorios desde el
repositorio hasta la máquina local. Cada usuario puede poseer
varios clientes, y cada cliente puede acceder a distintas partes
del repositorio (incluso a varias partes que se solapan entre sí).
El cliente también especifica el directorio raíz del
árbol de
directorios sobre el que se realiza la asociación y la
máquina
donde efectivamente está dicho árbol. Es por esto que
si pretende trabajar en varias máquinas tendrá que
usar varios clientes.
</para>
<para>Puede acceder a los clientes mediante
<command>p4 client</command>. Si se ejecuta esta orden sin
argumentos aparece una plantilla del cliente dentro de un
editor, permitiendo de esta forma crear un nuevo cliente. Los
campos importantes de esta plantilla se explican a
continuación:</para>
<variablelist>
<varlistentry>
<term><literal>Client:</literal></term>
<listitem>
<para>Este es el nombre de la especificación del cliente.
Puede ser cualquier cosa, pero debe ser una cadena única
dentro del servidor <application>Perforce</application>. Suelen
usarse nombres como
<literal><replaceable>nombre_de_usuario</replaceable>_<replaceable>nombre_de_máquina</replaceable></literal>,
que permite identificar fácilmente a los clientes cuando se
navega por ellos.
Por defecto hay ya un nombre, que se
corresponde con el nombre de la máquina.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>Description:</literal></term>
<listitem>
<para>Este campo suele consistir en un breve texto descriptivo
que ayude a identificar al cliente.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>Root:</literal></term>
<listitem>
<para>Se trata del directorio local que actuará como
directorio raíz para todos los ficheros dentro de la
asociación en el cliente.
Debe ser una localización única
dentro del sistema
de ficheros que no se solape con otros ficheros o clientes
<application>Perforce</application>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>Options:</literal></term>
<listitem>
<para>La mayoría de las opciones por defecto son correctas y
válidas para todo el mundo, aunque suele ser recomendable
comprobar que estén activadas las opciones
<option>compress</option> y <option>rmdir</option>
y que no tienen el prefijo <literal>no</literal>. Los
detalles de cada una de estas opciones están en la
documentación de <application>Perforce</application>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>LineEnd:</literal></term>
<listitem>
<para>Este parámetro gestiona las conversiones CR-LF y debe
dejarse tal cual salvo que sus necesidades específicas
requieran cambiarlo.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>View:</literal></term>
<listitem>
<para>Aquí es donde están las asociaciones de ficheros
servidor-a-local.
El valor por defecto es:</para>
<programlisting>//depot/... //<replaceable>cliente</replaceable>/...</programlisting>
<para>Esto asociará por completo el repositorio
<application>Perforce</application> al directorio
<filename class="directory">Root</filename>
del cliente. <emphasis>NO USE ESTE VALOR POR DEFECTO</emphasis>.
El repositorio de &os; es enorme e intentar asociarlo y
sincronizarse con dicho repositorio tardará muchísimo y
consumirá enormes recursos. Asocie
sólamente la sección del repositorio en la que va a
trabajar. Por ejemplo, hay un árbol para el proyecto
smpng en <filename
class="directory">//depot/projects/smpng</filename>. Una
asociación en ese caso sería algo así:</para>
<programlisting>//depot/projects/smpng/... //<replaceable>cliente</replaceable>/...</programlisting>
<para>Los <literal>...</literal> deben tomarse literalmente
tal cual están. Es un dialecto de
<application>Perforce</application> para decir <quote>este
directorio y todos los ficheros y directorios por debajo de
él.</quote>.</para>
<para>Una <quote>vista</quote> (View) puede contener múltiples
asociaciones. Vamos a suponer que quiere asociar los
árboles de SMPng
y de NFS. Su <quote>View</quote> sería algo
así:</para>
<programlisting>//depot/projects/smpng/... //<replaceable>cliente</replaceable>/smpng/...
//depot/projects/nfs/... //<replaceable>cliente</replaceable>/nfs/...</programlisting>
<para>Recuerde que <replaceable>cliente</replaceable> es el
nombre del cliente que se especificó en la sección
<literal>Client</literal>, pero en la sección
<literal>View</literal> además se utiliza para resolver al
directorio especificado en la sección
<literal>Root</literal>.</para>
<para>También tenga en cuenta que el mismo fichero o
directorio no puede asociarse más de una vez dentro de una
única vista. La orden del siguiente ejemplo no es correcta
y producirá resultados imprevistos:
</para>
<programlisting>//depot/projects/smpng/... //<replaceable>cliente</replaceable>/smpng-esto/...
//depot/projects/smpng/... //<replaceable>cliente</replaceable>/smpng-lo_otro/...</programlisting>
<para>Las <quote>vistas</quote> son la parte compleja del proceso de
aprendizaje de <application>Perforce</application>, así que
no tenga miedo de hacer tantas preguntas como estime
oportunas.</para>
</listitem>
</varlistentry>
</variablelist>
<para>Puede listar los clientes existentes mediante
<command>p4 clients</command>. Puede listarlos sin que sufran
modificaciones mediante <command>p4 client -o
<replaceable>nombre_cliente</replaceable></command>.</para>
<para>Siempre que se interactue con ficheros en
<application>Perforce</application> la variable de entorno
<envar>P4CLIENT</envar> debe contener al nombre del cliente que
se está utilizando, es decir:</para>
<screen>&prompt.user; <userinput>export P4CLIENT=<replaceable>nombredemicliente</replaceable></userinput></screen>
<para>Fíjese en que las asociaciones del cliente en el repositorio
no son exclusivos; varios clientes pueden estar asociados en la
misma zona del respositorio.
Esto permite el trabajo en equipo sobre el mismo
código, permitiendo que distintas personas accedan y
modifiquen la misma parte del respositorio.
</para>
</sect1>
<sect1 id="syncing">
<title>Sincronizaciones</title>
<para>Una vez definida la especificación del cliente y una vez
establecida la variable de entorno <envar>P4CLIENT</envar>, el
siguiente paso consiste en recuperar los ficheros para el cliente en
cuestión desde el servidor hasta la máquina local.
Esto se realiza
con <command>p4 sync</command>, el cual indica a
<application>Perforce</application> que sincronice los ficheros
locales con los del repositorio. La primera vez que se ejecuta
descargará todos los ficheros. Las siguientes ejecuciones
sólo descargarán aquellos ficheros que hayan cambiado
desde la última ejecución de la orden.
Gracias a esto es posible sincronizar sus fuentes con
las de otras personas con las que esté trabajando.</para>
<para>Las operaciones de sincronización sólo
atañen a aquellos ficheros cuyas modificaciones han
sido transmitidas a <application>Perforce</application>.
Si se modifica o borra un fichero en local sin informar de ello
al servidor la ejecución de un
<quote>sync</quote> no reflejará dichos cambios. No obstante, la
ejecución de <command>p4 sync -f</command> sincrozará
incondicionalmente todos los ficheros, sin que importe su estado.
Esto resulta útil para solucionar problemas cuando se cree que el
árbol pueda haber sufrido algún tipo de
corrupción.</para>
<para>Puede sincronizarse parte del árbol o del cliente
especificando una ruta relativa a la orden <quote>sync</quote>.
Por ejemplo, para sincronizar sólo el directorio
<filename class="directory">ufs</filename>
del proyecto <literal>smpng</literal> ejecute lo
siguiente:</para>
<screen>&prompt.user; <userinput>cd <replaceable>raizdelproyecto</replaceable>/smpng</userinput>
&prompt.user; <userinput>p4 sync src/sys/ufs/...</userinput></screen>
<para>El uso de rutas locales relativas funciona en muchas otras
órdenes <command>p4</command>.</para>
</sect1>
<sect1 id="branches">
<title>Ramas</title>
<para>Una de las características más interesantes de
<application>Perforce</application> es la posibilidad de crear
ramas. Las ramas son muy sencillas de crear y también resulta muy
fácil mover cambios entre distintas ramas (como se verá
más
adelante). Las ramas también nos permiten realizar trabajos muy
experimentales dentro de un entorno de <quote>sandbox</quote>, sin
necesidad de tener que preocuparnos por las colisiones con otros
usuarios o por desestabilizar el árbol principal. Además,
las ramas
proporcionan el aislamiento necesario frente a los errores que se
cometen cuando se aprende a manejar el sistema
<application>Perforce</application>. Vistas estas ventajas es
lógico que cada proyecto disponga de su propia rama y
en &os; recomendamos encarecidamente este esquema.
También se recomienda la aplicación frecuente de los cambios
realizados.</para>
<para>El repositorio <application>Perforce</application> (conocido
como el <quote>depósito</quote>, o <quote>depot</quote> en
la jerga de <application>Perforce</application>)
es un único árbol plano. Se accede a cada fichero a
través de una
sencilla ruta bajo el directorio <filename
class="directory">//depot</filename>, tanto si se trata de un
fichero de nueva creación como si proviene de una
ramificación.
Esto supone una gran diferencia con respecto a sistemas como CVS,
donde cada rama se encuentra en la misma ruta que su rama padre.
En <application>Perforce</application> el servidor mantiene las
relaciones entre los ficheros padre e hijo, pero los
ficheros en sí están bajo sus propias rutas.</para>
<para>El primer para para crear una rama consiste en crear una
especificación de rama. Es similar a la especificación
de un cliente,
pero se crea mediante la orden <command>p4 branch
<replaceable>nombre_de_rama</replaceable></command>.</para>
<para>Veamos los campos más importantes:</para>
<variablelist>
<varlistentry>
<term><literal>Branch</literal></term>
<listitem>
<para>El nombre de la rama. Puede ser cualquier nombre, pero
debe ser único en el repositorio. La convención
que se usa en &os; es
<replaceable>nombre_de_usuario</replaceable>_<replaceable>nombre_del_proyecto</replaceable>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>Description</literal></term>
<listitem>
<para>Puede poner aquí un texto simple que describa la
rama.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>View</literal></term>
<listitem>
<para>Esto es la asociación de la rama. En lugar de asociar
desde el <quote>depósito</quote> hacia la máquina local
como una asociación de cliente, se crea una asociación
entre la rama padre y la rama hija
dentro del <quote>depósito</quote>. Por ejemplo, puede
querer crear una rama del proyecto smpng. La asociación
resultaría en algo parecido a esto:</para>
<programlisting>//depot/projects/smpng/... //depot/projects/mi-super-smpng/...</programlisting>
<para>O puede crear una rama totalmente nueva a
partir de las fuentes de &os;:</para>
<programlisting>//depot/vendor/freebsd/... //depot/projects/mi-nuevo-proyecto/...</programlisting>
<para>Esto asociará el HEAD del árbol de &os; a su
nueva rama.</para>
</listitem>
</varlistentry>
</variablelist>
<para>La creación de la especificación de rama
únicamente graba la
especificación en sí misma dentro del servidor. No
modifica el <quote>depósito</quote> ni cambia
ningún fichero. El directorio que se declara en la rama
permanece vacío en el servidor hasta que se comience a
llenar.
</para>
<para>Para rellenar la rama primero debemos editar el cliente con
la orden <command>p4 client</command> y asegurarnos de que el
directorio de rama está asociado en el cliente. Puede ser
necesario añadir una línea <literal>View</literal>
como esta:</para>
<programlisting>//depot/projects/mi-nuevo-proyecto/... //<replaceable>micliente</replaceable>/mi-nuevo-proyecto/...</programlisting>
<para>El siguiente paso consiste en ejecutar <command>p4
integrate</command>, como se describe en la siguiente
sección.</para>
</sect1>
<sect1 id="Integrations">
<title>Integraciones</title>
<para><quote>Integración</quote> es el término que se utiliza
en <application>Perforce</application> para describir la acción de
mover cambios desde una parte del <quote>depósito</quote> a otra.
Se suele realizar junto con las órdenes creación y
mantenimiento de ramas. Una integración es necesaria cuando se
quiere rellenar inicialmente una rama y cuando se quieren mover cambios
realizados en la rama padre hacia la rama hija, o de la la rama hija
a la padre. Un caso muy común es la integración
periódica desde el árbol original de &os; hacia la rama
hija propia del usuario.
El servidor <application>Perforce</application>
mantiene el estado de los cambios en cada rama y sabe cuándo
hay cambios que pueden integrarse de una rama a otra.</para>
<para>La forma más común de hacer una integración
se muestra en la siguiente orden:
</para>
<screen>&prompt.user; <userinput>p4 integrate -b <replaceable>nombrederama</replaceable></userinput></screen>
<para><replaceable>nombrederama</replaceable> es el nombre que se
ha dado a la
especificación de rama, tal y como se explicó en la
sección anterior.
Esta orden indica a <application>Perforce</application> que
busque cambios en la rama padre que todavía no se hayan
aplicado a la rama hija. En base a los cambios encontrados se
prepara un listado de diferencias a aplicar. Si la integración
se realiza por primera vez sobre una rama (por ejemplo cuando se
realiza una operación de rellenado inicial) los ficheros
de la rama padre simplemente se copiarán en la ubicación
en la rama hija de la máquina local.</para>
<para>Una vez que la operación de integración ha finalizado
se debe ejecutar <command>p4 resolve</command>, que aplicará
los cambios y resolverá posibles conflictos.
Los conflictos puede surgir debido a
cambios que se solapan al encontrarse tanto en fichero de la rama
padre como en la copia del fichero de la rama hija. Normalmente no
suelen aparecer conflictos y <application>Perforce</application>
puede calcular rápidamente cómo unir los cambios.
Para ejecutar una operación de resolución
(<quote>resolve</quote>) utilice las siguientes órdenes:</para>
<screen>&prompt.user; <userinput>p4 resolve -as</userinput>
&prompt.user; <userinput>p4 resolve</userinput></screen>
<para>La primera invocación indica a
<application>Perforce</application> que una automáticamente los
cambios y que acepte aquellos ficheros que no den conflictos. La
segunda invocación permite inspeccionar cada fichero con conflictos
y resolver de forma manual dichas incompatiblidades.</para>
<para>Una vez hecha la integración de los ficheros llega el
momento de aplicar los cambios al repositorio. Para ello se
emplearemos la orden
<command>p4 submit</command>, cuyo uso se explica en la
siguiente sección.</para>
</sect1>
<sect1 id="submit">
<title>Aplicación de cambios en el repositorio</title>
<para>Los cambios que se han realizado en local se deben
aplicar en el contenido del servidor <application>Perforce</application>
para mayor seguridad frente a pérdidas y para que otras
personas puedan acceder a dichos cambios; esto se hace con la
orden <command>p4 submit</command>. Cuando se ejecuta esta
orden se abre una plantilla (<quote>submit template</quote>)
en el editor. &os; dispone de una platilla personalizada, de la
que a continuación se explican los campos más
importantes:</para>
<programlisting>Description:
&lt;enter description here&gt;
PR:
Submitted by:
Reviewed by:
Approved by:
Obtained from:
MFP4 after:</programlisting>
<para>es decir</para>
<programlisting>Descripción:
&lt;Introduzca una descripción&gt;
PR:
Enviado por:
Revisado por:
Aprobado por:
Obtenido de:
MFP4 tras:</programlisting>
<para>Se considera una buena práctica proporcionar al menos dos o
tres frases que describan los cambios entregados. Debería
declarar aquí qué hacen dichos cambios, por qué
se han hecho de esa forma o qué problemas intenta resolver
con ellos. También
conviene explicar qué APIs cambian y qué otros efectos
secundarios pueden tener.
Este texto debe sustituir a la línea <literal>&lt;enter
description here&gt;</literal> que aparece en la plantilla. Debe
recubrir las líneas y comenzar cada línea con una
tabulación. Las etiquetas de más abajo son
específicas de &os; y puede eliminarlas si no resultan
útiles o apropiadas en su contexto.</para>
<programlisting>Files:</programlisting>
<para>Este campo se rellena automáticamente con todos los ficheros
que el cliente etiquetó en el servidor con estados de
adición, borrado, integración o edición.
Le aconsejamos que revise esta lista y elimine de ella los ficheros
que todavía no esten listos.</para>
<para>Una vez guardada la sesión de su editor tiene lugar la entrega
de los datos al servidor. Esto significa que las copias locales de
los ficheros entregados se enviarán al servidor. Si algo va
mal durante este proceso se cancelará la entrega y se
avisará al usuario de que la entrega se ha convertido en
una lista de cambios que deben corregirse y reenviarse. Las
entregas son atómicas, es decir, si un fichero falla
la entrega se cancela en su totalidad.</para>
<para>Los cambios efectuados en el servidor no pueden cancelarse
una vez hechos, pero sí que pueden cancelarse si, dentro
aún del editor, se sale de él sin cambiar el
texto del campo
<literal>Description</literal>. <application>Perforce</application>
se quejará la primera vez que intente salir y le
devolverá al editor. Si sale por segunda vez el editor
cancelará la operación. Devolver el repositorio
al estado anterior a un cambio ya efectuado es un proceso
muy complicado y no hay un procedimiento estándar, por lo
que depende del caso concreto.</para>
</sect1>
<sect1 id="editing">
<title>Edición</title>
<para>En el servidor se almacena y mantiene el estado de cada
fichero del cliente. Para evitar colisiones entre distintas
personas trabajando al mismo tiempo en el mismo fichero
<application>Perforce</application> presta atención a qué
ficheros están abiertos en modo de edición, y utiliza
esa información para poder gestionar posteriormente las
operaciones de entrega, las sincronizaciones y las
integraciones.</para>
<para>Para abrir un fichero para editarlo utilice <command>p4
edit</command> de la siguiente forma:</para>
<screen>&prompt.user; <userinput>p4 edit <replaceable>nombredefichero</replaceable></userinput></screen>
<para>Esto marca el fichero en el servidor con el estado de
edición, lo que permite entregar el fichero posteriormente
una vez realizados los cambios oportunos, o lo etiqueta como de
tratamiento especial cuando se está efectuando una
operación de integración o sincronización.
Tenga en cuenta que la edición no es exclusiva en
<application>Perforce</application>. Varias personas pueden tener
el mismo fichero en estado de edición (será
informado de ello si es necesario cuando ejecute
<command>edit</command>), pero podrá entregar sus cambios
incluso cuando haya otras personas que tengan ese fichero en estado
de edición.</para>
<para>Cuando alguien entregue un cambio de un fichero que usted
esté editando necesitará cotejar sus modificaciones
con las de la otra u otras personas para poder aplicar
correctamente sus modifaciones al repositorio. La forma más
sencilla de hacerlo es ejecutar
<command>p4 sync</command> o <command>p4 submit</command> y dejar
que el programa encuentre algún conflicto, y a
continuación
ejecutar <command>p4 resolve</command> para <quote>resolver</quote>
manualmente los conflictos y aceptar los cambios de la otra persona
en su copia del fichero. Hecho esto, utilice <command>p4
submit</command> para aplicar sus cambios en el
repositorio.</para>
<para>Si posee un fichero abierto para su edición y
quiere descartar los cambios y devolverlo a su estado
original ejecute
<command>p4 revert</command> de la siguiente forma:</para>
<screen>&prompt.user; <userinput>p4 revert <replaceable>nombredefichero</replaceable></userinput></screen>
<para>Esto resincroniza el fichero con el contenido del servidor y
elimina en el servidor el atributo de edición para ese fichero.
Se perderá cualquier cambio que haya hecho en local.
Esto resulta muy útil cuando se han efectuado una serie de
cambios en un determinado fichero y se decide posteriormente que
no se desean aplicar dichos cambios en el servidor.</para>
<para>Cuando se sincroniza un fichero se marca como sólo lectura en
el sistema de ficheros. Aunque se pueden sobreescribir fácilmente
dichos permisos se aplican para recordar al usuario de una forma
educada que para ello se debe utilizar <command>p4 edit</command>.
Los ficheros modificados en local pero que no están en
estado de edición pueden sobreescribirse al ejecutar
<command>p4 sync</command>.</para>
</sect1>
<sect1 id="changes">
<title>Cambios, descripciones e historial</title>
<para>Puede ver el historial de cambios realizados al
<quote>depósito</quote> de
<application>Perforce</application> puede consultarse mediante
<command>p4 changes</command>. Esta orden proporciona una breve
descripción de cada cambio, quién la realizó
y cúal es el número de
modificación. Si lo que se quiere son los detalles
de un cambio en concreto utilice
<command>p4 describe
<replaceable>numero_de_cambio</replaceable></command>. Esta orden
proporciona el <quote>log</quote> y los
<quote>diffs</quote> de dicho cambio.
Normalmente se utilizan las opciones <option>-du</option> o
<option>-dc</option> para generar <quote>diffs</quote> unificados o
contextuales, respectivamente, en lugar del formato
del <quote>diff</quote> nativo.</para>
<para><command>p4 filelog <replaceable>nombre_de_fichero</replaceable></command>
muestra el historial de un fichero, incluyendo todas sus modificaciones,
integraciones y ramas que contenga.</para>
</sect1>
<sect1 id="diffs">
<title><quote>diffs</quote></title>
<para>Existen dos formas de generar <quote>diffs</quote> de ficheros en
<application>Perforce</application>, bien entre cambios locales
que todavía no se han entregado o bien entre dos
árboles (o dentro de una misma rama) del
<quote>depósito</quote>. Estos <quote>diffs</quote>
se generan mediante órdenes distintas,
<option>diff</option> y <option>diff2</option>:</para>
<variablelist>
<varlistentry>
<term><command>p4 diff</command></term>
<listitem>
<para>Ese comando genera un <quote>diff</quote> entre los cambios
locales y los cambios de ficheros en estado de edición. Los
parámetros <option>-du</option> y <option>-dc</option>
permiten crear <quote>diffs</quote> unificados o contextuales,
respectivamente. También se puede establecer la variable
<envar>P4DIFF</envar> para que apunte a un
<quote>diff</quote> local. Le recomendamos encarecidamente
usar esta orden para revisar sus cambios antes de
aplicarlos en el servidor.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>p4 diff2</command></term>
<listitem>
<para>Esta orden crea un <quote>diffs</quote> entre ficheros
dados en el <quote>depósito</quote>, o entre
ficheros especificados en una especificación de rama. La
operación tiene lugar en el servidor, así que
la variable <envar>P4DIFF</envar> no surte ningún efecto,
aunque las opciones <option>-du</option> y
<option>-dc</option> sí pueden usarse. Las dos formas de
esta orden son:</para>
<screen>&prompt.user; <userinput>p4 diff2 -b <replaceable>nombrederama</replaceable></userinput></screen>
<para>y</para>
<screen>&prompt.user; <userinput>p4 diff2 //depot/<replaceable>ruta1</replaceable> //depot/<replaceable>ruta2</replaceable></userinput></screen>
</listitem>
</varlistentry>
</variablelist>
<para>En todos los casos los <quote>diffs</quote> se muestran en la salida
estándar. Por desgracia <application>Perforce</application>
usa un formato de <quote>diffs</quote> que resulta ser ligeramente
incompatible con las herramientas Unix estándar
<command>diff</command> y <command>patch</command>. La utilización
de la variable <envar>P4DIFF</envar> para que apunte al verdadero
&man.diff.1; puede paliar este problema, o al menos en ciertos casos,
puesto sólo funciona con la orden
<command>p4 diff</command>. La salida de
<option>diff2</option> debe procesarse para que sea de alguna
utilidad (la opción <option>-u</option> de
<option>diff2</option> producirá <quote>diffs</quote>
unificados que serán <emphasis>más o menos
compatibles</emphasis>, pero no esto no incluye ficheros
nuevos o borrados. Este <quote>script</quote> puede serle
de utilidad para este <quote>proceso necesario</quote>:
<ulink
url="http://people.freebsd.org/~scottl/awkdiff"></ulink>.</para>
</sect1>
<sect1 id="add-rm-files">
<title>Añadir o eliminar ficheros</title>
<para>La integración de una rama hará que
se añadan ficheros existentes en el servidor en su
árbol, pero quizás sea necesario añadir
nuevos ficheros o eliminar alguno de los ya existentes.
Para añadir ficheros no tiene más que
crear el fichero y ejecutar
<command>p4 add</command> de la siguiente forma:</para>
<screen>&prompt.user; <userinput>p4 add <replaceable>nombredefichero</replaceable></userinput></screen>
<para>Si quiere añadir un árbol completo de ficheros
ejecute:</para>
<screen>&prompt.user; <userinput>find . -type f |xargs p4 add</userinput></screen>
<para>Al ejecutar <command>p4 submit</command> se copiarán los
ficheros al <quote>depósito</quote> del servidor.
Es muy importante añadir
sólo ficheros y no directorios. Si se añade
explícitamente un
directorio, <application>Perforce</application> lo tratará como
fichero, lo cual seguramente no es lo que usted tenía
previsto.</para>
<para>Borrar un fichero es igualmente sencillo mediante
<command>p4 delete</command>:</para>
<screen>&prompt.user; <userinput>p4 delete <replaceable>nombredefichero</replaceable></userinput></screen>
<para>Esta orden marcará el fichero para que sea borrado del
<quote>depósito</quote> la siguiente vez que se ejecute una
entrega.
También borrará la copia local del fichero, así que
sea cauteloso cuando la use.</para>
<para>Por supuesto que borrar un fichero no significa que se borre
realmente del repositorio.</para>
<para>Los ficheros borrados se pueden <quote>resucitar</quote>
mediante la sincronización con una versión
previa. La única forma de borrar de forma permanente un
fichero es mediante la orden <command>p4 obliterat</command>.
Dicha orden es irreversible y costosa, así que sólo
está al alcance del personal que administra
el repositorio.</para>
</sect1>
<sect1 id="working-with-diffs">
<title>El trabajo con <quote>diffs</quote></title>
<para>Algunas veces puede ser necesario aplicar un <quote>diff</quote>
al árbol
de <application>Perfoce</application> que provenga de otra
aplicación. Si se trata de un <quote>diff</quote>
de gran tamaño y que afecta a muchos ficheros, puede resultar
tedioso ejecutar manualmente <command>p4 edit</command> sobre cada
fichero. Hay un truco para hacerlo de una forma más sencilla.
En primer lugar, asegúrese de que no hay ficheros abiertos en su
cliente y de que su árbol está sincronizado y actualizado a la
última versión. A continuación aplique
sus cambios mediante las herramientas habituales, y forzando los
permisos de los ficheros en caso de ser necesario. Después
ejecute lo siguiente:</para>
<screen>&prompt.user; <userinput>p4 diff -se ... |xargs p4 edit</userinput>
&prompt.user; <userinput>p4 diff -sd ... |xargs p4 delete</userinput>
&prompt.user; <userinput>find . -type f |xargs p4 add</userinput></screen>
<para>La primera orden le dice a
<application>Perforce</application> que busque los ficheros que
han cambiado, incluso si no están abiertos. La segunda
orden le dice a <application>Perforce</application> que busque
los ficheros que no existen en la máquina local pero que
sí están en el servidor. La tercera orden intenta
añadir todos los ficheros que están en local. Es
un método de fuerza bruta, pero funciona bien porque
<application>Perforce</application> sólo añadirá
los ficheros que le resulten desconocidos. El resultado de estas
órdenes es un conjunto de ficheros abiertos para edición,
borrado o para ser añadidos, según el caso. Hecho
esto solo nos queda ejecutar
<command>p4 submit</command> para entregar los cambios.</para>
</sect1>
<sect1 id="renaming-files">
<title>Cambiar nombres de ficheros</title>
<para><application>Perforce</application> no dispone de una forma
predefinida de cambiar nombres a ficheros o de moverlos a otra parte
del árbol. Si se copia el fichero en
cuestión a una nueva ubicación mediante <command>p4
add</command>, y posteriormente <command>p4
delete</command> en la versión anterior, se obtiene
algo muy parecido a lo que se quería, pero tiene el
inconveniente de que no se preserva el historial de cambios
de ese fichero. Esto puede perjudicar futuras integraciones entre
padres e hijos. Hay otro método más recomendable,
que consiste en efectuar una integración dentro del
mismo árbol y de una sola vez. Veamos un ejemplo:</para>
<screen>&prompt.user; <userinput>p4 integrate -i <replaceable>ficheroprevio</replaceable> <replaceable>ficheronuevo</replaceable></userinput>
&prompt.user; <userinput>p4 resolve</userinput>
&prompt.user; <userinput>p4 delete <replaceable>ficheroprevio</replaceable></userinput>
&prompt.user; <userinput>p4 submit</userinput></screen>
<para>La integración fuerza a <application>Perforce</application> a
mantener un registro de las relaciones entre los nombres antiguos y
los nuevos, lo cual será muy útil en futuras
integraciones. La opción
<option>-i</option> indica que se trata de una integración
<quote>sin base</quote>, es decir, que no existe un historial de
ramas al que recurrir en la integración. Este
parámetro tiene sentido en el presente ejemplo, pero
no debería utilizarse en integraciones basadas en ramas.</para>
</sect1>
<sect1 id="freebsd-cvs-and-p4">
<title>Interacciones entre el CVS de &os; y Perforce</title>
<para>Los repositorios de
<application>Perforce</application> y de CVS de &os; están
completamente separados. No obstante, los cambios que se producen
en CVS se reflejan casi en tiempo real en
<application>Perforce</application>. Cada 2 minutos se pregunta al
servidor de CVS sobre cambios realizados en la rama HEAD, y dichos
cambios se entregan a <application>Perforce</application> dentro del
árbol <filename
class="directory">//depot/vendor/freebsd/...</filename>.
De este modo este árbol permite la ramificación y
la integración de proyectos derivados. Cualquier proyecto
que implique la modificación del código fuente de
&os; debería tener este árbol como su rama padre
(o rama <quote>abuela</quote>, dependiendo
de las necesidades concretas de cada proyecto), y deberían tener
lugar integraciones periódicas y sincronizaciones para que el
árbol esté en consonancia con el desarrollo de &os; y
evitar conflictos en la medida de lo posible.</para>
<para>El puente entre CVS y <application>Perforce</application> es
de un sólo sentido; los cambios del CVS se reflejarán en
<application>Perforce</application>, pero los cambios en
<application>Perforce</application> no se reflejarán en el CVS.
Si es necesario, se pueden exportar partes del repositorio de
<application>Perforce</application> al
<application>CVSup</application> y que así se puedan distribuir.
Por favor, contacte con los
administradores de <application>Perforce</application> de &os; si
ese es su caso.</para>
</sect1>
<sect1 id="offline-ops">
<title>Funcionamiento sin conexión de red</title>
<para>Uno de los inconvenientes de <application>Perforce</application> es
que supone que siempre es posible acceder al servidor a través
de la red. La mayoría de los estados, el historial y los
metadatos se almacenan en el servidor y no existe mecanismo alguno
para replicar el servidor como los hay en
CVS/<application>CVSup</application>. Es posible
ejecutar un servidor proxy, pero solamente ayuda un poco si se quiere
trabajar sin conexión al servidor.</para>
<para>La mejor forma de trabajar sin conexión de red es
comprobando que el cliente no tiene ningún fichero abierto y
que está totalmente sincronizado antes de dejar de estar
conectado.
Cuando se edite un fichero se deberán cambiar manualmente
los permisos a lectura-escritura. Cuando vuelva a estar
conectado ejecute la orden que se mostraba
en la <xref linkend="working-with-diffs"/> para
identificar automáticamente los ficheros que se han editado,
añadido o eliminado.
Es bastante común encontrarse con la sorpresa de que
<application>Perforce</application> ha sobreescrito un fichero
modificado en local que no se abrió en modo edición,
así que tenga especial cuidado con esto.</para>
</sect1>
<sect1 id="soc">
<title>Consideraciones finales para el <quote>Google Summer of Code</quote></title>
<para>La mayoría de los proyectos de &os; dentro del programa
<quote>Google Summer of Code</quote> están en
<filename
class="directory">//depot/projects/soc2005/<replaceable>nombre_del_proyecto</replaceable>/...</filename>
en el servidor &os; de <application>Perforce</application>.</para>
<para>Entre las responsabilidades del mentor del proyecto
está seleccionar un nombre adecuado para dicho proyecto y
hacer que el estudiante sea capaz de trabajar con
<application>Perforce</application>.</para>
<para>El acceso al servidor &os; de
<application>Perforce</application> no implica pasar a ser miembro
de la comunidad de committers del CVS de &os;, aunque animamos
de todo corazón a todos los estudiantes que consideren la
posibilidad de unirse al proyecto cuando estén listos
para ello.</para>
</sect1>
</article>