¡Bienvenidos una semana más a un nuevo rootie queridos amigos! Esta semana volvemos a la carga con una nueva entrega sobre Git. Hoy, como comentamos en nuestro última entrada, vamos a hablar de dos temas diferentes: conflictos a la hora de reintegrar nuestras ramas y de lo que venimos llamando «comandos avanzados» pero en realidad son comandos que se utilizan no con tanta frecuencia, y que iremos completando en diferentes entradas.
Conflictos en Git.
Cuando estamos trabajando con Git, utilizando ramas, como ya hemos comentando en el artículo anterior, siempre llega un momento en que nuestras ramas tienen que reintegrarse en nuestra rama principal (normalmente master). Este proceso puede ir de tres formas:
- Mal
- Terriblemente mal
- ¡Ohmyroot!
¡Es broma, solo se dan las dos ultimas! Esto se debe a los diferentes conflictos que pueden aparecer (y en un momento u otro aparecerán) cuando estas trabajando con ramas. Estos conflictos aparecen en el proyecto cuando por ejemplo, hemos estado trabajando en dos ramas diferentes modificando el mismo código, lo que provocará que Git no sea capaz de reintegrar nuestro código en el/los archivo/s afectados y nos muestre un mensaje similar a este.
1 2 3 4 |
ohmyroot-laptop@Merks:~/Desktop/ohmyroot$ git merge fuuuuusion Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result. |
Arreglando un conflicto
Antes he mencionado que el merge puede ir terriblemente mal o ¡ohmyroot!, la diferencia entre el primero y el segundo será la cantidad de archivos afectado y la cantidad de código a revisar.
Una vez que Git ha encontrado un conflicto, automáticamente parará el proceso de reintegración, indicando que la rama no esta totalmente reintegrada, para que tu resuelvas manualmente el conflicto. Además Git modificará automáticamente los archivos afectados por el conflicto agregando marcadores, que nos indicarán a que revisión pertenece el código que engloban.
1 2 3 4 5 6 7 |
<<<<<<< HEAD:index.html <div id="pie">contacto : contacto@ohmyroot.com</div> ======= <div id="pie"> para cualquier comentario escríbenos a contacto@ohmyroot.com </div> >>>>>>> fuuuuusion:index.html |
Como podéis observar, se agregan al fichero varias líneas, que nos idican el HEAD, donde estamos apuntando para hacer el merge y con un separador el código de nuestra rama. Llegados a este punto, tenemos dos opciones:
Opción manual:

Esta solución al conflicto pasa por, abrir todos archivos afectados, ver en que consiste el conflicto en cada archivo, decidir si quieres una versión u otra o una combinación de las mismas, modificar el fichero, guardarlo y hacer el siguiente. Una vez estés seguro de que todos tus archivos se encuentran libres de conflictos, tienes que realizar el commit para finalizar el proceso de reintegración.
Opción asistida:
Para esta solución utilizaremos el comando git mergetool. Este comando ejecutará una herramienta gráfica que nos ayudará a realizar la opción manual, pero sin tener que abrir los archivos por nosotros mismos. Dependiendo de la herramienta (porque puedes configurarla para usar la que mas te guste) ofrecerá mas o menos ventajas, como resaltar el código afectado con diferentes colores, agregar partes de un lado u otro, etc. Una vez termines de usar la herramienta, Git te preguntará si la reintegración ha sido satisfactoria, si le contestas que si te añadirá todos los archivos listos para hacer el commit.
Como nota final a los conflictos, a mi para la herramienta de merge, me gusta mucho Meld que puede usarse tanto en Windows (¿en serio alguien programa en Windows?, ¿puedo dejar de mencionarlo?) como en sistemas Unix y OS.
Comandos avanzados

Aparte de los comandos que he ido nombrando en posts anteriores, vamos a hablar de comandos más avanzados (o que por lo que sea todavía no he nombrado)
Git log:
El comando git log nos devolverá el histórico de confirmaciones de la rama en la que estamos trabajando de una forma interactiva (podremos hacer scroll arriba/abajo). Este comando nos mostrara el hash del commit, el autor con su email, la fecha y el mensaje de confirmación., en orden descendente.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ohmyroot-laptop@Merks:~/Desktop/ohmyroot$ git log commit 4237c5b053b54079eeb489109f79836b763ac178 Author: Merkury <contacto@ohmyroot.com> Date: Mon Nov 21 11:00:00 2016 +0000 fixed typo commit 6972fca035fa8927f68aafc014577b45f7612444 Merge: ad865a3 827e9fd Author: Merkury <contacto@ohmyroot.com> Date: Mon Nov 21 10:50:00 2016 +0000 Merge branch 'master' of https://github.com/Merk87/ohmyroot |
Git stash:
El comando git stash, como su nombre indica en inglés, nos permite crear un almacenamiento temporal de nuestros cambios (que estén sin confirmar), y volver temporalmente al estado inicial de la rama. Por ejemplo en mi repositorio he añadido dos nuevos ficheros:
1 2 3 4 5 6 7 8 9 10 |
ohmyroot-laptop@Merks:~/Desktop/ohmyroot$ git status On branch master Your branch is up-to-date with 'origin/master'. Untracked files: (use "git add <file>..." to include in what will be committed) bar.php foo.php nothing added to commit but untracked files present (use "git add" to track) |
Pero resulta, que en mitad de este importantisimo trabajo, alguien me llama y me dice que hay un bug en producción y tengo que arreglarlo. Como no quiero perder estos cambios, pero no quiero confirmarlos, porque es código sin probar, incompleto, etc. usaría git stash una vez ejecutado, tendríamos este mensaje:
1 2 3 4 5 6 7 |
ohmyroot-laptop@Merks:~/Desktop/ohmyroot$ git stash Saved working directory and index state WIP on master: 4237c5b fixed typo HEAD is now at 4237c5b fixed typo ohmyroot-laptop@Merks:~/Desktop/ohmyroot$ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working tree clean |
Una vez que queremos recuperar los cambios almacenados en el stash mas reciente y eliminarlo, podemos hacer simplemente git stash pop.
Si tenemos mas de un stash (puedes ejecutar git stash list para comprobarlo)
1 2 3 4 |
ohmyroot-laptop@Merks:~/Desktop/ohmyroot$ git stash list stash@{0}: WIP on master: 049d078 added the index file stash@{1}: WIP on master: c264051 Revert "added file_size" stash@{2}: WIP on master: 21d80a5 added number to log |
Tendremos que indicar que stash queremos aplicar usando el comando git stash apply [email protected]{2} el número entre las llaves, indica el stash en la lista.
Git revert:
Este comando, nos sirve para deshacer un commit completo. Lo bueno de este comando es que no elimina la instantánea del repositorio, si no que compara el commit a deshacer y nos crea un nuevo commit, con los cambios necesarios, con lo que nuestro log, queda intacto (y podemos hacer revert al commit generado en el revert!)

Git blame:
Uno de mis favoritos… yo en la oficina lo llamo «Jugar al juego de la culpa». Git blame como ya os he spoileado nos dice exactamente quien hizo que cambio en que fichero. Para usarlo simplemente tenemos que hacer git blame y nos mostrara lo siguiente:
1 2 3 4 5 6 7 8 9 10 |
ohmyroot-laptop@Merks:~/Desktop/ohmyroot$ git blame index.html dfab71cc (Victor Moreno 2016-11-02 22:32:23 +0000 1) <<!DOCTYPE html> dfab71cc (Victor Moreno 2016-11-02 22:32:23 +0000 2) <html> dfab71cc (Victor Moreno 2016-11-02 22:32:23 +0000 3) <head> dfab71cc (Victor Moreno 2016-11-02 22:32:23 +0000 4) <title>hmyroot!</title> dfab71cc (Victor Moreno 2016-11-02 22:32:23 +0000 5) </head> dfab71cc (Victor Moreno 2016-11-02 22:32:23 +0000 6) <body> dfab71cc (Victor Moreno 2016-11-02 22:32:23 +0000 7) <h1>ohmyroot!</h1> dfab71cc (Victor Moreno 2016-11-02 22:32:23 +0000 8) </body> dfab71cc (Victor Moreno 2016-11-02 22:32:23 +0000 9) </html> |
Como podéis ver, nos muestra numero (abreviado) de commit, autor, fecha y hora y la linea del fichero. Yo lo encuentro extremadamente útil para cagarme en para poder preguntar a la gente porque hizo tal cosa.
¡Bonus track!
Hoy os voy a compartir un par de git aliases que para los usuarios de consola os van a venir muy bien. Simplemente añadiendo estos dos comandos en nuestro .gitconfi
1 2 3 4 5 6 7 8 9 10 11 12 |
[alias] #Si existe, poner los comandos al final. # Los colores pueden cambiarse. # Copiarlo en una única linea: hist = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dimwhite)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all # Copiarlo en una única linea: hist-files= log --graph --abbrev-commit --decorate --date=relative --all --stat --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all |
Estos dos comandos os mostrarán, respectivamente, los diferentes commits hechos tanto en master como en diferentes ramas, dibujando diferentes lineas por cada rama y lo mismo pero mostrando información sobre los ficheros editados, aqui podéis verlos en acción. Esto crea una herramienta visual bastante buena en consola.
Y con esto nos despedimos por hoy, en la próxima entrega sobre Git hablaremos sobre un tema bastante interesante Merge Vs. Rebase y ademas haré otra entrega de comandos avanzados!. Para cualquier duda, pregunta, comentario, soborno o amenaza, podéis usar los comentarios o en nuestras redes sociales Facebook y Twitter.
1 |
sudo shutdown -h now |