Notxor tiene un blog

Defenestrando la vida


Usando «magit»

Ya he hablado otras veces por aquí de git y cómo, a estas alturas, se ha convertido en una herramienta indispensable para mí. La verdad es que ahora prácticamente no utilizo la línea de comandos para usarlo. La mayor parte de las cosas que hago orbitan alrededor de emacs y git ha caído también en esa órbita.

El tema es que, como emacs se ha convertido en la herramienta que más utilizo para casi todo: escribir documentos, programar, llevar la contabilidad, la agenda. En fin, un montón de cosas. Además luego muchos de esos ficheros que genero van a un repositorio git y así puedo acceder desde todos mis dispositivos, me sirve de copia de seguridad también y me permite estudiar cuándo se hizo una modificación y por qué.

Cuando comencé en estas cosas de los repositorios era muy caótico. Lo sigo siendo, sobre todo en la forma de expresarme. Mis imprecisiones en el lenguaje técnico lo sufre especialmente el amigo Deesix que tiene la costumbre de darme los tirones de orejas que me merezco. Algo loable, por su paciencia y que yo le agradezco infinitamente. Si alguien lee este escrito como «iniciación» al uso de magit en emacs, tiene que agradecerle que yo haya prestado una especial atención a la terminología intentando no confundir al lector. Me permitiréis que os cite una frase suya: «bastante difícil es comunicarse como para complicarlo», escrita a las 22:46:05 del día 28 de noviembre de 2018 a través del IRC.

Dicho esto, entraré en materia.

magit

La herramienta para manejar repositorios git en emacs se llama magit. Otra de las herramientas que merecen la pena de mi entorno de trabajo favorito1.

Instalar magit

Seguramente este paso se podría dar por sabido. Cualquiera que haya trabajado mínimamente con emacs sabe cómo instalar un paquete. De todas formas lo escribo aquí:

M-x package-install <RET> magit <RET>

Con eso, ya podemos disponer de la herramienta. La única dependencia es que git tiene que estar instalado en el sistema.

La única línea de código que tengo en el init.el es la siguiente:

(global-set-key (kbd "C-c g") 'magit-status)

Uso de magit

Voy a utilizar éste artículo como fuente para mostrar cómo vengo utilizando la herramienta. ¿Será éste un artículo o un metaartículo? Bueno, da igual, imaginemos que queremos añadir el artículo al repositorio. Lo primero que podemos hacer es llamar a magit-status, en mi caso pulsando la combinación de teclas C-c g porque lo tengo fijado así en la configuración de emacs. Ese comando dividirá la ventana y aparecerá el buffer de magit-status en el que me informa de que hay un fichero untraked: blog/magit.org. Pongo la imagen para ser más visual:

buffer-magit-status.png

Como vemos también nos indica en las dos primeras líneas de los valores de Head y Merge. En este caso, nuestros repositorios: local y origin, tienen la rama source sincronizados en el mismo commit.

Siguiente paso: añadir el fichero al proyecto pulsando s con el cursor situado sobre la línea. Esto hará stage y preguntará si debe guardar el fichero si ha detectado que hay cambios sin guardar. Si hubiera varios ficheros o cambios se puede hacer también que añada todos los cambios pulsando s sobre el título que los agrupa. El resultado quedaría así:

staged-changes.png

Aparecerá una ventana que nos permite escribir el mensaje asociado con el commit junto a un buffer que nos muestra los cambios que se asocian con él. Al pulsar c en el buffer de magit-status, el sistema abre un menú con todas las acciones que podemos realizar en el commit:

menu-commit.png

Como sólo queremos hacer el commit volvemos a pulsar c y nos aparecerá un buffer en el que podemos escribir el mensaje asociado con el commit y otro con todos los cambios que se corresponderán con él.

escribiendo-commit.png

¿Y si no lo quiero meter todo en el mismo commit?

Hay ocasiones en las que no quieres asociar todos los cambios que se han hecho en un archivo en el mismo commit. Antes de descubrir cómo se hace en magit lo hacía desde la línea de comandos con git commit -p o con el entorno gráfico que proporciona el mismo git: git-tk. Suponía que debía haber un modo (normalmente siempre lo hay), para hacerlo sin salir de emacs. Y lo encontré. Pero voy a mostrar los pasos con un ejemplo, a parte de lo añadido al final del artículo también he cambiado la fecha en la cabecera para actualizar la fecha. Quiero separar los commits, porque uno se realiza por un cambio en el contenido mientras el otro es un cambio en los «metadatos».

Vuelvo al buffer de magit-status y me encuentro que sólo he modificado un archivo: blog/magit.org. Si hago stage pulsando s sobre él, lo hará sobre todos los cambios que tenga. En lugar de pulsar s, pulsaré <TAB>. El resultado es que me despliega todos los cambios de ese fichero en un formato diff para analizar qué se ha cambiado, así:

diff-cambios.png

Ahora me iré con el cursor hacia la línea donde cambié la fecha y voy a hacer el stage, pulsando s sobre esos cambios. En la imagen siguiente podemos ver que el mismo fichero blog/magit.org tiene cambios en estado staged y en estado unstaged.

staged-unstaged.png

Ahora es cuando hacemos el commit del modo anterior. Repetiremos el proceso las veces que necesitemos para dejar todos los cambios preparados y listos para el siguiente paso.

Subir cambios al repositorio remoto

Mientras hemos ido haciendo commits podemos habernos dado cuenta que las dos primeras líneas, que marcan el head y el merge junto con nuestros repositorios source (local) y origin/source (remoto), no apuntan al mismo commit. Es decir, no están sincronizados. Para sincronizarlos debemos subir todos esos cambios, que hemos hecho en el local al remoto haciendo un push. Para hacerlo, tengo por costumbre comprobar primero que en el remoto no hay cambios que no estén en el local. Cuando trabajas como único «mantenedor» del repositorio, es habitual que no haya nada en el remoto que no esté en el local, pero si trabajas con varios dispositivos algunas veces te puedes llevar alguna «sorpresa», y mucho más cuando varias personas trabajan sobre el mismo repositorio remoto. Resumiendo, para hacer el pull hay que pulsar F ─obsérvese que es mayúscula, la minúscula corresponde a fetch y abrirá otro diálogo─ para que se muestre el diálogo de pull.

haciendo-pull.png

Si todo está correcto, continuamos con el siguiente paso: hacer el push. Para ello, pulsaremos en el buffer de magit-status la tecla P ─obsérvese también la mayúscula─ y nos abrirá el diálogo. Como lo quiero subir al repositorio origin/source pulsaré después la tecla u

haciendo-push.png

A estos pasos, para desesperación de los más técnicos, yo los llamo «un mete-saca rapidito» y si todo ha ido bien, ya tendremos el repositorio local y el remoto sincronizados de nuevo.

Cambiando de rama

Algunas veces no estás en la rama adecuada o simplemente quieres cambiar a otra. No hace falta que salgas de emacs cambies la rama y vuelvas a entrar en emacs. Simplemente hay que ejecutar un comando magit-checkout con M-x magit-checkout y te situará en la rama adecuada. Se puede percibir que en la línea de status de emacs cuando estamos editando un fichero perteneciente a un repositorio git, automáticamente lo muestra diciéndonos además en qué rama estamos. Por ejemplo, mientras edito este fichero emacs muestra el mensaje Git:source en su barra de estado informándome que hay un repositorio git y está señalando a la rama source.

Conclusión

Hay muchas más opciones, tantas como tiene git. Sin embargo me he limitado a contar las que más utilizo y cómo. magit es una gran herramienta para gestionar los repositorios git, cada vez encuentro más y más funcionalidades; ha conseguido que deje la línea de comandos para hacer muchas cosas. Sólo espero que acostumbrado a la facilidad que proporciona no se me olviden los comandos y me encuentre imposibilitado de trabajar cuando me falte.

Nota al pie de página:

1

Obsérvese que evito llamar «editor» a emacs.


Comentarios