Merge branch 'patch-1' of https://github.com/gitnacho/gitmagic
[gitmagic.git] / es / grandmaster.txt
blobf4b0ee07e6917be915d946cf9b1c67f00d3baaeb
1 == Gran Maestría en Git ==
3 Esta página con nombre pretencioso es el cajón donde dejar los trucos de Git no categorizados.
5 === Lanzamientos de Código ===
7 Para mis proyectos, Git controla únicamente los ficheros que me gustaría archivar y enviar a 
8 los usuarios. Para crear un tarball del código fuente, ejecuto:
10  $ git archive --format=tar --prefix=proj-1.2.3/ HEAD
12 === Commit De Lo Que Cambió ===
14 Decirle a Git cuándo agregaste, eliminaste o renombraste archivos es complicado
15 para ciertos proyectos. En cambio, puedes escribir:
17  $ git add .
18  $ git add -u
20 Git va a mirar los archivos en el directorio actual y resolver los detalles
21 por si mismo. En lugar del segundo comando add, corre `git commit -a` si estás en condiciones
22 de hacer commit. Ver en *git help ignore* como especificar archivos
23 que deberían ser ignorados.
25 Puedes hacer lo de arriba en un único paso con:
27  $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove
29 Las opciones *-z* y *-0* previenen efectos secundarios adversos de archivos que contienen
30 caracteres extraños. Como este comando agrega archivos ignorados, podrías querer usar la opción
31 `-x` or `-X`.
33 === ¡Mi Commit Es Muy Grande! ===
35 ¿Postergaste hacer un commit por demasiado tiempo? ¿Estabas enfervorizado 
36 escribiendo código y te olvidaste del control de fuentes hasta ahora?
37 ¿Hiciste una serie de cambios no relacionados, simplemente porque es tu estilo?
39 No te preocupes, ejecuta:
41  $ git add -p
43 Por cada edición que hiciset, Git va a mostrar el pedazo de código que fue cambiado,
44 y preguntar si debería ser parte del próximo commit. Contesta con "y" o "n". 
45 Hay otras opciones, como posponer la decisión; escribe "?" para saber más.
47 Una vez satisfecho, escribe
49  $ git commit
51 para hacer un commit que solo contiene los cambios seleccionados (los cambios 'staged'). Asegúrate
52 de omitir la opción *-a*, o Git va a poner todo lo editado en el commit.
54 ¿Que pasa si editaste varios archivos en varios lugares? Revisar cada cambio uno por uno
55 se vuelve frustrante y adormecedor. En este caso, usa *git add -i*, cuya interfaz
56 es menos clara pero más flexible. Con solo presionar un par de teclas, puedes poner 
57 o sacar del 'stage' varios archivos a la vez, o revisar y seleccionar cambios solamente
58 en archivos particulares. Como alternativa se puede usar *git commit --interactive*, el
59 cual hace commit luego de que terminas.
61 ==== Cambios en el 'stage' ====
63 Hasta ahora hemos evitado el famoso 'indice' de git, pero ahora debermos enfrentarlo
64 para explicar lo de arriba. El indice es un area temporal de montaje. Git evita enviar
65 datos directamente entre tu proyecto y su historia. En su lugar, Git primero escribe datos
66 al índice, y luego copia los datos del índice a su destino final.
68 Por ejemplo, *commit -a* es en realidad un proceso de 2 pasos. El primer paso pone 
69 una foto del estado actual de cada archivo administrado en el índice. El segundo paso
70 graba de forma permanente esa foto que está en el índice. Un commit hecho sin *-a*
71 solo efectúa el segundo paso, y solo tiene sentido luego de haber ejecutado comandos
72 que de alguna forma alteran el índice, como *git add*.
74 Usualmente podemos ignorar el índice y pretender que estamos leyendo y escribiendo
75 directo en la historia. En esta ocasión, queremos un control más fino de lo que se
76 escribe en la historia, y nos vemos forzados a manipular el índice. Guardamos una foto de
77 algunos, pero no todos, de nuestros cambios en el índice, y luego grabamos
78 de forma permanenta esta instantánea cuidadosamente organizada.
80 === No Pierdas La Cabeza ===
82 El tag HEAD (Cabeza) es como un cursor que normalmente apunta al último commit, avanzando
83 con cada nuevo commit. Algunos comandos de Git te dejan moverlo. Por ejemplo:
85  $ git reset HEAD~3
87 mueve el HEAD tres commits hacia atrás. Por lo tanto todos los comandos de Git ahora
88 actúan como si no hubieras hecho esos últimos tres commits, mientras tus archivos 
89 permanecen en el presente. Ver la página de ayuda para algunas aplicaciones.
91 ¿Como hago para volver al futuro? Los commits del pasado nada saben del futuro.
93 Teniendo el SHA1 del HEAD original, hacemos:
95  $ git reset SHA1
97 Pero supongamos que nunca lo anotaste. No te preocupes, para comandos como este, Git
98 guarda el HEAD original como un tag llamado ORIG_HEAD, y puedes volver sano y salvo con:
100  $ git reset ORIG_HEAD
102 === Cazando Cabezas ===
104 Quizás ORIG_HEAD no es suficiente. Quizás acabas de descubrir que cometiste un error monumental
105 y que hay que volver a un commit antiguo en una rama olvidada hace largo tiempo.
107 Por defecto, Git guarda un commit por al menos 2 semanas, incluso si le ordenaste destruir
108 la rama que lo contenía. El problema es encontra el hash apropiado. Podrías
109 mirar todos los hashes en `.git/objects` y usar prueba y error para encontrar el que buscas.
110 Pero hay una forma mucho más fácil.
112 Git guarda el hash de cada commit que hace en `.git/logs`. El subdirectorio `refs` contiene
113 la historia de la actividad en todas las ramas, mientras que el archivo `HEAD` tiene cada hash
114 que alguna vez ha tomado. Este último puede usarse para encontrar hashes de commits en branches
115 que se han borrado de manera accidental.
117 El comando reflog provee una interfaz amigable para estos logs. Prueba
119   $ git reflog
121 En lugar de cortar y pegar hashes del reflog, intenta:
123  $ git checkout "@{10 minutes ago}"
125 O prueba un checkout del 5to commit que visitaste hacia atrás:
127  $ git checkout "@{5}"
129 Ver la sección ``Specifying Revisions'' de *git help rev-parse* por mas datos.
131 Podrías querer configurar un periodo de gracia mayor para los commits condenados. Por ejemplo:
133   $ git config gc.pruneexpire "30 days"
135 significa que un commmit eliminado se va a perder de forma permanente solo cuando
136 hayan pasado 30 dáis y se ejecute *git gc*.
138 También podrías querer deshabilitar invocaciones automáticas de *git gc*:
140   $ git config gc.auto 0
142 en cuyo caso los commits solo serán borrados cuando ejecutes *git gc* de forma manual.
144 === Construyendo sobre Git ===
146 Siguiendo la tradición UNIX, el diseño de Git permite ser facilmente usado como un componente de bajo
147 nivel de otros programas, como GUI e interfaces web, interfaces de linea de comandos alternativas,
148 herramientas de manejo de patches, herramientas de importación y conversión, etc.
149 De hecho, algunos de los comandos de Git son ellos mismos scripts parados sobre los hombros de gigantes.
150 Con unos pocos ajustes, puedes personalizar Git para cubrir tus necesidades.
152 Un truco simple es usar los alias incluidos en git para acortar los comandos
153 usados de forma más frecuente:
155   $ git config --global alias.co checkout
156   $ git config --global --get-regexp alias  # muestra los alias actuales
157   alias.co checkout
158   $ git co foo                              # igual a 'git checkout foo'
160 Otro es imprimir la rama actual en el prompt, o en el título de la ventana.
162 Usar
164   $ git symbolic-ref HEAD
166 muestra el nombre de la rama actual. En la práctica, es probable que quieras quitar el 
167 "refs/heads/" e ignorar los errores:
169   $ git symbolic-ref HEAD 2> /dev/null | cut -b 12-
171 El subdirectorio +contrib+ es la cueva de los tesoros de las herramientas hechas con Git.
172 Con tiempo, algunas de ellas pueden ser promovidas a comandos oficiales. En Debian y Ubuntu,
173 este directorio está en +/usr/share/doc/git-core/contrib+.
175 Un residente popular es +workdir/git-new-workdir+. Usando symlinks inteligentes, este script
176 crea un nuevo directorio de trabajo cuya historia es compartida con el repositorio original:
177   $ git-new-workdir repositorio/existente nuevo/directorio
179 El nuevo directorio y sus archivos interiores pueden ser vistos como un clon, excepto que como la 
180 historia es compartida, ambos árboles se mantienen sincronizados de forma automática.
181 No hay necesidad de merges, push ni pull.
183 === Acrobacias Peligrosas ===
185 En estos dias, Git hace difícil que el usuario destruya datos de manera accidental.
186 Pero si sabes lo que estás haciendo, puedes hacer caso omiso de las trabas de seguridad para
187 los comandos comunes.
190 *Checkout*: Los cambios no commiteados hacen que checkout falle. Para destruir tus cambios, y hacer checkout de un commit dado, usa la opción de forzar:
192   $ git checkout -f COMMIT
194 Por otro lado, si especificas una ruta específica para hacer checkout, no hay chequeos de seguridad.
195 Las rutas suministradas son sobre-escritas de forma silenciosa.
196 Hay que tener cuidado al usar checkout de esta forma:
198 *Reset*: Reset también falla en presencia de cambios sin commmitear. Para hacerlo a la fuerza, ejecuta:
200   $ git reset --hard [COMMIT]
202 *Branch*: El borrado de una rama falla si esto causa que se pierdan cambios, para forzarlo escribe:
204   $ git branch -D BRANCH  # en lugar de -d
206 De forma similar, intentar sobreescribir una rama moviendo otra, falla si esto resultase en pérdida de datos. Para forzar el mover una rama, corre:
208   $ git branch -M [ORIGEN] DESTINO  # en lugar de -m
209 A diferencia de checkout y reset, estos dos comandos evitan la destrucción de datos.
210 Los cambios están aún guardados en el subdirectorio .git, y pueden obtenerse
211 recuperando el has apropiado de `.git/logs` (ver "Cazando Cabezas" arriba).
212 Por defecto, serán guardados por al menos dos semanas.
214 *Clean*: Algunos comandos de Git se rehúsan a proceder porque están preocupados
215 de destruir archivos no monitoreados. Si tienes la certeza de que todos los archivos
216 y directorios sin monitorear son prescindibles, se pueden borrar sin piedad con:
218   $ git clean -f -d
220 ¡La próxima vez, ese comando molesto va a funcionar!
222 === Mejora Tu Imagen Pública ===
224 Los errores estúpidos abundan en la historia de muchos proyectos. El más
225 preocupante son los archivos perdidos por el olvido de ejecutar *git add*.
226 Por suerte nunca perdí datos cruciales por omisión accidental, dado que muy rara
227 vez elimino directorios de trabajo originales. Lo normal es que note el error un par
228 de commits mas adelante, por lo que el único daño es un poco de historia perdida
229 y el tener que admitir la culpa.
231 También me preocupo por no tenes espacios en blanco al final de las líneas.
232 Aunque son inofensivos, procuro que nunca aparezcan en la historia pública.
234 Además, si bien nunca me sucedió, me preocupo por no dejar conflictos de merge
235 sin resolver. Usualmente los descubro al compilar el proyecto, pero hay algunos
236 casos en los que se puede no notar.
238 Es útil comprar un seguro contra la idiotez, usando un _hook_ para alertarme de 
239 estos problemas:
241  $ cd .git/hooks
242  $ cp pre-commit.sample pre-commit  # En versiones mas viejas de Git: chmod +x pre-commit
244 Ahora Git aborta un commit si se detectan espacios inútiles en blanco o conflictos
245 de merge sin resolver.
247 Para esta guía, eventualmente agregué lo siguiente al inicio del hook *pre-commit*,
248 pare prevenirme de la desatención.
250  if git ls-files -o | grep '\.txt$'; then
251    echo FALLA! Archivos .txt sin monitorear.
252    exit 1
253  fi
255 Varias operaciones de git soportan hooks; ver *git help hooks*. Se pueden escribir
256 hooks para quejarse de errores ortográficos en los mensajes de commit, agregar nuevos archivos,
257 indentar párrafos, agregar una entrada en una página, reproducir un sonido, etc.
259 Habíamos encontrado el hook *post-update* antes, cuando discutíamos como usar Git sobre HTTP.
260 Este hook actualiza algunos archivos que Git necesita para comunicación no nativa.