hgbook / es / hook.tex

   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
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
\chapter{Manejo de eventos en repositorios mediante ganchos}
\label{chap:hook}

Mercurial ofrece un poderoso mecanismo para permitirle a usted
automatizar la ejecución de acciones en respuesta a eventos que
ocurran en un repositorio. En algunos casos, usted puede controlar
incluso la respuesta de Mercurial a dichos eventos.

Mercurial usa el término \emph{gancho} para identificar estas
acciones. Los ganchos son conocidos como ``disparadores'' en algunos
sistemas de control de revisiones, pero los dos nombres se refieren al
mismo concepto.

\section{Vistazo general de ganchos en Mercurial}

A continuación se encuentra una breve lista de los ganchos que
Mercurial soporta. Volveremos a cada uno de estos ganchos con más
detalle después, en la sección~\ref{sec:hook:ref}.

\begin{itemize}
\item[\small\hook{changegroup}] Es ejecutado luego de que un grupo de
    conjuntos de cambios ha sido traído al repositorio desde algún
    otro sitio.
\item[\small\hook{commit}] Es ejecutado después de la creación de
    un conjunto de cambios en el repositorio local.
\item[\small\hook{incoming}] Es ejecutado una vez por cada conjunto de
    cambios traído al repositorio desde otra ubicación. Note la
    diferencia respecto al gancho \hook{changegroup}, que es ejecutado
    una vez por cada \emph{grupo} de conjuntos de cambios que se
    traiga.
\item[\small\hook{outgoing}] Es ejecutado luego de que un grupo de
    conjuntos de cambios ha sido transmitido desde el repositorio.
\item[\small\hook{prechangegroup}] Es ejecutado antes de iniciar la
    recepción de un grupo de conjuntos de cambios en el repositorio.
\item[\small\hook{precommit}] De control. Es ejecutado antes de
    iniciar una consignación.
\item[\small\hook{preoutgoing}] De control. Es ejecutado antes de
    iniciar la transmisión de un grupo de conjuntos de cambios desde
    el repositorio.
\item[\small\hook{pretag}] De control. Es ejecutado antes de crear una
    etiqueta.
\item[\small\hook{pretxnchangegroup}] De control. Es ejecutado después
    de haber recibido un grupo de conjuntos de cambios en el
    repositorio local, pero antes de que la transacción se complete y
    los cambios sean permanentes dentro del repositorio.
\item[\small\hook{pretxncommit}] De control. Es ejecutado luego de la
    creación de un conjunto de cambios en el repositorio local, pero
    antes de que la transacción que hace permanente el cambio sea
    completada.
\item[\small\hook{preupdate}] De control. Es ejecutado antes de
    iniciar una actualización o fusión en el directorio de trabajo.
\item[\small\hook{tag}] Es ejecutado después de la creación de una
    etiqueta.
\item[\small\hook{update}] Es ejecutado después de que termina una
    actualización o una fusión.
\end{itemize}
Cada uno de los ganchos cuya descripción empieza con la frase
``de control'' tiene la facultad de determinar si una actividad puede
continuar. Si el gancho se ejecuta con éxito, la actividad puede
continuar; si falla, o bien la actividad no es permitida, o se
deshacen los cambios que se puedan haber llevado a cabo, dependiendo
del gancho involucrado.

\section{Ganchos y seguridad}

\subsection{Los ganchos se ejecutan con sus privilegios de usuario}

Cuando usted ejecuta un comando de Mercurial en un repositorio, y el
comando causa la ejecución de un gancho, dicho gancho se ejecuta en
\emph{su} sistema, en \emph{su} cuenta de usuario, con \emph{sus}
privilegios. Ya que los ganchos son elementos arbitrarios de código
ejecutable, usted debería tratarlos con un nivel adecuado de
desconfianza. No instale un gancho a menos en que confíe en quien lo
creó y en lo que el gancho hace.

En algunos casos, usted puede estar expuesto a ganchos que usted no
%TODO acá introduzco algo de texto por mi cuenta, por claridad
instaló. Si usted usa Mercurial en un sistema extraño, tenga en cuenta
que Mercurial ejecutará los ganchos definidos en el fichero \hgrc.

Si está trabajando con un repositorio propiedad de otro usuario,
Mercurial podrá ejecutar los ganchos definidos en el repositorio de
dicho usuario, pero los ejecutará como ``usted''. Por ejemplo, si
usted jala (\hgcmd{pull}) desde ese repositorio, y el
\sfilename{.hg/hgrc} define un gancho saliente (\hook{outgoing}),
dicho gancho se ejecuta bajo su cuenta de usuario, aun cuando usted no
es el propietario del repositorio.

\begin{note}
  Esto sólo aplica si usted está jalando desde un repositorio en un
  sistema de ficheros local o de red. Si está jalando a través de http
  o ssh, cualquier gancho saliente (\hook{outgoing}) se ejecutará bajo
  la cuenta que está ejecutando el proceso servidor, en el servidor.
\end{note}

XXX Para ver qué ganchos han sido definidos en un repositorio, use el
comando \hgcmdargs{config}{hooks}. Si usted está trabajando en un
repositorio, pero comunicándose con otro que no le pertenece
(por ejemplo, usando \hgcmd{pull} o \hgcmd{incoming}), recuerde que
los ganchos que debe considerar son los del otro repositorio, no los
del suyo.

\subsection{Los ganchos no se propagan}

En Mercurial, no se hace control de revisiones de los ganchos, y no se
propagan cuando usted clona, o jala de, un repositorio. El motivo para
esto es simple: un gancho es código ejecutable arbitrario. Se ejecuta
bajo su identidad, con su nivel de privilegios, en su máquina.

Sería extremadamente descuidado de parte de cualquier sistema
distribuido de control de revisiones el implementar control de
revisiones para ganchos, ya que esto ofrecería maneras fácilmente
%TODO subvertir
aprovechables de subvertir las cuentas de los usuarios del sistema de
control de revisiones.

Ya que Mercurial no propaga los ganchos, si usted está colaborando con
otras personas en un proyecto común, no debería asumir que ellos están
usando los mismos ganchos para Mercurial que usted usa, o que los de
ellos están configurado correctamente. Usted debería documentar los
ganchos que usted espera que la gente use.

En una intranet corporativa, esto es algo más fácil de manejar, ya que
usted puede, por ejemplo, proveer una instalación ``estándar'' de
Mercurial en un sistema de ficheros NFS, y usar un fichero \hgrc\
global para definir los ganchos que verán todos los usuarios. Sin
embargo, este enfoque tiene sus límites; vea más abajo.

\subsection{Es posible hacer caso omiso de los ganchos}

Mercurial le permite hacer caso omiso de la deficinión de un gancho,
a través de la redefinición del mismo. Usted puede deshabilitar el
gancho fijando su valor como una cadena vacía, o cambiar su
comportamiento como desee.

Si usted instala un fichero \hgrc\ a nivel de sistema o sitio completo
que define algunos ganchos, debe entender que sus usuarios pueden
deshabilitar o hacer caso omiso de los mismos.

\subsection{Asegurarse de que ganchos críticos sean ejecutados}

Algunas veces usted puede querer hacer respetar una política, y no
permitir que los demás sean capaces de evitarla. Por ejemplo, usted
puede tener como requerimiento que cada conjunto de cambios debe pasar
un riguroso conjunto de pruebas. Definir este requerimientos a través
de un gancho en un fichero \hgrc\ global no servirá con usuarios
remotos en computadoras portátiles, y por supuesto que los usuarios
locales pueden evitar esto a voluntad haciendo caso omiso del gancho.

En vez de eso, usted puede definir las políticas para usar Mercurial
de tal forma que se espere que los usuarios propaguen los cambios a
través de un servidor ``canónico'' bien conocido que usted ha
asegurado y configurado apropiadamente.

Una manera de hacer esto es a través de una combinación de ingeniería
social y tecnología. Cree una cuenta de acceso restringido; los
usuarios pueden empujar cambios a través de la red a los repositorios
administrados por esta cuenta, pero no podrán ingresar a dicha cuenta
para ejecutar órdenes en el intérprete de comandos. En este escenario,
un usuario puede enviar un conjunto de cambios que contenga la
porquería que él desee.

Cuando alguien empuja un conjunto de cambios al servidor del que todos
jalan, el servidor probará el conjunto de cambios antes de aceptarlo
como permanente, y lo rechazará si no logra pasar el conjunto de
pruebas. Si la gente sólo jala cambios desde este servidor de filtro,
servirá para asegurarse de que todos los cambios que la gente jala han
sido examinados automáticamente

\section{Precauciones con ganchos \texttt{pretxn} en un repositorio de
acceso compartido}

Si usted desea usar ganchos para llevar a cabo automáticamente algún
trabajo en un repositorio al que varias personas tienen acceso
compartido, debe tener cuidado con la forma de hacerlo.

Mercurial sólo bloquea un repositorio cuando está escribiendo al
mismo, y sólo las partes de Mercurial que escriben al repositorio le
prestan atención a los bloqueos. Los bloqueos de escritura son
necesarios para evitar que múltiples escritores simultáneos
interfieran entre sí, corrompiendo el repositorio.

Ya que Mercurial tiene cuidado con el orden en que lee y escribe
datos, no necesita adquirir un bloqueo cuando desea leer datos del
repositorio. Las partes de Mercurial que leen del repositorio nunca le
prestan atención a los bloqueos. Este esquema de lectura libre de
bloqueos incremententa en gran medida el desempeño y la concurrencia.

Sin embargo, para tener un gran desempeño es necesario hacer
sacrificios, uno de los cuales tiene el potencial de causarle
problemas a menos de que usted esté consciente de él. Describirlo
requiere algo de detalle respecto a cómo Mercurial añade conjuntos de
cambios al repositorio y cómo lee esos cambios de vuelta.

Cuando Mercurial \emph{escribe} metadatos, los escribe directamente en
el fichero de destino. Primero escribe los datos del fichero, luego
los datos del manifiesto (que contienen punteros a los nuevos datos
del fichero), luego datos de la bitácora de cambios (que contienen
punteros a los nuevos datos del manifiesto). Antes de la primera
escritura a cada fichero, se guarda un registro de dónde estaba el
final de fichero en su registro de transacciones. Si la transacción
debe ser deshecha, Mercurial simplemente trunca cada fichero de vuelta
al tamaño que tenía antes de que empezara la transacción.

Cuando Mercurial \emph{lee} metadatos, lee la bitácora de cambios
primero, y luego todo lo demás. Como un lector sólo accederá a las
partes del manifiesto o de los metadatos de fichero que él puede ver
en la bitácora de cambios, nunca puede ver datos parcialmente
escritos.

Algunos ganchos de control (\hook{pretxncommit} y
\hook{pretxnchangegroup}) se ejecutan cuando una transacción está casi
completa. Todos los metadatos han sido escritos, pero Mercurial aún
puede deshacer la transacción y hacer que los datos recién escritos
desaparezcan.

Si alguno de estos ganchos permanece en ejecución por mucho tiempo,
abre una ventana de tiempo en la que un lector puede ver los metadatos
de conjuntos de cambios que aún no son permanentes y que no debería
considerarse que estén ``realmante ahí''. Entre más tiempo tome la
ejecución del gancho, más tiempo estará abierta esta ventana.

\subsection{Ilustración del problema}

En principio, un buen uso del gancho \hook{pretxnchangegroup} sería
ensamblar y probar automáticamente todos los cambios entrantes antes
de que sean aceptados en un repositorio central. Esto le permitiría a
usted garantizar que nadie pueda empujar cambios que ``rompan el
ensamblaje''. Pero si un cliente puede jalar cambios mientras están
siendo probados, la utilidad de esta prueba es nula; alguien confiado
puede jalar cambios sin probar, lo que potencialmente podría romper su
proceso de ensamblaje.

La respuesta técnica más segura frente a este retos es montar dicho
repositorio ``guardián'' como \emph{unidireccional}. Permita que
reciba cambios desde el exterior, pero no permita que nadie jale
cambios de él (use el gancho \hook{preoutgoing} para bloquear esto).
Configure un gancho \hook{changegroup} para que si el ensamblaje o
prueba tiene éxito, el gancho empuje los nuevos cambios a otro
repositorio del que la gente \emph{pueda} jalar.

En la práctica, montar un cuello de botella centralizado como éste a
menudo no es una buena idea, y la visibilidad de las transacciones no
tiene nada que ver con el problema. A medida que el tamaño de un
proyecto---y el tiempo que toma ensamblarlo y probarlo---crece, usted
se acerca rápidamente a un límite con este enfoque ``pruebe antes de
comprar'', en el que tiene más conjuntos de cambios a probar que
tiempo para ocuparse de ellos. El resultado inevitable es frustración
para todos los que estén involucrados.

Una aproximación que permite manejar mejor el crecimiento es hacer que
la gente ensamble y pruebe antes de empujar, y ejecutar el ensamble y
pruebas automáticas centralmente \emph{después} de empujar, para
asegurarse de que todo esté bien. La ventaja de este enfoque es que no
impone un límite a la rata en la que un repositorio puede aceptar
cambios.

\section{Tutorial corto de uso de ganchos}
\label{sec:hook:simple}

Escribir un gancho para Mercurial es fácil. Empecemos con un gancho
que se ejecute cuando usted termine un \hgcmd{commit}, y simplemente
muestre el hash del conjunto de cambios que usted acaba de crear. El
gancho se llamará \hook{commit}.

\begin{figure}[ht]
  \interaction{hook.simple.init}
  \caption{Un gancho simple que se ejecuta al hacer la consignación de
  un conjunto de cambios}
  \label{ex:hook:init}
\end{figure}

Todos los ganchos siguen el patrón del ejemplo~\ref{ex:hook:init}.
Usted puede añadir una entrada a la sección \rcsection{hooks} de su
fichero \hgrc.  A la izquierda está el nombre del evento respecto al
cual dispararse; a la derecha está la acción a llevar a cabo. Como
puede ver, es posible ejecutar cualquier orden de la línea de comandos
en un gancho. Mercurial le pasa información extra al gancho usando
variables de entorno (busque \envar{HG\_NODE} en el ejemplo).

\subsection{Llevar a cabo varias acciones por evento}

A menudo, usted querrá definir más de un gancho para un tipo de evento
particular, como se muestra en el ejemplo~\ref{ex:hook:ext}. 
Mercurial le permite hacer esto añadiendo una \emph{extensión} al
final del nombre de un gancho. Usted extiende el nombre del gancho
%TODO Yuk, no me gusta ese "parada completa"
poniendo el nombre del gancho, seguido por una parada completa (el
caracter ``\texttt{.}''), seguido de algo más de texto de su elección.
Por ejemplo, Mercurial ejecutará tanto \texttt{commit.foo} como
\texttt{commit.bar} cuando ocurra el evento \texttt{commit}.

\begin{figure}[ht]
  \interaction{hook.simple.ext}
  \caption{Definición de un segundo gancho \hook{commit}}
  \label{ex:hook:ext}
\end{figure}

Para dar un orden bien definido de ejecución cuando hay múltiples
ganchos definidos para un evento, Mercurial ordena los ganchos de
acuerdo a su extensión, y los ejecuta en dicho orden. En el ejemplo de
arribam \texttt{commit.bar} se ejecutará antes que
\texttt{commit.foo}, y \texttt{commit} se ejecutará antes de ambos.

Es una buena idea usar una extensión descriptiva cuando usted define
un gancho. Esto le ayudará a recordar para qué se usa el gancho. Si el
gancho falla, usted recibirá un mensaje de error que contiene el
nombre y la extensión del gancho, así que usar una extensión
descriptiva le dará una pista inmediata de porqué el gancho falló (vea
un ejemplo en la sección~\ref{sec:hook:perm}).

\subsection{Controlar cuándo puede llevarse a cabo una actividad}
\label{sec:hook:perm}

En los ejemplos anteriores, usamos el gancho \hook{commit}, que es
ejecutado después de que se ha completado una consignación. Este es
uno de los varios ganchos que Mercurial ejecuta luego de que una
actividad termina. Tales ganchos no tienen forma de influenciar la
actividad como tal.

Mercurial define un número de eventos que ocurren antes de que una
actividad empiece; o luego de que empiece, pero antes de que termine.
Los ganchos que se disparan con estos eventos tienen la capacidad
adicional de elegir si la actividad puede continuar, o si su ejecución
es abortada.

El gancho \hook{pretxncommit} se ejecuta justo antes de que una
consignación se ejecute. En otras palabras, los metadatos que
representan el conjunto de cambios han sido escritos al disco, pero no
se ha terminado la transacción. El gancho \hook{pretxncommit} tiene la
capacidad de decidir si una transacción se completa, o debe
deshacerse.

Si el gancho \hook{pretxncommit} termina con un código de salida de
cero, se permite que la transacción se complete; la consignación
termina; y el gancho \hook{commit} es ejecutado. Si el gancho
\hook{pretxncommit} termina con un código de salida diferente de cero,
la transacción es revertida; los metadatos representando el conjunto
de cambios son borrados; y el gancho \hook{commit} no es ejecutado.

\begin{figure}[ht]
  \interaction{hook.simple.pretxncommit}
  \caption{Uso del gancho \hook{pretxncommit} para controlar consignaciones}
  \label{ex:hook:pretxncommit}
\end{figure}

El gancho en el ejemplo~\ref{ex:hook:pretxncommit} revisa si el
mensaje de consignación contiene el ID de algún fallo. Si lo contiene,
la consignación puede continuar. Si no, la consignación es cancelada.

\section{Escribir sus propios ganchos}

Cuando usted escriba un gancho, puede encontrar útil el ejecutar
Mercurial o bien pasándole la opción \hggopt{-v}, o con el valor de
configuración \rcitem{ui}{verbose} fijado en ``true'' (verdadero).
Cuando lo haga, Mercurial imprimirá un mensaje antes de llamar cada
gancho.

\subsection{Escoger cómo debe ejecutarse su gancho}
\label{sec:hook:lang}

Usted puede escribir un gancho que funcione como un programa normal
---típicamente un guión de línea de comandos---o como una función de
Python que se ejecuta dentro del proceso Mercurial.

Escribir un gancho como un programa externo tiene la ventaja de que no
requiere ningún conocimiento del funcionamiento interno de Mercurial.
Usted puede ejecutar comandos Mercurial normales para obtener la
informción extra que pueda necesitar. La contraparte de esto es que
los ganchos externos son más lentos que los ganchos internos
ejecutados dentro del proceso.

Un gancho Python interno tiene acceso completo a la API de Mercurial,
y no se ``externaliza'' a otro proceso, así que es inherentemente más
rápido que un gancho externo. Adicionalmente es más fácil obtener la
mayoría de la información que un gancho requiere a través de llamadas
directas a la API de Mercurial que hacerlo ejecutando comandos
Mercurial.

Si se siente a gusto con Python, o requiere un alto desempeño,
escribir sus ganchos en Python puede ser una buena elección. Sin
embargo, cuando usted tiene un gancho bastante directo por escribir y
no le importa el desempeño (el caso de la mayoría de los ganchos), es
perfectamente admisible un guión de línea de comandos.

\subsection{Parámetros para ganchos}
\label{sec:hook:param}

Mercurial llama cada gancho con un conjunto de paŕametros bien
definidos. En Python, un parámetro se pasa como argumento de palabra
clave a su función de gancho. Para un programa externo, los parámetros
son pasados como variables de entornos.

Sin importar si su gancho está escrito en Python o como guión de línea
de comandos, los nombres y valores de los parámetros específicos de
los ganchos serán los mismos. Un parámetro booleano será representado
como un valor booleano en Python, pero como el número 1 (para
``verdadero'') o 0 (para falso) en una variable de entorno para un
gancho externo. Si un parámetro se llama \texttt{foo}, el argumento de
palabra clave para un gancho en Python también se llamará
\texttt{foo}, mientras que la variable de entorno para un gancho
externo se llamará \texttt{HG\_FOO}.

\subsection{Valores de retorno de ganchos y control de actividades}

Un gancho que se ejecuta exitosamente debe terminar con un código de
salida de cero, si es externo, o retornar el valor booleano
``falso'', si es interno. Un fallo se indica con un código de salida
diferente de cero desde un gancho externo, o un valor de retorno
booleano ``verdadero''. Si un gancho interno genera una excepción, se
considera que el gancho ha fallado.

Para los ganchos que controlan si una actividad puede continuar o no,
cero/falso quiere decir ``permitir'', mientras que
% TODO me suena mejor "no permitir" que "denegar"
no-cero/verdadero/excepción quiere decir ``no permitir''.

\subsection{Escribir un gancho externo}

Cuando usted define un gancho externo en su fichero \hgrc\ y el mismo
es ejecutado, dicha definición pasa a su intérprete de comandos, que
hace la interpretación correspondiente. Esto significa que usted puede
usar elementos normales del intérprete en el cuerpo del gancho.

Un gancho ejecutable siempre es ejecutado con su directorio actual
fijado al directorio raíz del repositorio.

Cada parámetro para el gancho es pasado como una variable de entorno;
el nombre está en mayúsculas, y tiene como prefijo la cadena
``\texttt{HG\_}''.

Con la excepción de los parámetros para los ganchos, Mercurial no
define o modifica ninguna variable de entorno al ejecutar un gancho.
Es útil recordar esto al escribir un gancho global que podría ser
ejecutado por varios usuarios con distintas variables de entorno
fijadas. En situaciones con múltiples usuarios, usted no debería
asumir la existencia de ninguna variable de entorno, ni que sus
valores sean los mismos que tenían cuando usted probó el gancho en su
ambiente de trabajo.

\subsection{Indicar a Mercurial que use un gancho interno}

La sintaxis para definir un gancho interno en el fichero \hgrc\ es
ligeramente diferente de la usada para un gancho externo. El valor del
gancho debe comenzar con el texto ``\texttt{python:}'', y continuar
con el nombre completamente cualificado de un objeto invocable que se
usará como el valor del gancho.

El módulo en que vive un gancho es importado automáticamente cuando se
ejecuta un gancho. Siempre que usted tenga el nombre del módulo y la
variable de entorno \envar{PYTHONPATH} ajustada adecuadamente, todo
debería funcionar sin problemas.

El siguiente fragmento de ejemplo de un fichero \hgrc\ ilustra la
sintaxis y significado de los conceptos que acabamos de describir.
\begin{codesample2}
  [hooks]
  commit.example = python:mymodule.submodule.myhook
\end{codesample2}
Cuando Mercurial ejecuta el gancho \texttt{commit.example}, importa 
\texttt{mymodule.submodule}, busca el objeto invocable llamado
\texttt{myhook}, y lo invoca (llama).

\subsection{Escribir un gancho interno}

El gancho interno más sencillo no hace nada, pero ilustra la
estructura básica de la API\ndt{\emph{Application Progamming
Interface}, Interfaz para Programación de Aplicaciones} para ganchos:
\begin{codesample2}
  def myhook(ui, repo, **kwargs):
      pass
\end{codesample2}
El primer argumento para un gancho Python siempre es un objeto
\pymodclass{mercurial.ui}{ui}.  El segundo es un objeto repositorio;
de momento, siempre es una instancia de 
\pymodclass{mercurial.localrepo}{localrepository}.  Después de estos
dos argumentos están los argumentos de palabra clave. Los argumentos
que se pasen dependerán del tipo de gancho que se esté llamando, pero
un gancho siempre puede ignorar los argumentos que no le interesen,
relegándolos a un diccionario de argumentos por palabras clave, como se
hizo arriba con \texttt{**kwargs}.

\section{Ejemplos de ganchos}

\subsection{Escribir mensajes de consignación significativos}

Es difícil de imaginar un mensaje de consignación útil y al mismo
tiempo muy corto. El simple gancho \hook{pretxncommit} de la
figura~\ref{ex:hook:msglen.go} evitará que usted consigne un conjunto
de cambios con un mensaje de menos de 10 bytes de longitud.

\begin{figure}[ht]
  \interaction{hook.msglen.go}
  \caption{Un gancho que prohíbe mensajes de consignación demasiado
  cortos}
  \label{ex:hook:msglen.go}
\end{figure}

\subsection{Comprobar espacios en blanco finales}

Un uso interesante para ganchos relacionados con consignaciones es
ayudarle a escribir código más limpio. Un ejemplo simple de
%TODO dictum => regla
``código más limpio'' es la regla de que un cambio no debe añadir
líneas de texto que contengan ``espacios en blanco finales''. El
espacio en blanco final es una serie de caracteres de espacio y
tabulación que se encuentran al final de una línea de texto. En la
mayoría de los casos, el espacio en blanco final es innecesario, ruido
invisible, pero ocasionalmente es problemático, y la gente en general
prefiere deshacerse de él.

Usted puede usar cualquiera de los ganchos \hook{precommit} o
\hook{pretxncommit} para revisar si tiene el problema de los espacios
en blanco finales. Si usa el gancho \hook{precommit}, el gancho no
sabrá qué ficheros se están consignando, por lo que se tendrá que
revisar cada fichero modificado en el repositorio para ver si tiene
espacios en blanco finales. Si usted sólo quiere consignar un cambio
al fichero \filename{foo}, y el fichero \filename{bar} contiene
espacios en blanco finales, hacer la revisión en el gancho
\hook{precommit} evitará que usted haga la consignación de
\filename{foo} debido al problem en \filename{bar}.  Este no parece el
enfoque adeucado.

Si usted escogiera el gancho \hook{pretxncommit}, la revisión no
ocurriría sino hasta justo antes de que la transacción para la
consignación se complete. Esto le permitirá comprobar por posibles
problemas sólo en los ficheros que serán consignados. Sin embargo, si
usted ingresó el mensaje de consignación de manera interactiva y el
%TODO roll-back
gancho falla, la transacción será deshecha; usted tendrá que
reingresar el mensaje de consignación luego de que corrija el problema
con los espacios en blanco finales y ejecute \hgcmd{commit} de nuevo.

\begin{figure}[ht]
  \interaction{hook.ws.simple}
  \caption{Un gancho simple que revisa si hay espacios en blanco
  finales}
  \label{ex:hook:ws.simple}
\end{figure}

La figura~\ref{ex:hook:ws.simple} presenta un gancho
\hook{pretxncommit} simple que comprueba la existencia de espacios en
blanco finales. Este gancho es corto, pero no brinda mucha ayuda.
Termina con un código de salida de error si un cambio añade una línea
con espacio en blanco final a cualquier fichero, pero no muestra
ninguna información que pueda ser útil para identificar el fichero o
la línea de texto origen del problema. También tiene la agradable
propiedad de no prestar atención a las líneas que no sufrieron
modificaciones; sólo las líneas que introducen nuevos espacios en
blanco finales causan problemas.

\begin{figure}[ht]
  \interaction{hook.ws.better}
  \caption{Un mejor gancho para espacios en blanco finales}
  \label{ex:hook:ws.better}
\end{figure}

El ejemplo de la figura~\ref{ex:hook:ws.better} es mucho más complejo,
pero también más útil. El gancho procesa un diff unificado para
revisar si alguna línea añade espacios en blanco finales, e imprime el
nombre del fichero y el número de línea de cada ocurrencia. Aún mejor,
si el cambio añade espacios en blanco finales, este gancho guarda el
mensaje de consignación e imprime el nombre del fichero en el que el
mensaje fue guardado, antes de terminar e indicarle a Mercurial que
deshaga la transacción, para que uste pueda usar
\hgcmdargs{commit}{\hgopt{commit}{-l}~\emph{nombre\_fichero}} para
reutilizar el mensaje de consignación guardado anteriormente, una vez
usted haya corregido el problema.

Como anotación final, note en la figura~\ref{ex:hook:ws.better} el
%TODO on-site => in-situ ?
uso de la característica de edición \emph{in-situ} de \command{perl}
para eliminar los espacios en blanco finales en un fichero. Esto es
lo suficientemente conciso y poderoso para que lo presente aquí.
% TODO corregí el backslash, y comprobé por mi cuenta un archivo
% aparte, y el comando hace lo que debe hacer. Favor copiar del pdf el
% comando perl y comprobar con un archivo con espacios en blanco
% finales, y si todo está bien (que debería), borrar esta nota
\begin{codesample2}
    perl -pi -e 's,\textbackslash{}s+\$,,' nombre\_fichero
\end{codesample2}

\section{Ganchos adicionales}

Mercurial se instala con varios ganchos adicionales. Usted puede
encontrarlos en el directorio \dirname{hgext} del árbol de ficheros
fuente de Mercurial. Si usted está usando un paquete binario de
Mercurial, los ganchos estarán ubicados en el directorio
\dirname{hgext} en donde su instalador de paquetes haya puesto a
Mercurial.

\subsection{\hgext{acl}---control de acceso a partes de un repositorio}

La extensión \hgext{acl} le permite controlar a qué usuarios remotos
les está permitido empujar conjuntos de cambios a un servidor en red.
Usted puede proteger cualquier porción de un repositorio (incluyendo
el repositorio completo), de tal manera que un usuario remoto
específico pueda empujar cambios que no afecten la porción protegida.

Esta extensión implementa control de acceso basado en la identidad del
usuario que empuja los conjuntos de cambios, \emph{no} en la identidad
de quien hizo la consignación de los mismos. Usar este gancho tiene
sentido sólo si se tiene un servidor adecuadamente asegurado que
autentique a los usuarios remotos, y si usted desea segurarse de que
sólo se le permita a ciertos usuarios empujar cambios a dicho
servidor.

\subsubsection{Configuración del gancho \hook{acl}}

Para administrar los conjuntos de cambios entrantes, se debe usar el
gancho \hgext{acl} como un gancho de tipo \hook{pretxnchangegroup}.
Esto le permite ver qué ficheros son modificados por cada conjunto de
%TODO rollback => "deshacer el efecto"
cambios entrante, y deshacer el efecto de un grupo de conjuntos de
cambios si alguno de ellos modifica algún fichero ``prohibido''.
Ejemplo:
\begin{codesample2}
  [hooks]
  pretxnchangegroup.acl = python:hgext.acl.hook
\end{codesample2}

La extensión \hgext{acl} es configurada mediante tres secciones.

La sección \rcsection{acl} sólo tiene una entrada,
\rcitem{acl}{sources}\ndt{Fuentes.}, que lista las fuentes de los
conjuntos de cambios entrantes a las que el gancho debe prestar
atención. Usualmente usted no necesita configurar esta sección.
\begin{itemize}
  \item[\rcitem{acl}{serve}] Controlar conjuntos de
    cambios entrantes que están llegando desde un repositorio a
    través de http o ssh. Este es el valor por defecto de
  \rcitem{acl}{sources}, y usualmente es el único valor de
  configuración que necesitará para este ítem.
\item[\rcitem{acl}{pull}] Controlar conjuntos de cambios entrantes que
  lleguen vía un pull (jalado) desde un repositorio local.
\item[\rcitem{acl}{push}] Controlar conjuntos de cambios entrantes que
  lleguen vía un push (empuje) desde un repositorio local.
\item[\rcitem{acl}{bundle}] Controlar conjuntos de cambios entrantes
    %TODO bundle
  que lleguen desde otro repositorio a través de un paquete.
\end{itemize}

La sección \rcsection{acl.allow} controla los usuarios a los que les
está permitido añadir conjuntos de cambios al repositorio. Si esta
sección no está presente, se le permite acceso a todos los usuarios
excepto  a los que se les haya negado explícitamente el acceso. Si
esta sección no está presente, se niega el acceso a todos los usuarios
excepto a todos a los que se les haya permitido de manera explícita
(así que una sección vacía implica que se niega el acceso a todos los
usuarios).

La sección \rcsection{acl.deny} determina a qué usuarios no se les
permite añadir conjuntos de cambios al repositorio. Si esta sección no
está presente o está vacía, no se niega el acceso a ningún usuario.

La sintaxis para los ficheros \rcsection{acl.allow} y
\rcsection{acl.deny} es idéntica. A la izquierda de cada entrada se
encuentra un patrón glob que asocia ficheros o directorios, respecto a
la raíz del repositorio; a la derecha, un nombre usuario.

En el siguiente ejemplo, el usuario \texttt{escritordoc} sólo puede
empujar cambios al directorio \dirname{docs} del repositorio, mientras
que \texttt{practicante} puede enviar cambios a cualquier fichero o
directorio excepto \dirname{fuentes/sensitivo}.
\begin{codesample2}
  [acl.allow]
  docs/** = escritordoc

  [acl.deny]
  fuentes/sensitivo/** = practicante
\end{codesample2}

\subsubsection{Pruebas y resolución de problemas}

Si usted desea probar el gancho \hgext{acl}, ejecútelo habilitando la
opción de salida de depuración habilitada. Ya que usted probablemente
lo estará ejecutando en un servidor donde no es conveniente (o incluso
posible) pasar la opción \hggopt{--debug}, no olvide que usted puede
habilitar la salida de depuración en su \hgrc:
\begin{codesample2}
  [ui]
  debug = true
\end{codesample2}
Con esto habilitado, el gancho \hgext{acl} imprimirá suficiente
información para permitirle saber porqué está permitiendo o denegando
la operación de empujar a usuarios específicos.

\subsection{\hgext{bugzilla}---integración con Bugzilla}

La extensión \hgext{bugzilla} añade un comentario a un fallo Bugzilla
siempre que encuentre una referencia al ID de dicho fallo en un
mensaje de consignación. Usted puede instalar este gancho en un
servidor compartido, para que cada vez que un usuario remoto empuje
cambios al servidor, el gancho sea ejecutado.

Se añade un comentario al fallo que se ve así (usted puede configurar
los contenidos del comentario---vea más abajo):
%TODO traducir?
\begin{codesample2}
  Changeset aad8b264143a, made by Joe User <joe.user@domain.com> in
  the frobnitz repository, refers to this bug.

  For complete details, see
  http://hg.domain.com/frobnitz?cmd=changeset;node=aad8b264143a

  Changeset description:
        Fix bug 10483 by guarding against some NULL pointers
\end{codesample2}
El valor de este gancho se encuentra en que automatiza el proceso de
actualizar un fallo cuando un conjunto de cambios se refiera a él. Si
usted configura este gancho adecuadamente, hará fácil para la gente
navegar directamente desde un fallo Bugzilla a un conjunto de cambios
que se refiere a ese fallo.

Usted puede usar el código de este gancho como un punto de partida
para otras recetas de integración con Bugzilla aún más exóticas. Acá
hay algunas posibilidades:
\begin{itemize}
\item Requerir que cada conjunto de cambios tenga un ID de fallo en su
  mensaje de consignación. En este caso, usted querrá configurar el
  gancho como uno de tipo \hook{pretxncommit}.  Esto le permitirá al
  gancho rechazar cambios que no contiene IDs de fallos.
\item Permitir a los conjuntos de cambios entrantes modificar
  automáticamente el \emph{estado} de un fallo, así como simplemente
  añadir un comentario. Por ejemplo, el gancho podría reconocer la
  cadena ``corregido fallo 31337'' como la señal de que debería
  actualizar el estado del fallo 31337 a ``requiere pruebas''.
\end{itemize}

\subsubsection{Configuración del gancho \hook{bugzilla}}
\label{sec:hook:bugzilla:config}

Usted debería configurar este gancho en el \hgrc\ de su servidor como
un gancho \hook{incoming}\ndt{Entrante.}, por ejemplo como sigue:
\begin{codesample2}
  [hooks]
  incoming.bugzilla = python:hgext.bugzilla.hook
\end{codesample2}

Debido a la naturaleza especializada de este gancho, y porque Bugzilla
no fue escrito con este tipo de integración en mente, configurar este
% TODO involved => complejo ? no intarwebs here :(
gancho es un proceso algo complejo.

Antes de empezar, usted debe instalar la interfaz de Python para MySQL
en los sistemas en los que se vaya a ejecutar el gancho. Si no está
disponible como paquete binario para su sistema, usted puede descargar
el paquete desde~\cite{web:mysql-python}.

La información para configurar este gancho se ubica en la sección 
\rcsection{bugzilla} de su \hgrc.
\begin{itemize}
\item[\rcitem{bugzilla}{version}] La versión de Bugzilla instalada en
  el servidor. El esquema de base de datos que Bugzilla usa cambia
  ocasionalmente, así que este gancho debe saber exactamente qué
  esquema usar. A la fecha, la única versión soportada es la
  \texttt{2.16}.
\item[\rcitem{bugzilla}{host}] El nombre de máquina (\emph{hostname})
  del servidor MySQL que almacena sus datos Bugzilla. La base de datos
  debe ser configurada para permitir conexiones desde las máquinas en
  las que usted ejecute el gancho \hook{bugzilla}.
\item[\rcitem{bugzilla}{user}] El nombre de usuario que se usará para
  conectarse al servidor MySQL. La base de datos debe ser configurada
  para permitir a dicho usuario conectarse desde cualquiera de las
  máquinas en las que se ejecute el gancho \hook{bugzilla}.  Este
  usuario debe tener acceso y poder modificar las tablas de Bugzilla.
  El valor por defecto para este ítem es \texttt{bugs}, que es el
  nombre estándar del usuario para Bugzilla en una base de datos
  MySQL.
\item[\rcitem{bugzilla}{password}] La contraseña MySQL para el usuario
  configurado anteriormente. Ésta es almacenada como texto plano, así
  que usted deberá asegurarse de que los usuarios no autorizados no
  puedan leer el fichero \hgrc\ en donde usted guarda esta
  información.
\item[\rcitem{bugzilla}{db}] El nombre de la base de datos Bugzilla en
  el servidor MySQL. El nombre por defecto para este ítem es
  \texttt{bugs}, que es el nombre estándar de la base de datos MySQL
  en donde Bugzilla almacena sus datos.
\item[\rcitem{bugzilla}{notify}] Si usted desea que Bugzilla envíe un
    %TODO suBscriptores?
  correo de notificación a los suscriptores después de que el gancho
  haya añadido un comentario a un fallo, necesitará que este gancho
  ejecute un comando siempre que actualice la base de datos. El
  comando que se ejecute depende de en dónde haya sido instalado
  Bugzilla, pero típicamente se verá así, si usted ha instalado
  Bugzilla en \dirname{/var/www/html/bugzilla}:
  \begin{codesample4}
    cd /var/www/html/bugzilla && ./processmail %s nobody@nowhere.com
  \end{codesample4}
  El programa \texttt{processmail} de Bugzilla espera recibir un ID de
  fallo (el gancho reemplaza ``\texttt{\%s}'' por el ID del fallo) y
  una dirección de correo. También espera poder escribir a ciertos
  ficheros en el directorio en que se ejecuta. Si Bugzilla y éste
  gancho no están instalados en la misma máquina, usted deberá
  encontrar una manera de ejecutar \texttt{processmail} en el servidor
  donde está instalado Bugzilla.
\end{itemize}

\subsubsection{Asociar nombres de consignadores a nombres de usuario
Bugzilla}

Por defecto, el gancho \hgext{bugzilla} trata de usar la dirección de
correo electrónico de la persona que hizo la consignación del conjunto
de cambios como el nombre de usuario Bugzilla con el cual debe
actualizar el fallo. Si esto no se ajusta a sus necesidades, es
posible asociar direcciones de correo a nombres de usuario Bugzilla
usando una sección \rcsection{usermap}.

Cada ítem en la sección \rcsection{usermap} contiene una dirección de
correo electrónico a la izquierda, y un nombre de usuario Bugzilla a
la derecha.
\begin{codesample2}
  [usermap]
  jane.user@example.com = jane
\end{codesample2}
Usted puede mantener los datos de \rcsection{usermap} en un fichero
\hgrc, o decirle al gancho \hgext{bugzilla} que lea la información
desde un fichero \filename{usermap} externo.  En este caso, usted
puede almacenar los datos de \filename{usermap} en (por ejemplo) un
repositorio modificable por los usuarios. Esto hace posible para sus
usuarios mantener sus propias entradas \rcitem{bugzilla}{usermap}.  El
fichero \hgrc\ principal se vería así:
\begin{codesample2}
  # fichero hgrc normal se refiere a un fichero usermap externo
  [bugzilla]
  usermap = /home/hg/repos/userdata/bugzilla-usermap.conf
\end{codesample2}
Mientras que el fichero \filename{usermap} al que se hace referencia
se vería así:
\begin{codesample2}
  # bugzilla-usermap.conf - dentro de un repositorio hg
  [usermap]
  stephanie@example.com = steph
\end{codesample2}

\subsubsection{Configurar el texto que se añade a un fallo}

Usted puede configurar el texto que este gancho añade como comentario;
usted los especifica como una plantilla Mercurial. Varias entradas
\hgrc\ (aún en la sección \rcsection{bugzilla}) controlan este
comportamiento.
\begin{itemize}
\item[\texttt{strip}] La cantidad de elementos iniciales de ruta a
  remover de un nombre de ruta del repositorio para construir una ruta
  parcial para una URL. Por ejemplo, si los repositorios en su
  servidor se ubican en \dirname{/home/hg/repos}, y usted tiene un
  repositorio cuya ruta es \dirname{/home/hg/repos/app/tests},
  entonces fijar \texttt{strip} a \texttt{4} resultará en una ruta
  parcial de \dirname{app/tests}.  El gancho hará disponible esta ruta
  parcial cuando expanda una plantilla, como \texttt{webroot}.
\item[\texttt{template}] El texto de la plantilla a usar. En adición a
  las variables usuales relacionadas con conjuntos de cambios, esta
  plantilla puede usar \texttt{hgweb} (el valor del ítem de
  configuración \texttt{hgweb} de arriba) y \texttt{webroot} (la ruta
  construida usando \texttt{strip} arriba).
\end{itemize}

Adicionalmente, usted puede añadir un ítem \rcitem{web}{baseurl} a la
sección \rcsection{web} de su \hgrc.  El gancho \hgext{bugzilla}
publicará esto cuando expanda una plantilla, como la cadena base a
usar cuando se construya una URL que le permita a los usuarios navegar
desde un comentario de Bugzilla a la vista de un conjunto de cambios.
Ejemplo:
\begin{codesample2}
  [web]
  baseurl = http://hg.domain.com/
\end{codesample2}

A continuación se presenta un ejemplo completo de configuración para
el gancho \hgext{bugzilla}.
%TODO traducir?
\begin{codesample2}
  [bugzilla]
  host = bugzilla.example.com
  password = mypassword
  version = 2.16
  # server-side repos live in /home/hg/repos, so strip 4 leading
  # separators
  strip = 4
  hgweb = http://hg.example.com/
  usermap = /home/hg/repos/notify/bugzilla.conf
  template = Changeset \{node|short\}, made by \{author\} in the \{webroot\}
    repo, refers to this bug.\\nFor complete details, see 
    \{hgweb\}\{webroot\}?cmd=changeset;node=\{node|short\}\\nChangeset
    description:\\n\\t\{desc|tabindent\}
\end{codesample2}

\subsubsection{Pruebas y resolución de problemas}

Los problemas más comunes que aparecen en la configuración del gancho
\hgext{bugzilla} suelen estar relacionados con la ejecución del guión
de Bugzilla \filename{processmail} y la asociación de nombres de
consignadores a nombres de usuario.

Recuerde que en la sección~\ref{sec:hook:bugzilla:config} arriba el
usuario que ejecuta el proceso Mercurial en el servidor es también 
el usuario que ejecutará el guión \filename{processmail}. El guión
\filename{processmail} algunas veces hace que Bugzilla escriba en
ficheros en su directorio de configuración, y los ficheros de
configuración de Bugzilla usualmente son propiedad del usuario bajo el
cual se ejecuta el servidor web.

Usted puede hacer que \filename{processmail} sea ejecutado con la
identidad del usuario adecuado usando el comando \command{sudo}. A
continuación se presenta una entrada de ejemplo para un fichero
\filename{sudoers}.
\begin{codesample2}
  hg_user = (httpd_user) NOPASSWD: /var/www/html/bugzilla/processmail-wrapper %s
\end{codesample2}
Esto permite que el usuario \texttt{hg\_user} ejecute el programa
\filename{processmail-wrapper} con la identidad del usuario
\texttt{httpd\_user}.

Esta indirección a través de un guión envoltorio es necesaria, porque
\filename{processmail} espera que al ser ejecutado su directorio
actual sea aquel en el cual se instaló Bugzilla; usted no puede
especificar ese tipo de condición en un fichero \filename{sudoers}.
Los contenidos del giuón envoltorio son simples:
\begin{codesample2}
  #!/bin/sh
  cd `dirname $0` && ./processmail "$1" nobody@example.com
\end{codesample2}
No parece importar qué dirección de correo se le pase a
\filename{processmail}.

Si su \rcsection{usermap} no es configurada correctamente, los
usuarios verán un mensaje de error del gancho \hgext{bugzilla} cuando
empujen cambios al servidor. El mensaje de error se verá así:
\begin{codesample2}
  cannot find bugzilla user id for john.q.public@example.com
\end{codesample2}
Lo que esto quiere decir es que la dirección del consignador,
\texttt{john.q.public@example.com}, no es un nombre de usuario
Bugzilla válido, ni tiene una entrada en su \rcsection{usermap} que lo
asocie con un nombre de usuario válido Bugzilla.

\subsection{\hgext{notify}---enviar notificaciones de correo
electrónico}

%TODO feeds => notificaciones: lo más fácil es mirar en wikipedia
Aunque el servidor web embebido de Mercurial provee notificaciones de
cambios en cada repositorio, muchas personas prefieren recibir las
notificaciones de cambios vía correo electrónico. El gancho
\hgext{notify}\ndt{Notificación.} le permite a usted enviar
notificaciones a un conjunto de direcciones de correo cuando lleguen
conjuntos de cambios en los que los subscriptores estén interesados.

De la misma forma que con el gancho \hgext{bugzilla}, el gancho
\hgext{notify} está orientado a plantillas, así que usted puede
personalizar los contenidos del mensaje de notificación que se envía.

Por defecto, el gancho \hgext{notify} incluye un diff de cada conjunto
%TODO que se envía? revisar, pienso que es ``que se recibe''
de cambios que se envía; usted puede limitar el tamaño del diff, o
desactivar completamente esta característica. Es útil para permitir a
los subscriptores revisar los cambios inmediatamente, en vez de tener
que hacer clic para visitar una URL.

\subsubsection{Configuración del gancho \hgext{notify}}

Usted puede configurar el gancho \hgext{notify} para enviar un mensaje
de correo por conjunto de cambios entrante, o uno por grupo entrante
de conjuntos de cambios (todos los que llegaron en un único empuje o
jalado).
\begin{codesample2}
  [hooks]
  # enviar un correo por grupo de cambios
  changegroup.notify = python:hgext.notify.hook
  # enviar un correo por cambio
  incoming.notify = python:hgext.notify.hook
\end{codesample2}

La información para configurar este gancho se ubica en la sección
\rcsection{notify} de un fichero \hgrc.
\begin{itemize}
\item[\rcitem{notify}{test}] Por defecto, este gancho no envía correos
  en absoluto; en vez de eso, imprime el mensaje que se
  \emph{enviaría}. Fije este ítem en \texttt{false} para permitir el
  envío de correos. El motivo por el que el envío de correos está
  desactivado es que hacen falta varios intentos para configurar esta
  extensión exactamente como usted desea, y sería maleducado enviar a
  los subscriptores una cantidad de notificaciones ``rotas'' mientras
  usted depura su configuración.
\item[\rcitem{notify}{config}] La ruta a un fichero de configuración
  que contiene información de subscripción. Esto se mantiene separado
  del \hgrc\ principal para que usted pueda mantenerlo en un
  repositorio. La gente puede clonar ese repositorio, actualizar sus
  subscripciones, y empujar los cambios de vuelta a su servidor.
\item[\rcitem{notify}{strip}] La cantidad de caracteres iniciales de
  separación de ruta a remover de la ruta del repositorio, al decidir
  si un repositorio tiene subscriptores. Por ejemplo, si los
  repositorios en su servidor están en \dirname{/home/hg/repos}, y
  \hgext{notify} está trabajando con un repositorio llamado
  \dirname{/home/hg/repos/shared/test}, fijar \rcitem{notify}{strip} a
  \texttt{4} hará que \hgext{notify} elimine las partes iniciales de
  la ruta hasta \dirname{shared/test}, y asociará los subscriptores
  frente a dicha ruta.
\item[\rcitem{notify}{template}] El texto de plantilla a usar cuando
  se envíen mensajes. Especifica los contenidos de la cabecera del
  mensaje y el cuerpo del mismo.
\item[\rcitem{notify}{maxdiff}] El número máximo de líneas de datos de
  diff a añadir al final de un mensaje. Si la longitud de un diff es
  mayor a eso, se trunca. Por defecto, está fijado en 300. Fije esto a 
  \texttt{0} para omitir los diffs en los correos de notificación.
\item[\rcitem{notify}{sources}] Una lista de fuentes de conjuntos de
  cambios a considerar. Esto le permite a usted indicar a
  \hgext{notify} para que sólo envíe correos acerca de cambios que
  usuarios remotos hayan empujado al repositorio vía un servidor, por
  ejemplo.  Vea la sección~\ref{sec:hook:sources} para las fuentes que
  usted puede especificar aquí.
\end{itemize}

Si usted fija el ítem \rcitem{web}{baseurl} en la sección
\rcsection{web}, usted lo puede usar en una plantilla; estará
disponible como \texttt{webroot}.

A continuación se presenta un ejemplo completo de configuración para
el gancho \hgext{notify}.
\begin{codesample2}
  [notify]
  # enviar correo
  test = false
  # datos de subscriptores están en el repositorio notify
  config = /home/hg/repos/notify/notify.conf
  # repos están en /home/hg/repos on server, así que elimine 4
  # caracteres"/"
  strip = 4
  template = X-Hg-Repo: \{webroot\}
    Subject: \{webroot\}: \{desc|firstline|strip\}
    From: \{author\}

    changeset \{node|short\} in \{root\}
    details: \{baseurl\}\{webroot\}?cmd=changeset;node=\{node|short\}
    description:
      \{desc|tabindent|strip\}

  [web]
  baseurl = http://hg.example.com/
\end{codesample2}

Esto producirá un mensaje que se verá como el siguiente:
\begin{codesample2}
  X-Hg-Repo: tests/slave
  Subject: tests/slave: Handle error case when slave has no buffers
  Date: Wed,  2 Aug 2006 15:25:46 -0700 (PDT)

  changeset 3cba9bfe74b5 in /home/hg/repos/tests/slave
  details: http://hg.example.com/tests/slave?cmd=changeset;node=3cba9bfe74b5
  description:
          Handle error case when slave has no buffers
  diffs (54 lines):

  diff -r 9d95df7cf2ad -r 3cba9bfe74b5 include/tests.h
  --- a/include/tests.h      Wed Aug 02 15:19:52 2006 -0700
  +++ b/include/tests.h      Wed Aug 02 15:25:26 2006 -0700
  @@ -212,6 +212,15 @@ static __inline__ void test_headers(void *h)
  [...snip...]
\end{codesample2}

\subsubsection{Pruebas y resolución de problemas}

No olvide que por defecto, la extensión \hgext{notify} \emph{no
enviará ningún correo electrónico} hasta que usted la configure
explícitamente para hacerlo, fijando el valor de \rcitem{notify}{test}
a \texttt{false}.  Hasta que usted haga eso, simplemente se imprimirá
el mensaje que se \emph{enviaría}.

\section{Información para escritores de ganchos}
\label{sec:hook:ref}

\subsection{Ejecución de ganchos internos}

Un gancho interno es llamado con argumentos de la siguiente forma:
\begin{codesample2}
  def myhook(ui, repo, **kwargs):
      pass
\end{codesample2}
El parámetro \texttt{ui} es un objeto \pymodclass{mercurial.ui}{ui}.
El parámetro \texttt{repo} es un objeto
\pymodclass{mercurial.localrepo}{localrepository}. Los nombres y
valores de los parámetros en \texttt{**kwargs} dependen del gancho que
se invoque, con las siguientes características en común:
\begin{itemize}
\item Si hay un parámetro llamado \texttt{node} o
  \texttt{parent\emph{N}}, contendrá un ID hexadecimal de un conjunto
  de cambios. La cadena vacía es usada para representar un
  ``ID de conjunto de cambios nulo'' en vez de una cadena de ceros.
\item Si hay un parámetro llamado \texttt{url}, contendrá la URL de un
  repositorio remoto, si puede ser determinada.
\item Los parámetros booleanos son representados como objetos
    \texttt{bool} de Python.
\end{itemize}

Un gancho interno es ejecutado sin cambiar el directorio de trabajo
del proceso (a diferencia de los ganchos externos, que son ejecutados
desde la raíz del repositorio). El gancho no debe cambiar el
directorio de trabajo del proceso, porque esto haría que falle
cualquier llamada que se haga a la API de Mercurial.

Si un gancho retorna el valor booleano ``false''\ndt{Falso.}, se
considera que éste tuvo éxito. Si retorna
``true''\ndt{Verdadero.} o genera una excepción, se considera que
ha fallado. Una manera útil de pensar en esta convención de llamado es
``dígame si usted falló''.

Note que los IDs de conjuntos de cambios son pasados a los ganchos de
Python como cadenas hexadecimales, no como los hashes binarios que la
API de Mercurial usa normalmente. Para convertir un hash de
hexadecimal a binario, use la función \pymodfunc{mercurial.node}{bin}.

\subsection{Ejecución de ganchos externos}

Un gancho externo es pasado al intérprete de comandos del usuario bajo
el cual se ejecuta Mercurial. Las características del intérprete, como
sustitución de variables y redirección de comandos, están disponibles.
El gancho es ejecutado desde el directorio raíz del repositorio
(a diferencia de los ganchos internos, que se ejecutan desde el mismo
directorio en que Mercurial fue ejecutado).

Los parámetros para el gancho se pasan como variables de entorno. El
nombre de cada variable de entorno se pasa a mayúsculas y se le añade
el prefijo ``\texttt{HG\_}''.  Por ejemplo, si el nombre de un
parámetro es ``\texttt{node}'', el nombre de la variable de entorno
que almacena el parámetro se llamará ``\texttt{HG\_NODE}''.

Un parámetro booleano se representa con la cadena ``\texttt{1}'' para
``true'', ``\texttt{0}'' para ``false''.  Si una variable se llama
\envar{HG\_NODE}, \envar{HG\_PARENT1} o \envar{HG\_PARENT2},  
contendrá un ID de conjunto de cambios representado como una cadena
hexadecimal. La cadena vacía es usada para representar un ``ID de
conjunto de cambios nulo'' en vez de una cadena de ceros. Si una
variable de entorno se llama \envar{HG\_URL}, contendrá la URL de un
repositorio remoto, si puede ser determinada.

Si un gancho termina con un código de salida de cero, se considera que
tuvo éxito. Si termina con un código de salida diferente de cero, se
considera que falló.

\subsection{Averiguar de dónde vienen los conjuntos de cambios}
%TODO los trae la cigüeña. De París. Y quedan debajo de una col.

Un gancho que involucra la transferencia de conjuntos de cambios entre
un repositorio local y otro puede ser capaz de averiguar información
acerca de ``el otro lado''. Mercurial sabe \emph{cómo} son
transferidos los conjuntos de cambios, y en muchos casos también desde
o hacia donde están siendo transferidos.

\subsubsection{Fuentes de conjuntos de cambios}
\label{sec:hook:sources}

Mercurial le indicará a un gancho cuáles son, o fueron, los medios
usados para transferir los conjuntos de cambios entre repositorios.
Esta información es provista por Mercurial en un parámetro Python
llamado \texttt{source}\ndt{Fuente.}, o una variable de entorno
llamada \envar{HG\_SOURCE}.

\begin{itemize}
\item[\texttt{serve}] Los conjuntos de cambios son transferidos desde
  o hacia un repositorio remoto a través de http o ssh.
\item[\texttt{pull}] Los conjuntos de cambios son transferidos vía una
  operación de jalado de un repositorio a otro.
\item[\texttt{push}] Los conjuntos de cambios son transferidos vía un
  empuje de un repositorio a otro.
\item[\texttt{bundle}] Los conjuntos de cambios son transferidos desde
    %TODO bundle
  o hacia un paquete.
\end{itemize}

\subsubsection{A dónde van los cambios---URLs de repositorios remotos}
\label{sec:hook:url}
%TODO al cielo? no, ésos son los perros

Cuando es posible, Mercurial le indicará a los ganchos la ubicación de
``el otro lado'' de una actividad que transfiera datos de conjuntos de
cambios entre repositorios. Esto es provisto por Mercurial en un
parámetro Python llamado \texttt{url}, o en una variable de entorno
llamada \envar{HG\_URL}.

No siempre esta información está disponible. Si un gancho es invocado
un repositorio que es servido a través de http o ssh, Mercurial no
puede averiguar dónde está el repositorio remoto, pero puede saber
desde dónde se conecta el cliente. En esos casos, la URL tendrá una de
las siguientes formas:
\begin{itemize}
\item \texttt{remote:ssh:\emph{ip-address}}---cliente ssh remoto, en
  la dirección IP dada.
\item \texttt{remote:http:\emph{ip-address}}---cliente remoto http, en
  la dirección IP dada. Si el cliente está usando SSL, tendrá la forma
  \texttt{remote:https:\emph{ip-address}}.
\item Vacío---no se pudo descubrir información acerca del cliente
  remoto.
\end{itemize}

\section{Referencia de ganchos}

\subsection{\hook{changegroup}---luego de añadir conjuntos de cambios
remotos}
\label{sec:hook:changegroup}

Este gancho es ejecutado luego de que un grupo de conjuntos de cambios
preexistentes ha sido añadido al repositorio, por ejemplo vía un
\hgcmd{pull} o \hgcmd{unbundle}.  Este gancho es ejecutado una vez por
cada operación que añade uno o más conjuntos de cambios. Este gancho
se diferencia del gancho \hook{incoming}, que es ejecutado una vez por
cada conjunto de cambios, sin importar si los cambios llegan en grupo.

Algunos usos posibles para este gancho includen el probar o ensamblar
los conjuntos de cambios añadidos, actualizar una base de datos de
fallos, o notificar a subscriptores de que el repositorio contiene
nuevos cambios.

Parámetros para este gancho:
\begin{itemize}
\item[\texttt{node}] Un ID de conjunto de cambios. El ID del primer conjunto
  de cambios que fue añadido en el grupo. Todos los conjuntos de
  cambios entre éste y la punta
  %TODO mirar qué hacer con el índice
  \index{tags!\texttt{tip}}(\texttt{tip}), inclusive, fueron añadidos
  %TODO unbundle
  por un único jalado (\hgcmd{pull}), empuje (\hgcmd{push}) o \hgcmd{unbundle}.
\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la
  sección~\ref{sec:hook:sources} para más detalles.
\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
  es conocida. Vea la sección~\ref{sec:hook:url} para más información.
\end{itemize}

Veta también: \hook{incoming} (sección~\ref{sec:hook:incoming}),
\hook{prechangegroup} (sección~\ref{sec:hook:prechangegroup}),
\hook{pretxnchangegroup} (sección~\ref{sec:hook:pretxnchangegroup})

\subsection{\hook{commit}---luego de la creación de un nuevo conjunto
de cambios}
\label{sec:hook:commit}

Este gancho es ejecutado luego de la creación de un nuevo conjunto de
cambios.

Parámetros para este gancho:
\begin{itemize}
\item[\texttt{node}] Un ID de conjunto de cambios. El ID de conjunto
  de cambios del conjunto de cambios que acabó de ser consignado.
\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID de
  conjunto de cambios del primer padre del conjunto de cambios que
  acaba de ser consignado.
\item[\texttt{parent2}] Un ID de conjunto de cambios. El ID de
  conjunto de cambios del segundo padre del conjunto de cambios que
  acaba de ser consignado.
\end{itemize}

Vea también: \hook{precommit} (sección~\ref{sec:hook:precommit}),
\hook{pretxncommit} (sección~\ref{sec:hook:pretxncommit})

\subsection{\hook{incoming}---luego de que un conjunto de cambios
remoto es añadido}
\label{sec:hook:incoming}

Este gancho es ejecutado luego de que un conjunto de cambios
preexistente ha sido añadido al repositorio, por ejemplo, vía un
\hgcmd{push}.  Si un grupo de conjuntos de cambios fue añadido en una
sola operación, este gancho es ejecutado una vez por cada conjunto de
cambios añadido.

Usted puede usar este gancho para los mismos fines que el gancho
\hook{changegroup} (sección~\ref{sec:hook:changegroup}); simplemente
algunas veces es más conveniente ejecutar un gancho una vez por cada
grupo de conjuntos de cambios, mientras que otras es más útil correrlo
por cada conjunto de cambios.

Parámetros para este gancho:
\begin{itemize}
\item[\texttt{node}] Un ID de conjunto de cambios. El ID del conjunto
  de cambios recién añadido.
\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la
  sección~\ref{sec:hook:sources} para más detalles.
\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
  es conocida. Vea la sección~\ref{sec:hook:url} para más información.
\end{itemize}

Vea también: \hook{changegroup} (sección~\ref{sec:hook:changegroup})
\hook{prechangegroup} (sección~\ref{sec:hook:prechangegroup}),
\hook{pretxnchangegroup} (sección~\ref{sec:hook:pretxnchangegroup})

\subsection{\hook{outgoing}---luego de la propagación de los conjuntos
de cambios}
\label{sec:hook:outgoing}

Este gancho es ejecutado luego de que un grupo de conjuntos de cambios
ha sido propagado fuera de éste repositorio, por ejemplo por un
comando \hgcmd{push} o \hgcmd{bundle}.

Un uso posible para este gancho es notificar a los administradores que
los cambios han sido jalados.

Parámetros para este gancho:
\begin{itemize}
\item[\texttt{node}] Un ID de conjunto de cambios. El ID del primer conjunto
  de cambios del grupo que fue enviado.
\item[\texttt{source}] Una cadena. La fuente de la operación (vea la
  sección~\ref{sec:hook:sources}).  Si un cliente remoto jaló cambios
  de este repositorio, \texttt{source} será \texttt{serve}.  Si el
  cliente que obtuvo los cambios desde este repositorio era local,
  \texttt{source} será \texttt{bundle}, \texttt{pull}, o
  \texttt{push}, dependiendo de la operación que llevó a cabo el
  cliente.
\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
  es conocida. Vea la sección~\ref{sec:hook:url} para más información.
\end{itemize}

Vea también: \hook{preoutgoing} (sección~\ref{sec:hook:preoutgoing})

\subsection{\hook{prechangegroup}---antes de empezar la adición de
conjuntos de cambios remotos}
\label{sec:hook:prechangegroup}

Este gancho de control es ejecutado antes de que Mercurial empiece a
añadir un grupo de conjuntos de cambios de otro repositorio.

Este gancho no tiene ninguna información acerca de los conjuntos de
cambios que van a ser añadidos, porque es ejecutado antes de que se
permita que empiece la transmisión de dichos conjuntos de cambios. Si
este gancho falla, los conjuntos de cambios no serán transmitidos.

Un uso para este gancho es prevenir que se añadan cambios externos a un
repositorio. Por ejemplo, usted podría usarlo para ``congelar''
temporal o permanentemente una rama ubicada en un servidor para que
los usuarios no puedan empujar cambios a ella, y permitiendo al mismo
tiempo modificaciones al repositorio por parte de un administrador
local.

Parámetros para este gancho:
\begin{itemize}
\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la
  sección~\ref{sec:hook:sources} para más detalles.
\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
  es conocida. Vea la sección~\ref{sec:hook:url} para más información.
\end{itemize}

Vea también: \hook{changegroup} (sección~\ref{sec:hook:changegroup}),
\hook{incoming} (sección~\ref{sec:hook:incoming}), ,
\hook{pretxnchangegroup} (sección~\ref{sec:hook:pretxnchangegroup})

\subsection{\hook{precommit}---antes de iniciar la consignación de un
conjunto de cambios}
\label{sec:hook:precommit}

Este gancho es ejecutado antes de que Mercurial inicie la consignación
de un nuevo conjunto de cambios. Es ejecutado antes de que Mercurial
tenga cualquier de los metadatos para la consignación, como los
ficheros a ser consignados, el mensaje de consignación, o la fecha de
consignación.

Un uso para este gancho es deshabilitar la capacidad de consignar
nuevos conjuntos de cambios, pero permitiendo conjuntos de cambios
entrantes. Otro es ejecutar un proceso de ensamble/compilación o
prueba, y permitir la consignación sólo si el ensamble/compilación o
prueba tiene éxito.

Parámetros para este gancho:
\begin{itemize}
  \item[\texttt{parent1}] Un ID de conjunto de cambios. El ID de
  conjunto de cambios del primer padre del directorio de trabajo.
\item[\texttt{parent2}] Un ID de conjunto de cambios. El ID de
  conjunto de cambios del segundo padre del directorio de trabajo.
\end{itemize}
Si la consignación continúa, los padres del directorio de trabajo se
convertirán en los padres del nuevo conjunto de cambios.

Vea también: \hook{commit} (sección~\ref{sec:hook:commit}),
\hook{pretxncommit} (sección~\ref{sec:hook:pretxncommit})

\subsection{\hook{preoutgoing}---antes de empezar la propagación de
conjuntos de cambios}
\label{sec:hook:preoutgoing}

Este gancho es ejecutado antes de que Mercurial conozca las
identidades de los conjuntos de cambios que deben ser transmitidos.

Un uso para este gancho es evitar que los cambios sean transmitidos a
otro repositorio.

Parámetros para este gancho:
\begin{itemize}
  \item[\texttt{source}] Una cadena. La fuente la operación que está
    tratando de obtener cambios de éste repositorio (vea
    la sección~\ref{sec:hook:sources}).  Revise la documentación para
    el parámetro \texttt{source} del gancho \hook{outgoing}, en la
    sección~\ref{sec:hook:outgoing}, para ver los posibles valores de
    este parámetro.
\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
    es conocida. Vea la sección~\ref{sec:hook:url} para más información.
\end{itemize}

Vea también: \hook{outgoing} (sección~\ref{sec:hook:outgoing})

\subsection{\hook{pretag}---antes de etiquetar un conjunto de cambios}
\label{sec:hook:pretag}

Este gancho de control es ejecutado antes de la creación de una
etiqueta. Si el gancho termina exitosamente, la creación de la
etiqueta continúa. Si el gancho falla, no se crea la etiqueta.

Parámetros para este gancho:
\begin{itemize}
\item[\texttt{local}] Un booleano. Indica si la etiqueta es local a
  ésta instancia del repositorio (p.e.~almacenado en
  \sfilename{.hg/localtags}) o administrado por Mercurial (almacenado
  en \sfilename{.hgtags}).
\item[\texttt{node}] Un ID de conjunto de cambios. El ID del conjunto
  de cambios a etiquetar.
\item[\texttt{tag}] Una cadena. El nombre de la etiqueta por crear.
\end{itemize}

Si la etiqueta que se va a crear se encuentra bajo control de
revisiones, los ganchos \hook{precommit} y \hook{pretxncommit}
(secciones~\ref{sec:hook:commit} y~\ref{sec:hook:pretxncommit})
también serán ejecutados.

Vea también: \hook{tag} (sección~\ref{sec:hook:tag})

\subsection{\hook{pretxnchangegroup}---antes de completar la adición
de conjuntos de cambios remotos}
\label{sec:hook:pretxnchangegroup}

Este gancho de control es ejecutado antes de una transacción---la que
maneja la adición de un grupo de conjuntos de cambios nuevos desde
fuera del repositorio---se complete.  Si el gancho tiene éxito, la
transacción se completa, y todos los conjuntos de cambios se vuelven
permanentes dentro de este repositorio. Si el gancho falla, la
transacción es deshecha, y los datos para los conjuntos de cambios son
eliminados.

Este gancho puede acceder a los metadatos asociados con los conjuntos
de cambios casi añadidos, pero no debe hacer nada permanente con estos
datos. Tampoco debe modificar el directorio de trabajo.

Mientras este gancho está corriendo, si otro proceso Mercurial accesa
el repositorio, podrá ver los conjuntos de cambios casi añadidos como
si fueran permanentes. Esto puede llevar a condiciones de carrera si
usted no toma precauciones para evitarlas.

Este gancho puede ser usado para examinar automáticamente un grupo de
conjuntos de cambios. Si el gancho falla, todos los conjuntos de
cambios son ``rechazados'' cuando la transacción se deshace.

Parámetros para este gancho:
\begin{itemize}
  \item[\texttt{node}] Un ID de conjunto de cambios. El ID del primer
  conjunto de cambios que fue añadido en el grupo. Todos los
  conjuntos de cambios entre éste y el
  \index{tags!\texttt{tip}}\texttt{tip}, inclusive, fueron añadidos
  por un único \hgcmd{pull}, \hgcmd{push} o \hgcmd{unbundle}.
\item[\texttt{source}] Una cadena. La fuente de estos cambios. Vea la
  sección~\ref{sec:hook:sources} para más detalles.
\item[\texttt{url}] Una URL. La ubicación del repositorio remoto, si
  es conocida. Vea la sección~\ref{sec:hook:url} para más información.
\end{itemize}

Vea también: \hook{changegroup} (sección~\ref{sec:hook:changegroup}),
\hook{incoming} (sección~\ref{sec:hook:incoming}),
\hook{prechangegroup} (sección~\ref{sec:hook:prechangegroup})

\subsection{\hook{pretxncommit}---antes de completar la consignación
de un nuevo conjunto de cambios}
\label{sec:hook:pretxncommit}

Este gancho de control es ejecutado antes de que una transacción---que
maneja una nueva consignación---se complete. Si el gancho tiene éxito,
la transacción se completa y el conjunto de cambios se hace permanente
dentro de éste repositorio. Si el gancho falla, la transacción es
deshecha, y los datos de consignación son borrados.

Este gancho tiene acceso a los metadatos asociados con el
prácticamente nuevo conjunto de cambios, pero no debería hacer nada
permanente con estos datos. Tampoco debe modificar el directorio de
trabajo.

Mientras este gancho está corriendo, si otro proceso Mercurial accesa
éste repositorio, podrá ver el prácticamente nuevo conjunto de cambios
como si fuera permanente. Esto puede llevar a condiciones de carrera si
usted no toma precauciones para evitarlas.

Parámetros para este gancho:
\begin{itemize}
  \item[\texttt{node}] Un ID de conjunto de cambios. El ID del
    conjunto de cambios recién consignado.
\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID de
  conjunto de cambios del primer padre del conjunto de cambios que
  acaba de ser consignado.
\item[\texttt{parent2}] Un ID de conjunto de cambios. El ID de
  conjunto de cambios del segundo padre del conjunto de cambios que
  acaba de ser consignado.
\end{itemize}

Vea también: \hook{precommit} (sección~\ref{sec:hook:precommit})

\subsection{\hook{preupdate}---antes de actualizar o fusionar el
directorio de trabajo}
\label{sec:hook:preupdate}

Este gancho de control es ejecutado antes de actualizar o fusionar el
directorio de trabajo. Es ejecutado sólo si las revisiones usuales de
Mercurial antes de las actualizaciones determinan que la actualización
o fusión pueden proceder. Si el gancho termina exitosamente, la
actualización o fusión pueden proceder.; si falla, la actualización o
fusión no empiezan.

Parámetros para este gancho:
\begin{itemize}
\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID del
  padre al que el directorio de trabajo será actualizado. Si se está
  fusionando el directorio de trabajo, no cambiará este padre.
\item[\texttt{parent2}] Un ID de conjunto de cambios. Sólo está
  definido si se está fusionando el directorio de trabajo. El ID de la
  revisión con la cual está siendo fusionado el directorio de trabajo.
\end{itemize}

Vea también: \hook{update} (sección~\ref{sec:hook:update})

\subsection{\hook{tag}---luego de etiquetar un conjunto de cambios}
\label{sec:hook:tag}

Este gancho es ejecutado luego de la creación de una etiqueta.

Parámetros para este gancho:
\begin{itemize}
\item[\texttt{local}] Un booleano. Indica si la etiqueta es local a
  ésta instancia del repositorio (p.e.~almacenado en
  \sfilename{.hg/localtags}) o administrado por Mercurial (almacenado
  en \sfilename{.hgtags}).
\item[\texttt{node}] Un ID de conjunto de cambios. El ID del
  conjunto de cambios que fue etiquetado.
\item[\texttt{tag}] Una cadena. El nombre de la etiqueta que fue
  creada.
\end{itemize}

Si la etiqueta creada está bajo control de revisiones, el gancho
\hook{commit} (sección~\ref{sec:hook:commit}) es ejecutado antes de
este gancho.

Vea también: \hook{pretag} (sección~\ref{sec:hook:pretag})

\subsection{\hook{update}---luego de actualizar o fusionar el
directorio de trabajo}
\label{sec:hook:update}

Este gancho es ejecutado después de una actualización o fusión en el
directorio de trabajo. Ya que una fusión puede fallar (si el comando
externo \command{hgmerge} no puede resolver los conflictos en un
fichero), este gancho indica si la actualización o fusión fueron
completados adecuadamente.

\begin{itemize}
\item[\texttt{error}] Un booleano. Indica si la actualización o fusión
  fue completada exitosamente.
\item[\texttt{parent1}] Un ID de conjunto de cambios. El ID del padre
  al cual fue actualizado el directorio de trabajo. Si se fusionó el
  directorio de trabajo, no se habrá cambiado este padre.
\item[\texttt{parent2}] Un ID de conjunto de cambios. Sólo está
  definido si se fusionó el directorio de trabajo. El ID de la
  revisión con la que fue fusionado el directorio de trabajo.
\end{itemize}

Vea también: \hook{preupdate} (sección~\ref{sec:hook:preupdate})

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "00book"
%%% End: 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.