diff --git a/book/07-git-tools/sections/advanced-merging.asc b/book/07-git-tools/sections/advanced-merging.asc index ff46651f..d718881f 100644 --- a/book/07-git-tools/sections/advanced-merging.asc +++ b/book/07-git-tools/sections/advanced-merging.asc @@ -3,7 +3,7 @@ La fusión en Git suele ser bastante fácil. Dado que Git facilita la fusión de otra rama varias veces, significa que puede tener una rama de larga duración, pero puede mantenerla actualizada sobre la marcha, resolviendo pequeños conflictos a menudo, en lugar de sorprenderse por un conflicto enorme en el final de la serie. -Sin embargo, a veces ocurren conflictos engañosos. A diferencia de otros sistemas de control de versiones, Git no intenta ser demasiado listo para fusionar la resolución de conflictos. La filosofía de Git es ser inteligente para determinar cuándo una resolución de fusión no es ambigua, pero si hay un conflicto, no intenta ser inteligente para resolverlo automáticamente. Por lo tanto, si espera demasiado para fusionar dos ramas que divergen rápidamente, puede encontrarse algunos problemas. +Sin embargo, a veces ocurren conflictos engañosos. A diferencia de otros sistemas de control de versiones, Git no intenta ser demasiado listo para fusionar la resolución de conflictos. La filosofía de Git es ser inteligente para determinar cuándo una resolución de fusión no es ambigua, pero si hay un conflicto, no intenta ser inteligente para resolverlo automáticamente. Por lo tanto, si espera demasiado para fusionar dos ramas que divergen rápidamente, puede encontrarse con algunos problemas. En esta sección, veremos cuáles podrían ser algunos de esos problemas y qué herramientas le dará Git para ayudarlo a manejar estas situaciones más engañosas. También cubriremos algunos de los diferentes tipos de fusión no estándar que puede hacer, y también veremos cómo deshacerse de las fusiones que ha realizado. @@ -11,7 +11,7 @@ En esta sección, veremos cuáles podrían ser algunos de esos problemas y qué Si bien cubrimos algunos conceptos básicos para resolver conflictos de fusión en <>, para conflictos más complejos, Git proporciona algunas herramientas para ayudarlo a descubrir qué está sucediendo y cómo lidiar mejor con el conflicto. -En primer lugar, si es posible, intente asegurarse de que su directorio de trabajo esté limpio antes de realizar una fusión que pueda tener conflictos. Si tiene un trabajo en progreso, hágale commit a una rama temporal o stash. Esto hace que puedas deshacer *cualquier cosa* que intentes aquí. Si tiene cambios no guardados en su directorio de trabajo cuando intenta fusionarlos, algunos de estos consejos pueden ayudarlo a perder ese trabajo. +En primer lugar, si es posible, intente asegurarse de que su directorio de trabajo esté limpio antes de realizar una fusión que pueda tener conflictos. Si tiene un trabajo en progreso, hágale commit a una rama temporal o stash. Esto hace que pueda deshacer *cualquier cosa* que intente aquí. Si tiene cambios no guardados en su directorio de trabajo cuando intenta fusionarlos, algunos de estos consejos pueden ayudarlo a perder ese trabajo. Veamos un ejemplo muy simple. Tenemos un archivo Ruby super simple que imprime 'hello world'. @@ -115,13 +115,13 @@ $ git status -sb La opción `git merge --abort` intenta volver a su estado antes de ejecutar la fusión. Los únicos casos en los que podría no ser capaz de hacer esto a la perfección serían si hubiera realizado cambios sin stash, no confirmados en su directorio de trabajo cuando lo ejecutó, de lo contrario, debería funcionar bien. -Si por alguna razón te encuentras en un estado horrible y solo quieres comenzar de nuevo, también puedes ejecutar `git reset --hard HEAD` o donde quieras volver. Recuerda una vez más que esto hará volar tu directorio de trabajo, así que asegúrate de no querer ningún cambio allí. +Si por alguna razón se encuentra en un estado horrible y solo quiere comenzar de nuevo, también puede ejecutar `git reset --hard HEAD` o donde quiera volver. Recuerde, una vez más, que esto hará volar su directorio de trabajo, así que asegúrese de no querer ningún cambio allí. ===== Ignorando el Espacio en Blanco -En este caso específico, los conflictos están relacionados con el espacio en blanco. Sabemos esto porque el caso es simple, pero también es muy fácil decirlo en casos reales al analizar el conflicto porque cada línea se elimina por un lado y se agrega nuevamente por el otro. De manera predeterminada, Git ve que todas estas líneas están siendo modificadas, por lo que no puede fusionar los archivos. +En este caso específico, los conflictos están relacionados con el espacio en blanco. Sabemos esto porque el caso es simple, pero también es muy fácil saberlo en casos reales, al analizar el conflicto, porque cada línea se elimina por un lado y se agrega nuevamente por el otro. De manera predeterminada, Git ve que todas estas líneas están siendo modificadas, por lo que no puede fusionar los archivos. -Sin embargo, la estrategia de combinación predeterminada puede tomar argumentos, y algunos de ellos son acerca de ignorar adecuadamente los cambios del espacio en blanco. Si ve que tiene muchos problemas con espacios en blanco en una combinación, simplemente puede cancelarla y volverla a hacer, esta vez con `-Xignore-all-space` o` -Xignore-space-change`. La primera opción ignora los cambios en cualquier **cantidad** de espacios en blanco existentes, el segundo ignora por completo todos los cambios de espacios en blanco. +Sin embargo, la estrategia de combinación predeterminada puede tomar argumentos, y algunos de ellos son acerca de ignorar adecuadamente los cambios del espacio en blanco. Si ve que tiene muchos problemas con espacios en blanco en una combinación, simplemente puede cancelarla y volverla a hacer, esta vez con `-Xignore-all-space` o` -Xignore-space-change`. La primera opción ignora los cambios en cualquier **cantidad** de espacios en blanco existentes, la segunda ignora por completo todos los cambios de espacios en blanco. [source,console] ---- @@ -134,7 +134,7 @@ Merge made by the 'recursive' strategy. Dado que en este caso, los cambios reales del archivo no eran conflictivos, una vez que ignoramos los cambios en los espacios en blanco, todo se fusiona perfectamente. -Esto es un salvavidas si tienes a alguien en tu equipo a quien le gusta ocasionalmente reformatear todo, desde espacios hasta pestañas o viceversa. +Esto es un salvavidas si tiene a alguien en su equipo a quien le gusta ocasionalmente reformatear todo, desde espacios hasta pestañas o viceversa. [[r_manual_remerge]] ===== Re-fusión Manual de Archivos @@ -143,7 +143,7 @@ Aunque Git maneja muy bien el preprocesamiento de espacios en blanco, hay otros Lo que realmente tenemos que hacer es ejecutar el archivo que intentamos fusionar a través de un programa `dos2unix` antes de intentar fusionar el archivo. Entonces, ¿cómo haríamos eso? -Primero, entramos en el estado de conflicto de la fusión. Luego queremos obtener copias de mi versión del archivo, su versión (de la rama en la que nos estamos fusionando) y la versión común (desde donde ambos lados se bifurcaron). Entonces, queremos arreglar su lado o nuestro lado y volver a intentar la fusión nuevamente solo para este único archivo. +Primero, entramos en el estado de conflicto de la fusión. Luego queremos obtener copias de mi versión del archivo, su versión (de la rama en la que nos estamos fusionando) y la versión común (desde donde ambos lados se bifurcaron). Entonces, queremos arreglar su lado o nuestro lado y volver a intentar la fusión sólo para este único archivo. Obtener las tres versiones del archivo es bastante fácil. Git almacena todas estas versiones en el índice bajo ``etapas'', cada una de las cuales tiene números asociados. La etapa 1 es el ancestro común, la etapa 2 es su versión y la etapa 3 es de la `MERGE_HEAD`, la versión en la que se está fusionando (``suya''). @@ -156,7 +156,7 @@ $ git show :2:hello.rb > hello.ours.rb $ git show :3:hello.rb > hello.theirs.rb ---- -Si quieres ponerte un poco más intenso, también puedes usar el comando de plomería `ls-files -u` para obtener el verdadero SHA-1s de las manchas de Git para cada uno de los archivos. +Si quiere ponerse un poco más intenso, también puede usar el comando de plomería `ls-files -u` para obtener el verdadero SHA-1s de las manchas de Git para cada uno de los archivos. [source,console] ---- @@ -168,7 +168,7 @@ $ git ls-files -u El `:1:hello.rb` es solo una clave para buscar esa mancha SHA-1. -Ahora que tenemos el contexto de estas tres etapas en nuestro directorio de trabajo, manualmente podemos arreglar los de ellos para solucionar los problemas de espacios en blanco y volver a fusionar el archivo con el poco conocido comando `git merge-file` que hace exactamente eso. +Ahora que tenemos el contexto de estas tres etapas en nuestro directorio de trabajo, manualmente podemos arreglarlos para solucionar los problemas de espacios en blanco y volver a fusionar el archivo con el poco conocido comando `git merge-file` que hace exactamente eso. [source,console] ---- @@ -195,11 +195,11 @@ index 36c06c8,e85207e..0000000 hello() ---- -En este punto, hemos agradablemente fusionado el archivo. De hecho, esto en realidad funciona mejor que la opción de `ignore-all-space` porque esto realmente soluciona los cambios de los espacios en blanco antes de la fusión, en lugar de simplemente ignorarlo. En la fusión `ignore-all-space, realmente, terminamos con unas pocas líneas con finales de línea DOS, haciendo que las cosas se mezclen. +En este punto hemos, agradablemente, fusionado el archivo. De hecho, esto en realidad funciona mejor que la opción de `ignore-all-space`, porque realmente soluciona los cambios de los espacios en blanco antes de la fusión, en lugar de simplemente ignorarlo. En la fusión `ignore-all-space, en realidad, terminamos con unas pocas líneas con finales de línea DOS, haciendo que las cosas se mezclen. -Si quieres tener una idea antes de finalizar este compromiso sobre qué había cambiado en realidad entre un lado y el otro, puedes pedirle a `git diff` que compare qué hay en tu directorio de trabajo que estas a punto de comprometer como resultado de la fusión a cualquiera de estas etapas. Vamos a través de todas ellas. +Si quiere tener una idea antes de finalizar este compromiso sobre qué había cambiado en realidad entre un lado y el otro, puede pedirle a `git diff` que compare qué hay en su directorio de trabajo que está a punto de comprometer como resultado de la fusión a cualquiera de estas etapas. Vamos a través de todas ellas. -Para comparar el resultado con lo que tenías en tu rama antes de la fusión, en otra palabras, para ver lo que tu fusión insertó, puedes correr `git diff --ours` +Para comparar el resultado con lo que tenías en su rama antes de la fusión, en otras palabras, para ver lo que su fusión insertó, puede correr `git diff --ours` [source,console] ---- @@ -220,9 +220,9 @@ index 36c06c8..44d0a25 100755 hello() ---- -Así podemos observar fácilmente lo que sucedió en nuestra rama, lo que en realidad estamos insertando a este archivo con esta fusión, está cambiando solamente esa línea. +Así, podemos observar fácilmente lo que sucedió en nuestra rama, y si lo que en realidad estamos insertando a este archivo con esta fusión está cambiando solamente esa línea. -Si queremos ver cómo el resultado de la fusión difiere de lo que estaba del otro lado, puedes correr `git diff --theirs`. En este y el siguiente ejemplo, tenemos que usar `-w para despojarse de los espacios en blanco porque lo estamos comparando con lo que está en Git, no con nuestro archivo limpio `hello.theirs.rb` +Si queremos ver cómo el resultado de la fusión difiere de lo que estaba del otro lado, podemos correr `git diff --theirs`. En este y el siguiente ejemplo, tenemos que usar `-w` para despojarlo de los espacios en blanco porque lo estamos comparando con lo que está en Git, no con nuestro archivo limpio `hello.theirs.rb` [source,console] ---- @@ -241,7 +241,7 @@ index e85207e..44d0a25 100755 end ---- -Finalmente, puedes observar cómo el archivo ha cambiado desde ambos lados con `git diff --base`. +Finalmente, puede observar cómo el archivo ha cambiado desde ambos lados con `git diff --base`. [source,console] ---- @@ -263,7 +263,7 @@ index ac51efd..44d0a25 100755 hello() ---- -En este punto podemos usar el comando `git clean` para limpiar los archivos sobrantes que creamos para hacer el manual de la fusión, pero que ya no necesitamos. +En este punto podemos usar el comando `git clean` para limpiar los archivos sobrantes que creamos para hacer la fusión manual, pero que ya no necesitamos. [source,console] ---- @@ -278,7 +278,7 @@ Removing hello.theirs.rb Tal vez en este punto no estemos felices con la resolución por alguna razón, o quizás manualmente editando uno o ambos lados todavía no funciona como es debido y necesitamos más contexto. -Cambiemos el ejemplo un poco. Para este ejemplo, tenemos dos ramas de larga vida las cuales cada una tiene unos pocos cometidos en ellas aparte de crear un contenido de conflicto legítimo cuando es fusionado. +Cambiemos el ejemplo un poco. En este caso, tenemos dos ramas de larga vida las cuales cada una tiene unos pocos ``commit'' en ella, aparte de crear un contenido de conflicto legítimo cuando es fusionado. [source,console] ---- @@ -293,7 +293,7 @@ $ git log --graph --oneline --decorate --all * b7dcc89 initial hello world code ---- -Ahora tenemos tres cometidos únicos que viven solo en la rama `principal` y tres otras que viven en la rama `mundo`. Si intentamos fusionar la rama mundo, generamos un conflicto. +Ahora tenemos tres ``commit'' únicos que viven solo en la rama `principal` y otros tres que viven en la rama `mundo`. Si intentamos fusionar la rama `mundo`, generaremos un conflicto. [source,console] ---- @@ -320,13 +320,13 @@ end hello() ---- -Ambos lados de la fusión han añadido contenido a este archivo, pero algunos de los cometidos han modificado el archivo en el mismo lugar que causó el conflicto. +Ambos lados de la fusión han añadido contenido a este archivo, pero algunos de los ``commit'' han modificado el archivo en el mismo lugar que causó el conflicto. -Exploremos un par de herramientas que ahora tienes a tu disposición para determinar cómo el conflicto resultó ser. Tal vez no es tan obvio qué tan exactamente deberías solucionar este problema. Necesitas más contexto. +Exploremos un par de herramientas que ahora tiene a su disposición para determinar cómo el conflicto resultó ser. Tal vez, no es tan obvio cómo exactamente debería solucionar este problema. Necesita más contexto. -Una herramienta útil es `git checkout` con la opción ‘--conflicto’. Esto revisará el archivo de nuevo y reemplazará los marcadores de conflicto de la fusión. Esto puede ser útil si quieres reiniciar los marcadores y tratar de resolverlos de nuevo. +Una herramienta útil es `git checkout` con la opción ``--conflict''. Esto revisará el archivo de nuevo y reemplazará los marcadores de conflicto de la fusión. Esto puede ser útil si quiere reiniciar los marcadores y tratar de resolverlos de nuevo. -Puedes pasar `--conflict` en lugar de `diff3` o `merge` (lo que es por defecto). Si pasas `diff3`, Git usará una versión un poco diferente de marcadores de conflicto, no solo dándote ``ours'' versión y la versión de ``theirs'', sino también la versión ``base'' en línea para darte más contexto. +Puedes pasar `--conflict` en lugar de `diff3` o `merge` (lo que es por defecto). Si pasa `diff3`, Git usará una versión un poco diferente de marcadores de conflicto, no solo dándole ``ours'' versión y la versión de ``theirs'', sino también la versión ``base'' en línea para darle más contexto. [source,console] ---- @@ -352,23 +352,23 @@ end hello() ---- -Si este formato es de tu agrado, puedes configurarlo como defecto para futuros conflictos de fusión al colocar el `merge.conflictstyle` configurándolo a `diff3`. +Si este formato es de su agrado, puede configurarlo como ``default'' para futuros conflictos de fusión al colocar el `merge.conflictstyle` configurándolo a `diff3`. [source,console] ---- $ git config --global merge.conflictstyle diff3 ---- -El comando `git checkout` puede también tomar la opción de `--ellos`o la `--nuestra`, lo cual puede ser una manera mucho más rápida de escoger un lado o el otro sin tener que fusionar las cosas en lo absoluto. +El comando `git checkout` puede también tomar la opción de `--theirs`o la `--ours`, lo cual puede ser una manera mucho más rápida de escoger un lado o el otro sin tener que fusionar las cosas en lo absoluto. -Esto puede ser particularmente útil para conflictos de archivos binarios donde simplemente puedes escoger un lado, o donde solo quieres fusionar ciertos archivos desde otra rama – puedes hacer la fusión y luego revisar ciertos archivos de un lado o del otro antes de comprometerlos +Esto puede ser particularmente útil para conflictos de archivos binarios donde simplemente puede escoger un lado, o donde solo quiere fusionar ciertos archivos desde otra rama – puede hacer la fusión y luego revisar ciertos archivos de un lado o del otro antes de comprometerlos [[r_merge_log]] ===== Registro de Fusión -Otra herramienta útil al resolver conflictos de fusión es `git log`. Esto puede ayudarte a tener contexto a lo que pudo haber contribuido a los conflictos. Revisando un poco de historial para recordar por qué dos líneas de desarrollo estaban tocando el mismo código de área puede ser muy útil algunas veces. +Otra herramienta útil al resolver conflictos de fusión es `git log`. Esto puede ayudarle a tener contexto de lo que pudo haber contribuido a los conflictos. Revisar un poco el historial para recordar por qué dos líneas de desarrollo estaban tocando el mismo código de área, puede ser muy útil algunas veces. -Para obtener una lista completa de cometidos únicos que fueron incluidos en cualquiera de las ramas involucradas en esta fusión, podemos usar la sintaxis ``triple dot'' (triple punto) que aprendimos en <>. +Para obtener una lista completa de ``commit'' únicos que fueron incluidos en cualquiera de las ramas involucradas en esta fusión, podemos usar la sintaxis ``triple dot'' (triple punto) que aprendimos en <>. [source,console] ---- @@ -392,13 +392,13 @@ $ git log --oneline --left-right --merge > c3ffff1 changed text to hello mundo ---- -En su lugar, si corremos eso con la opción `-p` obtienes, solo los diffs del archivo que terminó en conflicto. Esto puede ser **bastante**útil al rápidamente darte el contexto que necesitas para ayudarte a entender por qué algo crea problemas y cómo resolverlo de una forma más inteligente. +En su lugar, si corremos eso con la opción `-p` obtendremos sólo los diffs del archivo que terminó en conflicto. Esto puede ser **bastante** útil, al darle rápidamente el contexto que necesita para ayudarle a entender por qué algo crea problemas y cómo resolverlo de una forma más inteligente. ===== Formato Diff Combinado -Dado que las etapas de Git clasifican los resultados que tienen éxito, cuando corres `git diff` mientras está en un estado de conflicto de fusión, solo puedes obtener lo que está actualmente en conflicto. Esto puede ser útil para ver lo que todavía debes resolver. +Dado que las etapas de Git clasifican los resultados que tienen éxito, cuando corre `git diff` mientras está en un estado de conflicto de fusión, sólo puede obtener lo que está actualmente en conflicto. Esto puede ser útil para ver lo que todavía debe resolver. -Cuando corres directamente `git diff` después de un conflicto de fusión, te dará la información en un formato de salida diff bastante único. +Cuando corre directamente `git diff` después de un conflicto de fusión, le dará la información en un formato de salida diff bastante único. [source,console] ---- @@ -421,9 +421,9 @@ index 0399cd5,59727f0..0000000 hello() ---- -El formato es llamado ``Diff combinado'' y proporciona dos columnas de datos al lado de cada línea. La primera columna muestra si esa línea es diferente (añadido o removido) entre la rama ``nuestra'' y el archivo en tu directorio de trabajo, y la segunda columna hace lo mismo entre la rama “de ellos” y la copia de tu directorio de trabajo. +El formato es llamado ``Diff combinado'' y proporciona dos columnas de datos al lado de cada línea. La primera columna muestra si esa línea es diferente (añadida o removida) entre la rama ``ours'' y el archivo en su directorio de trabajo, y la segunda columna hace lo mismo entre la rama ``theirs'' y la copia de su directorio de trabajo. -Así que en ese ejemplo se puede observar que las líneas <<<<<<< y >>>>>>> están en la copia de trabajo, pero no en ningún lado de la fusión. Esto tiene sentido porque la herramienta de fusión las mantiene ahí para nuestro contexto, pero se espera removamos. +Así que en ese ejemplo se puede observar que las líneas <<<<<<< y >>>>>>> están en la copia de trabajo, pero no en ningún lado de la fusión. Esto tiene sentido porque la herramienta de fusión las mantiene ahí para nuestro contexto, pero se espera que las removamos. Si resolvemos el conflicto y corremos `git diff` de nuevo, veremos la misma cosa, pero es un poco más útil. @@ -449,7 +449,7 @@ index 0399cd5,59727f0..0000000 Esto muestra que ``hola mundo'' estaba de nuestro lado, pero no en la copia de trabajo, que ``hello mundo'' estaba en el lado de ellos, pero no en la copia de trabajo y finalmente que ``hola mundo'' no estaba en ningún lado, sin embargo está ahora en la copia de trabajo. Esto puede ser útil para revisar antes de comprometer la resolución. -También se puede obtener desde el `git log` para cualquier fusión después del hecho, para ver cómo algo se resolvió luego de este. Git dará salida a este formato si se puede correr `git show` en un compromiso de fusión, o si se añade la opción `--cc` a un `git log -p` (el cual por defecto solo muestras parches para compromisos no fusionados). +También se puede obtener desde el `git log` para cualquier fusión después de realizada, para ver cómo algo se resolvió luego de dicha fusión. Git dará salida a este formato si se puede correr `git show` en un compromiso de fusión, o si se añade la opción `--cc` a un `git log -p` (el cual por defecto solo muestras parches para compromisos no fusionados). [source,console] ---- @@ -483,26 +483,26 @@ index 0399cd5,59727f0..e1d0799 [[r_undoing_merges]] ==== Deshaciendo Fusiones -Ahora que ya conoces como crear un merge commit (compromiso de fusión), probablemente hayas creado algunos por error. -Una de las ventajas de trabajar con Git es que está bien cometer errores, porque es posible (y en muchos casos es fácil) solucionarlos. +Ahora que ya conoce como crear un ``merge commit'' (compromiso de fusión), probablemente haya creado algunos por error. +Una de las ventajas de trabajar con Git es que está bien cometer errores, porque es posible y, en muchos casos, es fácil solucionarlos. Los compromisos de fusión no son diferentes. -Digamos que comenzaste a trabajar en una rama temática accidentalmente fusionada en una rama `master`, y ahora el historial de compromiso se ve así: +Digamos que comenzó a trabajar en una rama temática accidentalmente fusionada en una rama `master`, y ahora el historial de compromiso se ve así: .Accidental merge commit image::images/undomerge-start.png[Accidental merge commit.] -Existen dos formas de abordar este problema, dependiendo de cuál es el resultado que deseas. +Existen dos formas de abordar este problema, dependiendo de cuál es el resultado que desea. ===== Solucionar las referencias -Si el compromiso de fusión no deseado solo existe en tu repositorio local, la mejor y más fácil solución es mover las ramas para que así apunten a dónde quieres que lo hagan. -En la mayoría de los casos si sigues al errante `git merge` con `git reset --hard HEAD~`, esto restablecerá los punteros de la rama, así que se verá así: +Si el compromiso de fusión no deseado solo existe en su repositorio local, la mejor y más fácil solución es mover las ramas para que así apunten a dónde quiere que lo hagan. +En la mayoría de los casos si sigue al errante `git merge` con `git reset --hard HEAD~`, esto restablecerá los punteros de la rama, haciendo que se vea así: .History after `git reset --hard HEAD~` image::images/undomerge-reset.png[History after `git reset --hard HEAD~`.] -Ya vimos `restablecer` de nuevo en <>, así que no debería ser muy difícil averiguar lo que está sucediendo ahí +Ya vimos `reset` de nuevo en <>, así que no debería ser muy difícil averiguar lo que está sucediendo. Aquí un repaso rápido: `reset --hard` usualmente va a través de tres pasos: . Mover los puntos de la rama HEAD. @@ -510,15 +510,15 @@ Aquí un repaso rápido: `reset --hard` usualmente va a través de tres pasos: . Hacer que el índice parezca HEAD. . Hacer que el directorio de trabajo parezca el índice. -La desventaja de este enfoque es que es reescribir el historial, lo cual puede ser problemático con un depósito compartido. -Revisa <> para más de lo que puede suceder; la versión corta es que si otras personas tienen los compromisos que estas reescribiendo, probablemente deberías evitar `resetear`. -Este enfoque tampoco funcionará si cual quiera de los otros compromisos han sido creados desde la fusión; mover los refs efectivamente perdería esos cambios. +La desventaja de este enfoque es que se reescribirá el historial, lo cual puede ser problemático con un depósito compartido. +Revise <> para saber más de lo que puede suceder; la versión corta es que, si otras personas tienen los compromisos que está reescribiendo, probablemente debería evitar `resetear`. +Este enfoque tampoco funcionará si cualquiera de los otros compromisos han sido creados desde la fusión; mover los refs efectivamente perdería esos cambios. [[r_reverse_commit]] ===== Revertir el compromiso -Si mover los punteros de la rama alrededor no funciona para ti, Git te proporciona la opción de hacer un compromiso (commit) nuevo que deshace todos los cambios de uno ya existente. -Git llama a esta operación un ``revertir', y en este escenario en particular, has invocado algo así: +Si mover los punteros de la rama alrededor no funciona para su caso, Git le proporciona la opción de hacer un compromiso (``commit'') nuevo que deshace todos los cambios de uno ya existente. +Git llama a esta operación un ``revert'', y en este escenario en particular, ha invocado algo así: [source,console] ---- @@ -526,17 +526,17 @@ $ git revert -m 1 HEAD [master b1d8379] Revert "Merge branch 'topic'" ---- -La bandera `-m 1` indica cuál padre es el ``mainline'' y debería ser mantenido. +La bandera `-m 1` indica cuál padre es el ``mainline'' y debería ser mantenido. Cuando se invoque la fusión en el `HEAD` (`git merge topic`), el nuevo compromiso tiene dos padres: el primero es `HEAD` (`C6`), y el segundo es la punta de la rama siendo fusionada en (`C4`). -En este caso, se quiere deshacer todos los cambios introducidos por el fusionamiento en el padre #2 (`C4`), mientras manteniendo todo el contenido del padre #1 (`C6`). +En este caso, se quiere deshacer todos los cambios introducidos por el fusionamiento en el padre #2 (`C4`), pero manteniendo todo el contenido del padre #1 (`C6`). El historial con el compromiso revertido se ve así: .History after `git revert -m 1` image::images/undomerge-revert.png[History after `git revert -m 1`.] -El nuevo compromiso `^M` tiene exactamente los mismos contenidos que `C6`, así que comenzando desde aquí es como si la fusión nunca hubiese sucedido, excepto que la ahora los no fusionados compromisos están todavía en `HEAD`'s history. -Git se confundirá si intentas fusionar la rama `temática` en la rama `master`: +El nuevo compromiso `^M` tiene exactamente los mismos contenidos que `C6`, así que comenzando desde aquí es como si la fusión nunca hubiese sucedido, excepto que ahora los no fusionados compromisos están todavía en `HEAD`'s history. +Git se confundirá si intenta fusionar la rama `temática` en la rama `master`: [source,console] ---- @@ -545,7 +545,7 @@ Already up-to-date. ---- No hay nada en `topic` que no sea ya alcanzable para la `master`. -Que es peor, si añades trabajo a `topic` y fusionas otra vez, Git solo traerá los cambios desde la fusión revertida: +Que es peor, si añade trabajo a `topic` y fusiona otra vez, Git solo traerá los cambios desde la fusión revertida: .History with a bad merge image::images/undomerge-revert2.png[History with a bad merge.] @@ -567,15 +567,15 @@ Efectivamente `^^M` se fusiona en los cambios desde `C3` y `C4`, y `C8` se fusio ==== Otros Tipos de Fusiones -Hasta hora ya cubrimos la fusión normal de dos ramas, normalmente manejado con lo que es llamado la estrategia de fusión ``recursive''. Sin embargo, hay otras formas de fusionar a las ramas. Cubriremos algunos de ellos rápidamente. +Hasta hora ya cubrimos la fusión normal de dos ramas, normalmente manejado con lo que es llamado la estrategia de fusión ``recursive''. Sin embargo, hay otras formas de fusionar a las ramas. Cubriremos algunas de ellas rápidamente. ===== Nuestra o Su preferencia -Primero que nada, hay otra cosa útil que podemos hacer con el modo de fusión ``recursive''. Ya se vio que las opciones `ignore-all-space` y `ignore-space-change` las cuales son pasadas con un `-X` pero también le podemos decir a Git que favorezca un lado u otro cuando observe un conflicto. +Primero que nada, hay otra cosa útil que podemos hacer con el modo de fusión ``recursive''. Ya vimos las opciones `ignore-all-space` e `ignore-space-change` las cuales son pasadas con un `-X`, pero también le podemos decir a Git que favorezca un lado u otro cuando observe un conflicto. -Por defecto, cuando Git ve un conflicto entre dos ramas siendo fusionadas, añadirá marcadores de conflictos de fusión a los códigos y marca el archivo como conflictivo y te dejará resolverlo. Si prefieres que Git simplemente escoja un lado especifico e ignore el otro, en lugar de dejarte manualmente fusionar el conflicto, puedes pasar el comando de fusión ya sea un `-Xours` o `-Xtheirs`. +Por defecto, cuando Git ve un conflicto entre dos ramas siendo fusionadas, añadirá marcadores de conflicto de fusión a los códigos, marcará el archivo como conflictivo y le dejará resolverlo. Si prefiere que Git simplemente escoja un lado específico e ignore el otro, en lugar de dejarle manualmente fusionar el conflicto, puede pasar el comando de fusión, ya sea on un `-Xours` o `-Xtheirs`. -Si Git ve esto, no añadirá marcadores de conflictos. Cualquier diferencia que pueda ser fusionable, se fusionará. Cualquier diferencia que entre en conflicto, él simplemente escogerá el lado que especifiques en su totalidad, incluyendo los archivos binarios. +Si Git ve esto, no añadirá marcadores de conflicto. Cualquier diferencia que pueda ser fusionable, se fusionará. Cualquier diferencia que entre en conflicto, él simplemente escogerá el lado que especifique en su totalidad, incluyendo los archivos binarios. Si volvemos al ejemplo de ``hello world'' que estábamos utilizando antes, podemos ver que el fusionamiento en nuestra rama causa conflicto. @@ -605,9 +605,9 @@ En este caso, en lugar de obtener marcadores de conflicto en el archivo con ``he Esta opción también puede ser trasmitida al comando `git merge-file` que vimos antes al correr algo como esto `git merge-file --ours` para archivos de fusión individuales. -Si quieres realizar algo así, pero Git no ha intentado siquiera fusionar cambios desde el otro lado, hay una opción más draconiana, la cual es la estrategia de fusión ``ours'' merge _strategy. Esto es diferente de la opción de fusión recursiva ``ours'' recursive merge _option_. +Si quiere realizar algo así, pero Git no ha intentado siquiera fusionar cambios desde el otro lado, hay una opción más draconiana, la cual es la estrategia de fusión ``ours'' merge _strategy. Esto es diferente de la opción de fusión recursiva ``ours'' recursive merge _option_. -Esto básicamente hace una fusión falsa. Registrará un nuevo compromiso de fusión con ambas ramas como padres, pero ni siquiera mirará a la rama que estas fusionando. Simplemente registrará como el resultado de la fusión el código exacto en tu rama actual. +Esto básicamente hace una fusión falsa. Registrará un nuevo compromiso de fusión con ambas ramas como padres, pero ni siquiera mirará a la rama que está fusionando. Simplemente registrará como el resultado de la fusión el código exacto en su rama actual. [source,console] ---- @@ -617,10 +617,10 @@ $ git diff HEAD HEAD~ $ ---- -Puedes observar que no hay diferencia entre la rama en la que estábamos y el resultado de la fusión. +Puede observar que no hay diferencia entre la rama en la que estábamos y el resultado de la fusión. -Esto a menudo puede ser útil para básicamente engañar a Git para que piense que una rama ya ha sido fusionada cuando se hace una fusión más adelante. Por ejemplo, decir que has ramificado una rama de ``release'' y has hecho un poco de trabajo que querrás fusionar de vuelta en tu rama ``master'' en algún punto. -Mientras tanto, algunos arreglos de fallos en la ``master'' necesitan ser adaptados en la rama de `release`. Se puede fusionar la rama “bugfix” en la de `release` y también `merge -s ours`, la misma rama en la principal (a pesar de que el arreglo ya se encuentre ahí) Así que, más tarde cuando fusiones la de lanzamiento otra vez, no hay conflictos del bugfix. +Esto a menudo puede ser útil para, básicamente, engañar a Git y que piense que una rama ya ha sido fusionada cuando se hace una fusión más adelante. Por ejemplo, decir que ha ramificado una rama de ``release'' y ha hecho un poco de trabajo que querrá fusionar de vuelta en su rama ``master'' en algún punto. +Mientras tanto, algunos arreglos de fallos en la ``master'' necesitan ser adaptados en la rama de `release`. Se puede fusionar la rama ``bugfix'' en la de `release` y también `merge -s ours`, la misma rama en la principal (a pesar de que el arreglo ya se encuentre ahí). Así que, más tarde cuando fusione la de lanzamiento otra vez, no hay conflictos del ``bugfix''. include::subtree-merges.asc[] diff --git a/book/07-git-tools/sections/bundling.asc b/book/07-git-tools/sections/bundling.asc index 662c141d..78c4b367 100644 --- a/book/07-git-tools/sections/bundling.asc +++ b/book/07-git-tools/sections/bundling.asc @@ -1,11 +1,11 @@ [[r_bundling]] === Agrupaciones -Aunque ya hemos considerado las maneras mas comunes de transferir la base de datos del Git en el internet (HTTP, SSH, etc.), existe aún una manera de hacerlo, aunque no es muy comúnmente usada puede ser muy útil. +Aunque ya hemos considerado las maneras más comunes de transferir la base de datos de Git en el Internet (HTTP, SSH, etc.), existe aún otra manera de hacerlo, que aunque no es muy comúnmente usada puede ser muy útil. -El Git es capaz de ``agrupar'' la base de datos en un único archivo. Esto puede ser muy útil en varios escenarios. Tal vez tu red está caída y quieres enviar cambios a tu co-trabajdores. Quizas estás trabajando en algún lugar sin conexión y no tienes acceso a la red local por motivos de seguridad. Tal vez su tarjeta inalámbrica / ethernet se rompió. Tal vez no tienes acceso al servidor compartido por el momento, y quieres enviar un correo con actualizaciones y no quieres transferir 40 confirmaciones via `format-patch`. +Git es capaz de ``agrupar'' la base de datos en un único archivo. Esto puede ser muy útil en varios escenarios. Tal vez tu red está caída y quieres enviar cambios a tus co-trabajdores. Quizas estás trabajando en algún lugar sin conexión y no tienes acceso a la red local por motivos de seguridad. Tal vez tu tarjeta inalámbrica / ethernet se rompió. Tal vez no tienes acceso al servidor compartido por el momento, y quieres enviar un correo con actualizaciones y no quieres transferir 40 confirmaciones via `format-patch`. -Aquí es donde el comando de `git bundle` es muy útil. El comando `bundle` juntará todo lo que normalmente se empujaría sobre el cable con un comando de` push git ‘en un archivo binario que puedes enviar por correo a alguien o poner un flash drive, luego desglosarlo en otro repositorio. +Aquí es donde el comando de `git bundle` es muy útil. El comando `bundle` juntará todo, lo que normalmente se empujaría sobre el cable con un comando `git push`, en un archivo binario que puedes enviar por correo a alguien o poner en un flash drive, y luego desglosarlo en otro repositorio. Veamos un ejemplo simple. Digamos que tienes un repositorio con dos confirmaciones: @@ -22,7 +22,7 @@ commit b1ec3248f39900d2a406049d762aa68e9641be25 Author: Scott Chacon Date: Wed Mar 10 07:34:01 2010 -0800 - Primera confirmaciión + Primera confirmación ---- Si quieres enviar ese repositorio a alguien y no tienes acceso a algún repositorio para hacerlo, o simplemente no quieres configurar uno, puedes juntarlo con el `git bundle create `. @@ -37,11 +37,11 @@ Writing objects: 100% (6/6), 441 bytes, done. Total 6 (delta 0), reused 0 (delta 0) ---- -Ahora tienes un archive nombrado `repo.bundle` este tiene todos los datos nuevos necesarios para re-crear el repositorio de la rama `maester`. Con el comando de `bundle` necesitaras enlistar cualquier referencia o rango especifico de confirmaciones que quieres que sean incluidas. Si tiene la intención de clonar esto en otro lugar, debe agregar HEAD como referencia, así como lo hemos hecho aquí. +Ahora tienes un archivo nombrado `repo.bundle`, éste tiene todos los datos nuevos necesarios para re-crear el repositorio de la rama `maester`. Con el comando `bundle` necesitarás enlistar cualquier referencia o rango específico de confirmaciones que quieras que sean incluidas. Si tienes la intención de clonar esto en otro lugar, debes agregar HEAD como referencia, así como lo hemos hecho aquí. Puedes enviar por correo este archivo `repo.bundle` a alguien más, o ponerlo en una memoria USB y simplemente irte. -Por otro lado, supongamos que se envía este archivo de `repo.bundle` y deseas trabajar en el proyecto. Puedes clonarlo desde el archivo binario en un directorio, como lo harías desde una URL. +Por otro lado, supongamos que se envía este archivo de `repo.bundle` y deseas trabajar en el proyecto. Puedes clonarlo desde el archivo binario en un directorio, como lo harías desde una URL. [source,console] ---- @@ -53,9 +53,9 @@ $ git log --oneline b1ec324 first commit ---- -Si no quieres incluir HEAD en las referencias, tambien tendrás que especificar `-b master` o cualquier rama que sea incluída porque de otra manera no sabrá que rama revisar. +Si no quieres incluir HEAD en las referencias, también tendrás que especificar `-b master` o cualquier rama que sea incluída porque de otra manera Git no sabrá que rama revisar. -Digamos que ahora haces tres confirmaciones en ello y quieres enviar nuevas confirmaciones via agrupacion en una USB o por correo. +Digamos que ahora haces tres confirmaciones y quieres enviar nuevas confirmaciones vía agrupación en una USB o por correo. [source,console] ---- @@ -67,9 +67,9 @@ c99cf5b fourth commit - second repo b1ec324 first commit ---- -Primero necesitamos determinar el rango de confirmaciones que queremos incluir en la agrupación. No como los protocolos de la red que figuraran en el mínimo de datos para transferir desde la red por nosotros, tendremos que hacer esto manualmente. Ahora simplemente puedes hacer la misma cosa y agrupar el repositorio entero, el que trabajará, pero es mejor solo agrupar las diferencias – solamente las tres confirmaciones que hicimos localmente. +Primero necesitamos determinar el rango de confirmaciones que queremos incluir en la agrupación. No es como en los protocolos de la red donde figurará el mínimo de datos para transferir desde la red por nosotros, tendremos que hacer esto manualmente. Ahora simplemente puedes hacer la misma cosa y agrupar el repositorio entero, el que trabajará, pero es mejor sólo agrupar las diferencias – solamente las tres confirmaciones que hicimos localmente. -Para hacer eso, tienes que calcular la diferencia. Como hemos descrito en <>, Puedes especificar el rango de confirmaciones en un numero de caminos. Para obtener las tres confirmaciones que tenemos en nuestra rama maestra que no estaban en la rama que copiamos originalmente, podemos usar algo como `origin/master..master` o `master ^origin/master`. Puedes probar esto con el comando de `log`. +Para hacer eso, tienes que calcular la diferencia. Como hemos descrito en <>, Puedes especificar el rango de confirmaciones en un numero de caminos. Para obtener las tres confirmaciones que tenemos en nuestra rama maestra que no estaban en la rama que copiamos originalmente, podemos usar algo como `origin/master..master` o `master ^origin/master`. Puedes probar esto con el comando `log`. [source,console] ---- @@ -79,7 +79,7 @@ c99cf5b fourth commit - second repo 7011d3d third commit - second repo ---- -Entonces ahora que tenemos la lista de confirmaciones queremos incluirlas en la agrupación, agrupémoslas todas. hacemos eso con el comando de `git bundle create`, dandole un nombre al archivo que queremos que sea parte de la agrupación y el rango de confirmaciones que queremos incluir en el mismo. +Entonces ahora que tenemos la lista de confirmaciones, queremos incluirlas en la agrupación, agrupémoslas todas. Hacemos eso con el comando `git bundle create`, dándole un nombre al archivo que queremos que sea parte de la agrupación y el rango de confirmaciones que queremos incluir en el mismo. [source,console] ---- @@ -91,9 +91,9 @@ Writing objects: 100% (9/9), 775 bytes, done. Total 9 (delta 0), reused 0 (delta 0) ---- -Ahora tenemos un archivo de `commits.bundle` en nuestro directorio. Si tomamos este y se lo enviamos a nuestro compañero, ella pueda importarlo en el repositorio original, incluso si se ha incluido más trabajo en el tiempo que ha pasado. +Ahora tenemos un archivo de `commits.bundle` en nuestro directorio. Si tomamos éste y se lo enviamos a nuestro compañero, puede importarlo en el repositorio original, aún si se ha incluido más trabajo en el tiempo que ha pasado. -Cuando obtenga la agrupación, puede inspeccionarlo para ver que contiene antes de que lo importe en el repositorio. El primer comando es el `bundle verify` que hará saber si el archivo es actualmente una agrupacion válida del Git y asi tendras todos los requerimientos necesarios para reconstituiirlo apropiadamente. +Cuando obtenga la agrupación, puede inspeccionarlo para ver qué contiene antes de que lo importe en el repositorio. El primer comando es el `bundle verify` que te hará saber si el archivo es actualmente una agrupación válida de Git y así tendrás todos los requerimientos necesarios para reconstituirlo apropiadamente. [source,console] ---- @@ -105,7 +105,7 @@ The bundle requires these 1 ref ../commits.bundle is okay ---- -Si el agrupador a creado una agrupación de solo las dos últimas confirmaciones que se han hecho, en lugar de las tres, tel repositorio original no será capaz de improtarlo, dado que falta un requisito en la historia. El comando de `verify` debería de verse entonces así: +Si el agrupador ha creado una agrupación de sólo las dos últimas confirmaciones que se han hecho, en lugar de las tres, el repositorio original no será capaz de improtarlo, dado que falta un requisito en la historia. El comando de `verify` debería de verse entonces así: [source,console] ---- @@ -114,7 +114,7 @@ error: Repository lacks these prerequisite commits: error: 7011d3d8fc200abe0ad561c011c3852a4b7bbe95 third commit - second repo ---- -Como sea, nuestra primera agrupación es válida, Entonces podemos obtener confirmaciones de ella. si quieres ver que ramas están en la agrupación que pueden ser importadas, de igual manera hay un comando para verlo: +Como sea, nuestra primera agrupación es válida, entonces podemos obtener confirmaciones de ella. Si quieres ver qué ramas que están en la agrupación pueden ser importadas, hay un comando para verlo: [source,console] ---- @@ -122,7 +122,7 @@ $ git bundle list-heads ../commits.bundle 71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master ---- -el sub-comando de `verify` te dira el encabezado tambien. el punto es ver que puede ser puesto, para que puedas usar el comando de fetch `fetch` o `pull` para importar confirmaciones de este archivo. Aquí vamos a buscar la rama 'master' de la agrupación por una llamada 'other-master' en nuestro repositorio: +El sub-comando de `verify` te dirá el encabezado también. El punto es ver qué puede ser puesto, para que puedas usar el comando de fetch `fetch` o `pull` para importar confirmaciones de este archivo. Aquí vamos a buscar la rama 'master' de la agrupación con una llamada 'other-master' en nuestro repositorio: [source,console] ---- @@ -131,7 +131,7 @@ From ../commits.bundle * [new branch] master -> other-master ---- -Ahora podemos ver que hemos importado las confirmaciones a la rama de 'other-master'asi mismo como tantas confirmaciones hayamos hecho mientras tanto en nuestra rama 'master' . +Ahora podemos ver que hemos importado las confirmaciones a la rama de 'other-master', así como tantas confirmaciones hayamos hecho mientras tanto en nuestra rama 'master'. [source,console] ---- @@ -145,4 +145,4 @@ $ git log --oneline --decorate --graph --all * b1ec324 first commit ---- -Entonces, `git bundle` puede ser muy util para compartir o hacer operaciones tipo red cuando no tienes la red adecuada o repositorio compartido para hacerlo. +Entonces, `git bundle` puede ser muy útil para compartir o hacer operaciones tipo red cuando no tienes la red adecuada o repositorio compartido para hacerlo. diff --git a/book/07-git-tools/sections/credentials.asc b/book/07-git-tools/sections/credentials.asc index 3934a25f..9fc6d638 100644 --- a/book/07-git-tools/sections/credentials.asc +++ b/book/07-git-tools/sections/credentials.asc @@ -3,26 +3,25 @@ (((credentials))) (((git commands, credential))) -Si usa protocolo SSH para conectar a los remotos, es posible tener una llave sin clave, lo que permite -tranferir la data sin tener que escribir el nombre de usuario y la clave cada vez. +Si usa protocolo SSH para conectar a los remotos, es posible tener una llave sin clave, lo que permite tranferir la `data` sin tener que escribir el nombre de usuario y la clave cada vez. Sin embargo, esto no es posible por el protocolo HTTP - cada conexión necesita usuario y contraseña. -Esto se vuelve incluso más complicado para sistemas con autenticación de dos pasos, donde el token que -se usa para la clave es generado al azar y no puede ser utilizado. +Incluso se vuelve más complicado para sistemas con autenticación de dos pasos, donde el token que +se usa para la clave es generado al azar y no puede ser reutilizado. Afortunadamente, Git tiene un sistema de credenciales que lo ayuda con esto. Git tiene las siguientes funciones disponibles: -* El default es no guardar cache para nada. +* El ``default'' es no guardar cache para nada. Cada conexión solicitará el usuario y contraseña. -* El modo ``cache'' mantiene las credenciales en memoria por un cierto periodo de tiempo. +* El modo ``cache'' mantiene las credenciales en memoria por un cierto período de tiempo. Ninguna de las claves es guardada en disco, y son borradas del cache tras 15 minutos. * El modo ``store'' guarda las credenciales en un archivo de texto plano en disco, y nunca expiran. - Esto quiere decir que hasta que se cambie la contraseña en el host Git, no se necesitarán escribir credenciales de nuevo. + Esto quiere decir que hasta que se cambie la contraseña en el host Git, no se necesitará escribir las credenciales de nuevo. La desventaja de este método es que sus claves son guardadas en texto plano en un archivo dentro de su máquina. * Si está usando Mac, Git viene con el modo ``osxkeychain'', el cual guarda en cache las credenciales en el llavero que está conectado a su cuenta de sistema. Este método guarda las claves en disco, y nunca expiran, pero están encriptadas con el mismo sistema que guarda los certificados HTTPS y los auto-completar de Safari. -* Si está en Windows, puede installer un ayudante llamado ``winstore.'' - Este es similar al ayudante de ``osxkeychain'' descrito arriba, pero usa Windows Credential Store para controlar la información sensible. +* Si está en Windows, puede instalar un ayudante llamado ``winstore.'' + Éste es similar al ayudante de ``osxkeychain'' descrito arriba, pero usa Windows Credential Store para controlar la información sensible. Se puede encontrar en https://gitcredentialstore.codeplex.com[]. Se puede elegir cualquiera de estos métodos mediante el valor de configuración de Git: @@ -35,7 +34,7 @@ $ git config --global credential.helper cache Algunos de estos ayudantes tienen opciones. El modo ``store'' puede tomar un argumento `--file ', el cual personaliza la ubicación final del archivo en texto plano (el default es `~/.git-credentials`). -El modo ``cache'' acepta la opción `--timeout `, la cual cambia la cantidad de tiempo que el demonio se mantiene en ejecución (el default es ``900'', o 15 minutos). +El modo ``cache'' acepta la opción `--timeout `, la cual cambia la cantidad de tiempo que el ``demonio'' se mantiene en ejecución (el default es ``900'', o 15 minutos). Aquí hay un ejemplo de cómo configurar el modo ``store'' con un nombre de archivo personalizado: [source,console] @@ -58,10 +57,10 @@ Aquí se muestra cómo se vería un archivo `.gitconfig` si tuviera un archivo d ==== Bajo el sombrero ¿Cómo funciona todo esto? -El comando raíz de Git para el asistente de credenciales es `git credential`, el cual toma un comando como argumento, y luego más inputs por medio de stdin. +El comando raíz de Git para el asistente de credenciales es `git credential`, el cual toma un comando como argumento, y luego más inputs por medio de ``stdin''. Esto podría ser más fácil de entender con un ejemplo. -Supongamos que un modo de credenciales ha sido configurado, y que el asistente a guardado credenciales para `mygithost`. +Supongamos que un modo de credenciales ha sido configurado, y que el asistente ha guardado credenciales para `mygithost`. Aquí hay una sesión que usa el comando ``fill'', el cual es invocado cuando Git está intentando encontrar credenciales para el host: [source,console] @@ -86,12 +85,12 @@ username=bob password=s3cre7 ---- -<1> Esta es el comando que inicia la interacción. -<2> Git-credential entonces espera por un input en stdin. +<1> Este es el comando que inicia la interacción. +<2> Git-credential entonces espera por un input en ``stdin''. Nosotros lo proveemos con lo que conocemos: el protocolo y el nombre de host. -<3> Una línea en blanco indica que el input está completo, y el sistema de credencial debería responder con lo que conoce. -<4> Git-credential entonces entra en acción, y escribe en stdout los bits de información que encontró. -<5> Si no se encuentran credenciales, Git pregunta al usuario por el usuario y la contraseña, y lo entrega de vuelta a stdout (aquí ya están conectados a la misma consola). +<3> Una línea en blanco indica que el input está completo, y el sistema de credenciales debería responder con lo que conoce. +<4> Git-credential entonces entra en acción, y escribe en ``stdout'' los bits de información que encontró. +<5> Si no se encuentran credenciales, Git pregunta al usuario por el usuario y la contraseña, y los entrega de vuelta a ``stdout'' (aquí ya están conectados a la misma consola). El sistema de credenciales en realidad está invocando un programa que está separado de Git; el que figura en el valor de configuración `credential.helper`. Hay varias formas que puede tomar: @@ -105,9 +104,9 @@ Hay varias formas que puede tomar: | `!f() { echo "password=s3cre7"; }; f` | Code after `!` evaluated in shell |====== -Así, los modos descritos arriba en realidad se llaman `git-credential-cache`, `git-credential-store`, y en adelante, y los podemos configurar para que tomen argumentos de línea de comando. +Así, los modos descritos arriba en realidad se llaman `git-credential-cache`, `git-credential-store`, y en adelante, los podemos configurar para que tomen argumentos de línea de comando. La forma general para conseguirlo es ``git-credential-foo [args] .'' -El protocolo stdin/stdout es el mismo que git-credential, pero usan un conjunto ligeramente distinto de acciones: +El protocolo ``stdin/stdout'' es el mismo que ``git-credential'', pero usan un conjunto ligeramente distinto de acciones: * `get` es una petición para un par usuario/contraseña. * `store` es una petición para guardar un grupo de credenciales en la memoria del modo. @@ -116,7 +115,7 @@ El protocolo stdin/stdout es el mismo que git-credential, pero usan un conjunto Para las acciones `store` y `erase`, no es necesaria una respuesta (Git la ignora de todos modos). Para la acción `get`, sin embargo, Git está muy interesado en lo que el modo tiene que decir. Si el modo no sabe nada útil, puede simplemente salir sin mostrar inforamción, pero si sabe algo, debería aumentar la información provista con la información que ha almacenado. -El output es tratado como una serie de declaraciones de assignación; nada provista remplazará lo que Git ya conoce. +El output es tratado como una serie de declaraciones de asignación; nada provisto remplazará lo que Git ya conoce. Aquí hay un ejemplo de lo explicado, pero saltando git-credential y yendo directo a git-credential-store: @@ -135,9 +134,9 @@ username=bob <3> password=s3cre7 ---- -<1> Aquí decimos con `git-credential-store` que guarde las credenciales: username ``bob'' y la clave ``s3cre7'' serán usadas cuando se accese a `https://mygithost`. +<1> Aquí decimos con `git-credential-store` que guarde las credenciales: username ``bob'' y la clave ``s3cre7'', que serán usadas cuando se accese a `https://mygithost`. <2> Ahora vamos a recibir las credenciales. - Ahora proveemos las partes de la conexión que ya conocemos (`https://mygithost`), y una línea en blanco. + Proveemos las partes de la conexión que ya conocemos (`https://mygithost`), y una línea en blanco. <3> `git-credential-store` responde con el usuario y la contraseña que guardamos al comienzo. Aquí se muestra cómo se vería `~/git.store`: @@ -155,13 +154,13 @@ Los modos `osxkeychain` y `winsoter` usan el formato nativo de sus almacenamient Dado que `git-credential-store` y amigos son programas separados de Git, no es difícil de notar que _cualquier_ programa puede ser un asistente de credenciales de Git. Los modos provistos por Git cubren muchos de los casos de uso, pero no todos. Por ejemplo, supongamos que tu equipo tiene credenciales que son compartidas con el equipo entero, tal vez para despliegue. -Estas están guardadas en un directorio compartido, pero no deseas copiarlas a tu almacén de credenciales, porque cambian de manera seguida. +Éstas están guardadas en un directorio compartido, pero no deseas copiarlas a tu almacén de credenciales, porque cambian de manera seguida. Ninguno de los modos existentes cubre este caso; veamos lo que tomaría para escribir tu propio modo. Existen muchas funcionalidades clave que necesita tener este programa: -. La única acción que necesitamos vigilar es `get`; `store` y `erase` son operaciones de escritura, así que solo saldremos limpiamente cuando sean recibidas. +. La única acción que necesitamos vigilar es `get`, en tanto que `store` y `erase` son operaciones de escritura, así que sólo saldremos limpiamente cuando sean recibidas. . El formato de archivo de la credencial compartida es el mismo que se usa por `git-credential-store`. -. La ubicación de ese archivo es relativamente estándar, pero deberías permitir al usuario entregar una ruta alterna por si acaso. +. La ubicación de ese archivo es relativamente estándar, pero deberías permitir al usuario entregar una ruta alterna, por si acaso. Una vez más, vamos a escribir esta extensión en Ruby, pero cualquier lenguaje funcionará siempre y cuando Git pueda ejecutar el producto final. Aquí está el código de nuestro nuevo asistente de credenciales: @@ -172,14 +171,14 @@ include::../git-credential-read-only[] -------- <1> Aquí analizamos las opciones de la línea de comando, permitiendo al usuario especificar un archivo. El default es `~/.git-credentials`. -<2> Este programa solo responde si la acción es `get` y el archivo de almacenamiento existe. -<3> Este bucle lee de stdin hasta que se encuentre la primer línea en blanco. - Los input son guardadoes en el hash `known` para una posterior referencia. +<2> Este programa sólo responde si la acción es `get` y el archivo de almacenamiento existe. +<3> Este bucle lee de ``stdin'' hasta que se encuentre la primer línea en blanco. + Los inputs son guardados en el hash `known` para una posterior referencia. <4> Este bucle lee el contenido del archivo de almacenamiento, buscando por concordancias. - Si el protocolo y el host de `known` concuerdan con la línea, el programa imprime el resultado a stdout y sale. + Si el protocolo y el host de `known` concuerdan con la línea, el programa imprime el resultado a ``stdout'' y sale. Guardaremos nuestro modo como `git-credential-read-only`, ponlo en algún lugar en nuestro `PATH` y lo marcamos como ejecutable. -Aquí se muestra cómo se vería una sessión interactiva: +Aquí se muestra cómo se vería una sesión interactiva: [source,console] ---- @@ -200,4 +199,4 @@ Dado que su nombre comienza con ``git-'', podemos usar la sintaxis simple para e $ git config --global credential.helper read-only --file /mnt/shared/creds ---- -Como se puede apreciar, extender este sistema es bastante sencillo, y puede resolver algunos problemas comunes para usted y su equipo. +Como se puede apreciar, extender este sistema es bastante sencillo, y puede resolver algunos problemas comunes para ti y tu equipo. diff --git a/book/07-git-tools/sections/debugging.asc b/book/07-git-tools/sections/debugging.asc index e9a24c31..45607ea2 100644 --- a/book/07-git-tools/sections/debugging.asc +++ b/book/07-git-tools/sections/debugging.asc @@ -1,7 +1,7 @@ === Haciendo debug con Git Git también provee unas cuantas herramientas para realizar un debug a los problemas en tus proyectos. -Porque Git está diseñado para trabajar con casi cualquier tipo de proyecto, estas herramientas son bastante genéricas, pero pueden ayudar a cazar bugs o al culpable cuando las cosas salen mal. +Porque Git está diseñado para trabajar con casi cualquier tipo de proyecto, estas herramientas son bastante genéricas, pero pueden ayudar a cazar bugs o al culpable cuando las cosas salen mal. [[r_file_annotation]] ==== Anotaciones de archivo @@ -27,19 +27,19 @@ $ git blame -L 12,22 simplegit.rb 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22) end ---- -Nota que el primer campo es la parcial de SHA-1 del commit que modificó esa línea. -Los siguientes dos campos son valores extraídos del commit- el nombre del autor y la fecha del commit - así podrás ver de manera sencilla quién modificó esa línea y cuándo. +Nota que el primer campo es la parcial de SHA-1 del ``commit'' que modificó esa línea. +Los siguientes dos campos son valores extraídos del ``commit'' - el nombre del autor y la fecha del commit - así podrás ver de manera sencilla quién modificó esa línea y cuándo. Tras estos viene el número de línea y el contenido del archivo. -También nota las líneas del commit `^4832fe2`, que designan que esas líneas estuvieron en el commit original del archivo. -Ese commit es cuando este archivo fue introducido por primera vez al proyecto, y esas líneas no han sido modificadas desde entonces. -Esto es un poco confuso, porque ahora has visto al menos tres maneras diferentes en que Git usa el `^` para modificar el SHA-1 de un commit, pero eso es lo que significa aquí. +También nota las líneas del ``commit'' `^4832fe2`, que designan que esas líneas estuvieron en el ``commit'' original del archivo. +Ese ``commit'' es cuando este archivo fue introducido por primera vez al proyecto, y esas líneas no han sido modificadas desde entonces. +Esto es un poco confuso, porque ahora has visto al menos tres maneras diferentes en que Git usa el `^` para modificar el SHA-1 de un ``commit'', pero eso es lo que significa aquí. -Otra cosa interesante de Git es que no rastrea los nombres de archivos de forma explícita. -Registra las instantáneas y luego intenta averiguar lo que fue renombrado implícitamente, después del hecho. +Otra cosa interesante de Git, es que no rastrea los nombres de archivos de forma explícita. +Registra las instantáneas y luego intenta averiguar lo que fué renombrado implícitamente, después del hecho. Una de las características interesantes de esto es que se puede preguntar todo tipo de movimiento de código también. -Si pasas `-C` a` git blame`, Git analiza el archivo que estás anotando y trata de averiguar de dónde provienen originalmente fragmentos de código si se copiaron desde otro lugar. +Si pasas `-C` a` git blame`, Git analiza el archivo que estás anotando y trata de averiguar de dónde provienen originalmente los fragmentos de código si se copiaron desde otro lugar. Por ejemplo, digamos que estás modificando un archivo llamado `GITServerHandler.m` en múltiples archivos, uno de estos es `GITPackUpload.m`. -Realizando un blame a `GITPackUpload.m` con la opción `-C`, se puede ver de dónde vinieron las secciones del código: +Realizando un ``blame'' a `GITPackUpload.m` con la opción `-C`, se puede ver de dónde vinieron las secciones del código: [source,console] ---- @@ -60,22 +60,22 @@ ad11ac80 GITPackUpload.m (Scott 2009-03-24 150) ---- Esto es realmente útil. -Normalmente, se obtiene como el commit original aquel de dónde se copió el código, porque esta es la primera vez en la que se tocaron estas líneas en el archivo. -Git te informa el commit original donde se escribieron esas líneas, incluso si esto fue hecho en otro archivo. +Normalmente, se obtiene como el ``commit original'' aquel de dónde se copió el código, porque esta es la primera vez en la que se tocaron estas líneas en el archivo. +Git te informa el ``commit original'' donde se escribieron esas líneas, incluso si esto fue hecho en otro archivo. [[r_binary_search]] ==== Búsqueda binaria -Anotar un archivo ayuda si sabe dónde está el problema. -Si no sabes lo que está mal, y ha habido decenas o cientos de commits desde el último estado en el que sabes que funcionó el código, probablemente te recurrirás a `git bisect` para obtener ayuda. -El comando `bisect` hace una búsqueda binaria a través de su historial de commits para ayudarle a identificar lo más rápidamente posible qué commit introdujo un problema. +Anotar un archivo ayuda si sabes dónde está el problema. +Si no sabes lo que está mal, y ha habido decenas o cientos de ``commits'' desde el último estado en el que sabes que funcionó el código, probablemente recurrirás a `git bisect` para obtener ayuda. +El comando `bisect` hace una búsqueda binaria a través de su historial de commits para ayudarte a identificar lo más rápidamente posible qué commit introdujo un problema. -Supongamos que acaba de emitir un release de su código en un entorno de producción, está recibiendo informes de errores sobre algo que no estaba ocurriendo en su entorno de desarrollo y no puede imaginar por qué el código lo está haciendo. -Regresa a su código, y resulta que puede reproducir el problema, pero no puede averiguar qué está pasando mal. -Puede biseccionar el código para averiguarlo. -Primero ejecuta `git bisect start` para hacer que las cosas funcionen, y luego usas` git bisect bad` para decirle al sistema que el commit actual está roto. -Entonces, debe decir a bisect cuándo fue el último estado bueno conocido, usando `git bisect good [good_commit]`: +Supongamos que acabas de emitir un release de tu código en un entorno de producción, estás recibiendo informes de errores sobre algo que no estaba ocurriendo en tu entorno de desarrollo y no puedes imaginar por qué el código lo está haciendo. +Regresas a tu código, y resulta que puedes reproducir el problema, pero no puedes averiguar qué está mal. +Puedes biseccionar el código para averiguarlo. +Primero ejecuta `git bisect start` para hacer que las cosas funcionen, y luego usas `git bisect bad` para decirle al sistema que el ``commit'' actual está roto. +Entonces, debes decir a `bisect` cuándo fue el último estado bueno conocido, usando `git bisect good [good_commit]`: [source,console] ---- @@ -86,9 +86,9 @@ Bisecting: 6 revisions left to test after this [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo ---- -Git se dio cuenta de que se produjeron alrededor de 12 commits entre el commit que marcó como el último commit bueno (v1.0) y la versión mala actual, y se comprobó el del medio para usted. -En este punto, puede ejecutar su prueba para ver si el problema existe a partir de este commit. -Si lo hace, entonces se introdujo en algún momento antes de este commit medio; Si no lo hace, entonces el problema se introdujo en algún momento después del commit del medio. +Git se dió cuenta de que se produjeron alrededor de 12 commits entre el commit marcado como el último commit bueno (v1.0) y la versión mala actual, y comprobó el del medio para ti. +En este punto, puedes ejecutar tu prueba para ver si el problema existe a partir de este ``commit''. +Si lo hace, entonces se introdujo en algún momento antes de este ``commit'' medio; si no lo hace, entonces el problema se introdujo en algún momento después del ``commit'' medio. Resulta que no hay ningún problema aquí, y le dices a Git escribiendo `git bisect good` y continúa tu viaje: [source,console] @@ -98,8 +98,8 @@ Bisecting: 3 revisions left to test after this [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing ---- -Ahora estás en otro commit, a medio camino entre el que acabas de probar y tu mala comisión. -Ejecuta la prueba de nuevo y descubre que este commit está roto, por lo que le dices a Git que con `git bisect bad`: +Ahora estás en otro ``commit'', a medio camino entre el que acabas de probar y tu mala comisión. +Ejecutas la prueba de nuevo y descubres que este ``commit'' está roto, por lo que le dices a Git `git bisect bad`: [source,console] ---- @@ -108,8 +108,8 @@ Bisecting: 1 revisions left to test after this [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table ---- -Este commit está bien, y ahora Git tiene toda la información que necesita para determinar dónde se introdujo el problema. -Le dice que el SHA-1 del primer commit erróneo y muestra algo de la información del commit y qué archivos se modificaron en ese commit para que pueda averiguar qué sucedió que pueda haber introducido este error: +Este ``commit'' está bien, y ahora Git tiene toda la información que necesita para determinar dónde se introdujo el problema. +Te dice el SHA-1 del primer ``commit'' erróneo y muestra algo de la información del ``commit'' con qué archivos se modificaron en ese ``commit'' para que puedas averiguar qué sucedió que pueda haber introducido este error: [source,console] ---- @@ -125,17 +125,17 @@ Date: Tue Jan 27 14:48:32 2009 -0800 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config ---- -Cuando haya terminado, debe ejecutar `git bisect reset` para reiniciar su HEAD a donde estaba antes de comenzar, o terminará en un estado raro: +Cuando hayas terminado, debes ejecutar `git bisect reset` para reiniciar el HEAD a donde estaba antes de comenzar, o terminará en un estado raro: [source,console] ---- $ git bisect reset ---- -Esta es una herramienta poderosa que puede ayudarle a comprobar cientos de commits para un bug introducido en cuestión de minutos. -De hecho, si tiene un script que retornará 0 si el proyecto está bien u otro número si el proyecto está mal, puede automatizar completamente `git bisect`. -En primer lugar, vuelva a decirle el alcance de la bisectriz, proporcionando los commits malos y buenos. -Puede hacerlo enumerándolos con el comando `bisect start` si lo desea, listando primero el commit malo conocido y el segundo el commit bueno conocido: +Esta es una herramienta poderosa que puede ayudarte a comprobar cientos de ``commits'' para un bug introducido en cuestión de minutos. +De hecho, si tienes un script que retornará 0 si el proyecto está bien u otro número si el proyecto está mal, puedes automatizar completamente `git bisect`. +En primer lugar, vuelve a decirle el alcance de la bisectriz, proporcionando los ``commits'' malos y buenos. +Puedes hacerlo enumerándolos con el comando `bisect start` si lo deseas, listando primero el ``commit'' malo conocido y segundo el ``commit'' bueno conocido: [source,console] ---- @@ -143,5 +143,5 @@ $ git bisect start HEAD v1.0 $ git bisect run test-error.sh ---- -Hacerlo ejecuta automáticamente `test-error.sh` en cada commit de check-out hasta que Git encuentre el primer commit roto. -También puede ejecutar algo como `make` o ` make tests` o lo que sea que ejecute pruebas automatizadas para usted. +Hacerlo ejecuta automáticamente `test-error.sh` en cada ``commit'' de ``check-out'' hasta que Git encuentre el primer ``commit'' roto. +También puedes ejecutar algo como `make` o ` make tests` o lo que sea que ejecute pruebas automatizadas para ti. diff --git a/book/07-git-tools/sections/interactive-staging.asc b/book/07-git-tools/sections/interactive-staging.asc index c83375fc..a0c93d45 100644 --- a/book/07-git-tools/sections/interactive-staging.asc +++ b/book/07-git-tools/sections/interactive-staging.asc @@ -1,10 +1,10 @@ [[r_interactive_staging]] === Organización interactiva -El git viene con unos cuantos scripts que hace que algunas líneas de comando sean más fáciles de usar. -Aquí, Veras unos cuantos comandos interactivos que te ayudaran a preparar tus confirmaciones para incluir solo ciertas combinaciones y partes de los archivos. -Estás herramientas serán muy útiles si modificas unos cunatos archivos y decides que quieres esos cambios estén en varias confirmaciones enfocadas más que en una gran problemática confirmación. -De esta manera, puede asegurarse de que sus confirmaciones sean conjuntos de cambios lógicamente separados y que puedan ser revisados fácilmente por los desarrolladores que trabajan con usted. +Git viene con unos cuantos scripts que hacen que algunas líneas de comando sean más fáciles de usar. +Aquí, verás unos cuantos comandos interactivos que te ayudaran a preparar tus confirmaciones para incluir sólo ciertas combinaciones y partes de los archivos. +Estás herramientas serán muy útiles si modificas unos cuantos archivos y decides que esos cambios estén en varias confirmaciones enfocadas, en lugar de en una gran confirmación problemática. +De esta manera, puedes asegurarte de que tus confirmaciones sean conjuntos de cambios lógicamente separados y que puedan ser revisados fácilmente por los desarrolladores que trabajan contigo. Si empiezas `git add` con el `-i` o la opción `--interactive` , Git entra en un modo de celda interactiva, mostrando algo como esto: [source,console] @@ -21,15 +21,15 @@ $ git add -i What now> ---- -Puedes ver que este comando te muestra una muy diferente vista de tu área de ensayo – básicamente la misma informacion que con el with `git status` pero un poco más sucinto e informativo. -Muestra los cambios que haz realizado en la izquierda y cambios que no haz hecho a la derecha. +Puedes ver que este comando te muestra una muy diferente vista de tu área de ensayo – básicamente la misma información que con `git status`, pero un poco más sucinto e informativo. +Muestra los cambios que has realizado en la izquierda y cambios que no has hecho a la derecha. Después de esto viene una sección de comandos. -Aquí puedes hacer un sin número de cosas, incluidos los archivos organizados, archivos sin organizar, partes de archivos organizados, agregar archivos sin seguimiento y ver las diferencias de lo que se ha modificado. +Aquí puedes ver un sin número de cosas, incluidos los archivos organizados, archivos sin organizar, partes de archivos organizados, agregar archivos sin seguimiento y ver las diferencias de lo que se ha modificado. ==== Organizar y desorganziar archivos -Si tecleas `2` o `u` en el `What now>` rápidamente, la secuencia de comandos le solicita los archivos que desea representar: +Si tecleas `2` o `u` en el `What now>` rápidamente, la secuencia de comandos solicita los archivos que deseas representar: [source,console] ---- @@ -41,7 +41,7 @@ What now> 2 Update>> ---- -Para organizar los archivos de TODO and index.html , puedes teclear los números: +Para organizar los archivos de TODO e index.html , puedes teclear los números: [source,console] ---- @@ -53,8 +53,8 @@ Update>> 1,2 Update>> ---- -El `*` después de cada archivo significa que el archivo fue seleccionado para ser organizado. -Si presionas Enter después de no escribir nada en el `Update>>` rapidamente, Git toma cualquier cosa seleccionada y la organiza por ti: +El `*` antes de cada archivo significa que el archivo fue seleccionado para ser organizado. +Si presionas 'Enter' después de no escribir nada en el `Update>>` rapidamente, Git toma cualquier cosa seleccionada y la organiza por ti: [source,console] ---- @@ -71,8 +71,8 @@ What now> 1 3: unchanged +5/-1 lib/simplegit.rb ---- -Ahora puedes ver que los archivos de TODO and index.html han sido organizados y el archivo simplegit.rb aun está sin organizar. -If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option: +Ahora puedes ver que los archivos de TODO e index.html han sido organizados y el archivo simplegit.rb aún está sin organizar. +Si deseas quitar el archivo TODO en este punto, use la opción `3` o `r` (para revertir): [source,console] ---- @@ -93,7 +93,7 @@ Revert>> [enter] reverted one path ---- -Mirando el estatus de tu Git de nuevo, puedes ver que haz desordenado el archivo de TODO: +Mirando el estatus de tu Git de nuevo, puedes ver que has desordenado el archivo TODO: [source,console] ---- @@ -107,8 +107,8 @@ What now> 1 3: unchanged +5/-1 lib/simplegit.rb ---- -Para ver la diferencia de lo que ya haz ordenado, puedes usar el `6` o `d` (para diferente) comando. -Este te muestra una lista de tus archivos organziados, y puedes seleccionar aquellos que quisieras ver la diferencia de su organización. +Para ver la diferencia de lo que ya has ordenado, puedes usar el comando `6` o `d` (para diferente). +Éste te muestra una lista de tus archivos organziados, y puedes seleccionar aquellos de los que quisieras ver la diferencia de su organización. Esto es como especificar el `git diff --cached` en la línea de comando: [source,console] @@ -134,14 +134,14 @@ index 4d07108..4335f49 100644