es/ markup fixes.
[gitmagic/gitmagic.git] / es / history.txt
blob913737eab761e016f7f72f6a79e5008ba51b401d
1 == Lecciones de Historia ==
3 Una consecuencia de la naturaleza distribuída de git, es que la historia puede ser editada
4 facilmente. Pero si manipulas el pasado, ten cuidado: solo reescribe la parte de
5 la historia que solamente tú posees. Así como las naciones discuten eternamente sobre quién
6 cometió qué atrocidad, si otra persona tiene un clon cuya versión de la historia
7 difiere de la tuya, vas a tener problemas para reconciliar ambos árboles cuando éstos interactúen.
9 Por supuesto, si también controlas todos los demás árboles, puedes simplemente
10 sobreescribirlos.
12 Algunos desarrolladores están convencidos de que la historia debería ser inmutable, incluso con sus defectos.
13 Otros sienten que los árboles deberían estar presentables antes de ser mostrados en
14 público. Git satisface ambos puntos de vista. Al igual que el clonar, hacer branches y hacer merges,
15 reescribir la historia es simplemente otro poder que Git te da. Está en tus manos
16 usarlo con sabiduría.
18 === Me corrijo ===
20 ¿Hiciste un commit, pero preferirías haber escrito un mensaje diferente? Entonces escribe:
22  $ git commit --amend
24 para cambiar el último mensaje. ¿Te olvidaste de agregar un archivo? Ejecuta *git add* para
25 agregarlo, y luego corre el comando de arriba.
27 ¿Quieres incluir algunas ediciones mas en ese último commit? Edita y luego escribe:
29  $ git commit --amend -a
31 === ... Y Algo Más ===
33 Supongamos que el problema anterior es diez veces peor. Luego de una larga sesión hiciste unos cuantos commits.
34 Pero no estás conforme con la forma en que están organizados, y a algunos de los mensajes de esos commits les 
35 vendría bien una reescritura. Entonces escribe:
37  $ git rebase -i HEAD~10
39 y los últimos 10 commits van a aparecer en tu $EDITOR favorito. Un fragmento de muestra:
41     pick 5c6eb73 Added repo.or.cz link
42     pick a311a64 Reordered analogies in "Work How You Want"
43     pick 100834f Added push target to Makefile
45 Entonces:
47 - Elimina commits borrando líneas.
48 - Reordena commits reordenando líneas.
49 - Reemplaza "pick" por "edit" para marcar un commit para arreglarlo.
50 - Reemplaza "pick" por "squash" para unir un commit con el anterior.
52 Si marcaste un commit para edición, entonces ejecuta:
54  $ git commit --amend
56 En caso contrario, corre:
58  $ git rebase --continue
60 Por lo tanto, es bueno hacer commits temprano y seguido: siempre se puede acomodar después usando rebase.
62 === Los Cambios Locales Al Final ===
64 Estás trabajando en un proyecto activo. Haces algunos commits locales por un tiempo, y
65 entonces sincronizas con el árbol oficial usando un merge. Este ciclo se repite unas
66 cuantas veces antes de estar listo para hacer push hacia el árbol central.
68 El problema es que ahora la historia en tu clon local de Git, es un entrevero de tus cambios
69 y los cambios oficiales. Preferirías ver todos tus cambios en una sección contigua,
70 luego de todos los cambios oficiales.
72 Lo descrito arriba es un trabajo para *git rebase*. En muchos casos se puede usar
73 la bandera *--onto* y evitar la interacción.
75 Ver *git help rebase* para ejemplos detallados de este asombroso comando.
76 Se pueden partir commits. Incluso se pueden reordenar las branches de un árbol.
78 === Reescribiendo la Historia ===
80 Ocasionalmente, se necesita algo equivalente a borrar gente de fotos oficiales,
81 pero para control de código, para borrar cosas de la historia de manera Stalinesca. Por
82 ejemplo, supongamos que queremos lanzar un proyecto, pero involucra un archivo que
83 debería ser privado por alguna razón. Quizás dejé mi número de tarjeta de crédito en
84 un archivo de texto y accidentalmente lo agregué al proyecto. Borrar el archivo es
85 insuficiente, dado que se puede acceder a él en commits viejos. Debemos eliminar
86 el archivo de todos los commits:
88  $ git filter-branch --tree-filter 'rm archivo/secreto' HEAD
90 Ver *git help filter-branch*, donde se discute este ejemplo y se da un método
91 más rápido. En general, *filter-branch* permite alterar grandes secciones de
92 la historia con un solo comando.
94 Luego, el directorio +.git/refs/original+ describe el estado de las cosas antes de la operación.
95 Revisa que el comando filter-branch hizo lo que querías, y luego borra este directorio si deseas
96 ejecutar más comandos filter-branch.
98 Por último, reemplaza los clones de tu proyecto con tu versión
99 revisada si pretendes interactuar con ellos en un futuro.
101 === Haciendo Historia ===
103 [[makinghistory]]
104 ¿Quieres migrar un proyecto a Git? Si está siendo administrado con alguno de los sistemas más conocidos,
105 hay grandes posibilidades de que alguien haya escrito un script para exportar la historia completa a Git.
107 Si no lo hay, revisa *git fast-import*, que lee una entrada de texto en un formato
108 específico para crear una historia de Git desde la nada. Típicamente un script que usa
109 este comando se acomoda de apuro y se corre una sola vez, migrando el proyecto de
110 un solo tiro.
112 Como ejemplo, pega el texto a continuación en un archivo temporal, como ser `/tmp/history`:
113 ----------------------------------
114 commit refs/heads/master
115 committer Alice <alice@example.com> Thu, 01 Jan 1970 00:00:00 +0000
116 data <<EOT
117 Initial commit.
120 M 100644 inline hello.c
121 data <<EOT
122 #include <stdio.h>
124 int main() {
125   printf("Hello, world!\n");
126   return 0;
131 commit refs/heads/master
132 committer Bob <bob@example.com> Tue, 14 Mar 2000 01:59:26 -0800
133 data <<EOT
134 Replace printf() with write().
137 M 100644 inline hello.c
138 data <<EOT
139 #include <unistd.h>
141 int main() {
142   write(1, "Hello, world!\n", 14);
143   return 0;
147 ----------------------------------
149 Luego crea un repositorio Git desde este archivo temporal escribiendo:
151  $ mkdir project; cd project; git init
152  $ git fast-import < /tmp/history
154 Puedes hacer checkout de la última versión del proyecto con:
156  $ git checkout master .
158 El comando *git fast-export* convierte cualquier repositorio de git al
159 formato de *git fast-import*, y puedes estudiar su salida para escribir exportadores,
160 y también para transportar repositorios de git en un formato legible por humanos. De hecho
161 estos comandos pueden enviar repositorios de archivos de texto sobre canales de solo texto.
163 === ¿Dónde Nos Equivocamos? ===
165 Acabas de descubrir una prestación rota en tu programa, y estás seguro
166 que hace unos pocos meses funcionaba. ¡Argh! ¿De donde salió este bug?
167 Si solo hubieras ido testeando a medida que desarrollabas.
169 Es demasiado tarde para eso ahora. De todos modos, dado que haz ido haciendo commits seguido, Git
170 puede señalar la ubicación del problema.
172  $ git bisect start
173  $ git bisect bad SHA1_DE_LA_VERSION_MALA
174  $ git bisect good SHA1_DE_LA_VERSION_BUENA
176 Git hace checkout de un estado a mitad de camino. Prueba la funcionalidad, y si aún está rota:
178  $ git bisect bad
180 Si no lo está, reemplaza "bad" por "good". Git una vez más te transporta a un estado en mitad de camino
181 de las versiones buena y mala, acortando las posibilidades.
182 Luego de algunas iteraciones, esta búsqueda binaria va a llevarte al commit que
183 causó el problema. Una vez que hayas terminado tu investigación, vuelve a tu estado
184 original escribiendo:
186  $ git bisect reset
188 En lugar de testear cada cambio a mano, automatiza la búsquea escribiendo:
190  $ git bisect run COMANDO
192 Git utiliza el valor de retorno del comando dado, típicamente un script hecho solo para eso, para
193 decidir si un cambio es bueno o malo: el comando debería salir con código 0 
194 si es bueno, 125 si el cambio se debería saltear, y cualquier cosa entre 1 
195 y 127 si es malo. Un valor negativo aborta el bisect.
197 Puedes hacer mucho más: la página de ayuda explica como visualizar bisects, examinar
198 o reproducir el log de un bisect, y eliminar cambios inocentes conocidos para que
199 la búsqueda sea más rápida.
201 === ¿Quién Se Equivocó? ===
203 Como muchos otros sistemas de control de versiones, Git tiene un comando blame:
205  $ git blame ARCHIVO
207 que anota cada línea en el archivo dado mostrando quién fue el último en cambiarlo y cuando.
208 A diferencia de muchos otros sistemas de control de versiones, esta operación trabaja desconectada,
209 leyendo solo del disco local.
211 === Experiencia Personal ===
213 En un sistema de control de versiones centralizado, la modificación de la historia es una operación
214 dificultosa, y solo disponible para administradores. Clonar, hacer branches y merges,
215 es imposible sin comunicación de red. Lo mismo para operaciones básicas como
216 explorar la historia, o hacer commit de un cambio. En algunos sistemas, los usuarios
217 requieren conectividad de red solo para ver sus propios cambios o abrir un archivo
218 para edición.
220 Los sistemas centralizados no permiten trabajar desconectado, y necesitan una
221 infraestructura de red más cara, especialmente a medida que aumenta el número de desarrolladores. Lo
222 más importante, todas las operaciones son más lentas de alguna forma, usualmente al punto
223 donde los usuarios evitan comandos avanzados a menos que sean absolutamente necesarios. En casos
224 extremos esto se da incluso para los comandos más básicos. Cuando los usuarios
225 deben correr comandos lentos, la productividad sufre por culpa de un flujo de trabajo interrumpido.
227 Yo experimenté estos fenómenos de primera mano. Git fue el primer sistema de control
228 de versiones que usé. Me acostumbré rápidamente a él, dando por ciertas varias
229 funcionalidades. Simplemente asumí que otros sistemas eran similares: elegir
230 un sistema de control de versiones no debería ser diferente de elegir un editor de texto
231 o navegador web.
233 Cuando me vi obligado a usar un sistema centralizado me sorprendí. Una mala conexión
234 a internet importa poco con Git, pero hace el desarrollo insoportable cuando se necesita
235 que sea confiable como un disco local. Adicionalmente me encontré condicionado
236 a evitar ciertos comandos por las latencias involucradas, lo que terminó
237 evitando que pudiera seguir mi flujo de trabajo deseado.
239 Cuando tenía que correr un comando lento, la interrupción de mi tren de pensamiento
240 generaba una cantidad de daño desproporcionada. Mientras esperaba que se complete
241 la comunicación con el servidor, hacía alguna otra cosa para pasar el tiempo, como 
242 revisar el e-mail o escribir documentación. A la hora de volver a la tarea original, 
243 el comando había terminado hace tiempo, y yo perdía más tiempo intentando recordar
244 qué era lo que estaba haciendo. Los humanos no son buenos para el cambio de contexto.
246 También había un interesante efecto tragediad-de-los-comunes: anticipando
247 la congestión de la red, la gente consume más ancho de banda que el necesario
248 en varias operaciones, intentando anticipar futuras demoras. El esfuerzo combinado
249 intensifica la congestión, alentando a las personas a consumir aún más ancho de banda
250 la próxima vez para evitar demoras incluso más largas.