aboutsummaryrefslogtreecommitdiff
path: root/es_ES.ISO8859-1/articles/p4-primer/article.xml
blob: 55023fe416ae477bbf069dec856afc2016143327 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V4.2-Based Extension//EN"
	"../../../share/xml/freebsd42.dtd" [
<!ENTITY % entities PUBLIC "-//FreeBSD//ENTITIES DocBook FreeBSD Entity Set//ES" "../../share/xml/entities.ent">
%entities;
]>

<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 role="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
	  role="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 role="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
    role="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
    role="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
    role="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>