Apuntes mientras aprendo sobre software y computadoras.

Computación

Guía básica para usar Git

Hola, te doy la bienvenida a mi “Guía básica para usar GIT en Linux escrita por alguien que nunca utilizó Git antes”. O también para abreviar la “Guía básica para usar GIT”.

Al igual que la mayoría de los apuntes en esta página, estoy escribiendo todo esto para aprender un tema del que no conozco nada o casi nada. Y en este caso no conozco nada.

Solamente se que hay un sitio web llamado Github donde muchas personas comparten sus proyectos, pero no tengo idea de nada más. Esa es toda mi aproximación a Git, y solo porque aparece al frente de la palabra “Gitgub”.

¿Por que estoy escribiendo una guía de algo que no conozco? Intento valerme del antiguo truco de explicar algo para conseguir aprenderlo.

Así que si no te molesta acompañarme en el proceso de descubrimiento… te invito a seguir leyendo.

Vale agregar que todo este texto fue creado consultando el manual que acompaña a git. Es posible consultar ese manual, una vez instalado el programa, con el comando:

man git

Siempre de gran utilidad recordarlo, es posible usar el comando man para conocer el manual de la mayoría de los programas instalados.

Una última aclaración es que utilicé la versión en inglés del manual, para practicar un poco de inglés a la vez que escribo de computación. Aprender dos cosas al mismo tiempo, nada mal diría yo.

Y no es completamente necesario usar Linux para seguir este apunte, pero ayuda bastante. Muchos de los comandos que vamos a usar van a necesitar modificaciones para funcionar en otros sistemas operativos.

¿Qué es git?

El ya mencionado manual nos dice lo siguiente:

NAME
git – the stupid content tracker

Manual de git

Bien… en que forma traducir esto… Según entiendo, quiere decir lo siguiente:

git – un rastreador de contenido muy fácil de usar.

Bueno, entonces git sirve para “rastrear” el contenido de una carpeta. Lo que sea que eso significa. Sigamos leyendo.

DESCRIPTION
Git is a fast, scalable, distributed revision control system with an
unusually rich command set that provides both high-level operations and full access to internals.

Manual de Git

O en mis palabras:

Git es un sistema de revisión de control distribuible, rápido y escalable, con una inusualmente variada cantidad de comando que proveen la posibilidad de operaciones de alto nivel y acceso a su funcionamiento interno.

Descontemos los de la gran variedad de comandos, lo que más me interesa de todos esos fragmentos puedo interpretarlo como:
“sistema de revisión de control”: hace un seguimiento de los cambios en mis archivos a lo largo del tiempo.

Perfecto, creo que ya entiendo de que va la cosa. Git es un programa que me permite ver los cambios en un archivo a lo largo de sus distintas modificaciones.

Pero aun sabiendo esto, admito que es difícil de entender sin empezar a usarlo. Al igual que ocurre con la mayoría de lo que aprendemos, hay que usar la información para comprendela creo yo.

Con todo, esto parecer ser algo similar a lo que se conoce por un “checkpoint” o un punto de control en un videojuego. Cuando progresamos en la historia de un videojuego, podemos ir grabando nuestra partida a medida que avanzamos. Siempre podemos volver a experimentar cosas que ya jugamos en tanto que grabemos la partida y la recuperemos . Eso nos permite regresar al pasado, por decirlo de algún modo.

Git parece obrar de una forma similar, pero para archivos en general. Una vez más, va a ser mejor poner todo esto en acción.

Cómo instalar GIT en Linux

Bien, el sitio con los datos para la descarga e instalación de GIT podemos encontrarlos en: https://git-scm.com/downloads

Ahí vas a poder encontrar instrucciones para instalarlo en diferentes distribuciones de Linux. Lo mismo hay instrucciones para otros sistemas operativos.

Toda la instalación se realiza a través de la terminal. Para instalar lo en Linux Mint, el sistema donde realicé todas las pruebas para este apunte, el comando a utilizar es:

sudo apt install git

Para saber si se instaló correctamente, o si te da curiosidad saber si ya lo tenías instalado de antemano, se puede utilizar este sencillo comando para conocer que version tenemos en la computadora:

git --version

Y para tener un pantallazo general de los comandos principales que vamos a usar en el futuro próximo, podemos escribir en la terminal:

git --help

No hay que olvidar usar los dos guiones. Help nos brinda una versión mucho más resumida que el manual.

Guardando archivos: ver8finalfinalultimo

¿Cómo es la forma en la que organizo un proyecto cuando trabajo en la computadora? ¿Cómo hago para no perderme entre las distintas versiones de un archivo al momento de guardarlas?

Pensemos en un ejemplo fácil, un documento de texto. Cuando escribo un tutorial, tengo un primer borrador donde escribo algunas ideas con algo de desarrollo. Para empezar vamos a llamar a ese archivo “apunte.txt”, y lo voy a guardar en el directorio ”nuevo_tutorial”.

Luego guardo otro documento de texto, basado en el borrador original, una nueva versión “apunte_ver2.txt”. Es la nueva versión, mejor estructurada y con más información. Al continuar escribiendo guardo otro nuevo archivo llamado “apunte_ver3.txt” y luego la versión cuatro, cinco… y cuantas sean necesarias hasta llegar al resultado final.

Este proceso consigue que tenga siempre a disposición varios puntos de control a los que puedo volver. Claro que esos puntos de control no son otra cosa que nuevas versiones del mismo documento que generé manualmente.

En una misma carpeta ahora hay una docena de archivos, desde “apunte.txt” hasta “apunte_ver8finalfinalultimo.txt”, pasando por “apunte_ver2.txt” y todos los demás que existen en el medio.

Y eso es bastante engorroso, porque el resultado es una carpeta llena de documentos de texto de los cuales realmente no conozco el contenido (el nombre de los mismos no es para nada descriptivo) ni conozco la razón por las cual los abandoné. En su momento generar una nueva versión tenía sentido, pero dos minutos más tarde es imposible que recuerde cual fue el motivo de su creación. Volver a reutilizarlos es algo que casi nunca ocurre.

Para peor, llevar un orden de todas estas versiones se pone cada vez más difícil cuanto más complejos un proyecto. Pensemos por ejemplo en la escritura de un proyecto con múltiples fuentes o la creación de un programa con numerosas piezas de código y aplicaciones. Esta forma de trabajar que describí, la de archivos desordenados, no es nada práctica.

Aquí es donde Git entra en funcionamiento para ayudarnos. Se utiliza muchísimo en programación, pero se puede utilizar para el control y el seguimiento de otro tipo de proyectos.

Para los ejemplos que siguen voy a retener mi idea de controlar el progreso de “apunte.txt” en el directorio nuevo_tutorial, a modo de volver la explicación más sencilla toda la explicación. O eso espero.

Cómo crear una repo con Git

Con la terminal establecida en la carpeta que vamos a usar como principal, utilizamos el comando:

git init

Lo que si todo va bien me da como respuesta:

Initialized empty Git Repository

O traducido: Se inicializó un repositorio vacío de Git.

Eso va a generar una serie de archivos ocultos dentro del directorio. No puedo encontrar esos archivos a menos que expresamente pida mostrar los documentos ocultos en la carpeta (en inglés, “Shown Hidden Files”).

Es claro que no entiendo bien que es lo que hace cada uno de esos archivos por separado, pero entiendo que en su conjunto son lo que permiten que Git siga la pista de lo que ocurre en la carpeta.

Si tengo que describir lo acontecido, puedo entender que este directorio donde inicié el comando se convierte ahora en el repositorio de nuestro proyecto. O en la forma que comúnmente se lo llama, la “repo” del proyecto: el espacio donde Git va a seguir un control del progreso de los cambios.

Otra cosa importante es considerar que git rastrea los datos de todos los subdirectorios que contenga la repo. Puede iniciarse git en un directorio que no contiene ningún archivo, como en el caso de nuestro ejemplo, pero también puede hacerse en un caso donde ya hay documentos creados.

¿Qué hacer luego de crear mi repo?

Es una buena pregunta, si se me permite decirlo.

Realmente no hay nada muy aparatoso en Git, por ahora voy a seguir con la terminal de comandos. Se requiere de algo de imaginación de nuestra parte para que todo funcione, pero no es nada más que ganar experiencia usándolo.

Como ya dije, en este momento me encuentro en la carpeta “ nuevo_tutorial”. Ahí es hacia donde apunta mi terminal.

Lo primero que voy a hacer es generar un nombre para mi cuenta, en mi caso ese nombre es Gustavo. Eso lo hago con el comando:

git config --global user.name Gustavo

Si agrego más de un nombre, es decir con un espacio en el medio, tengo que ponerlo entre comillas. Luego puedo revisar que ni nombre se haya agregado correctamente al sistema con el comando:

git config user.name

Recordemos que Git se usa también para trabajar en equipo, y aunque en este momento estoy trabajando solo, no es mala idea completar estos pequeños detalles. Por lo mismo puedo agregar un correo electrónico de referencia por medio de:

git config --global user.email “nombre del correo”

Y puedo revisar ese dato también con:

git config user.email

Comando muy similar al que utilicé para revisar el nombre de mi cuenta.

Sobre esto de poner un nombre y un correo, puede parecer un detalle sin importancia pero no lo es. Si queda mal puesto, puede generar un error más adelante en el que Git pide reconocernos una y otra vez… puedo decir que me lo experimenté, vuelvo sobre eso luego.

Pero para terminar con esta parte, tambien es posible configurar estos datos desde antes de iniciar la repo. E incluso se puede usar nombres de cuenta diferentes en distintas repos, si no usamos la opción «–global» al agregarlo.

Por otra parte, tambien podemos ver estos datos con el comando:

git config --global -e

Bueno, listo, basta de dar vueltas con esto del nombre.

Un editor de textos… tal vez sea una buena idea

Ya que estamos, tal vez es una buena oportunidad para abrir en paralelo una herramienta que nos permita trabajar con código. Alguna de estas herramientas pueden ser por ejemplo Atom, Visual Studio Code, VSCodium o alguna otra alternativa. Personalmente yo estoy utilizando VSCodium desde hace un tiempo, con excelentes resultados.

¿Por qué usar un editor de código si no lo necesitamos? Lo que ocurre es que, como el editor puede abrir nuestro documento de texto, la terminal de comandos y nuestros directorios a la vez, nos va a permitir descubrir la forma en que git funciona de manera dinámica. Por ejemplo, instantáneamente vamos a descubrir lo que ocurre cuando alternamos entre puntos de control o cuando ejecutamos un comando.

Es posible usar Git valiendonos solamente de la terminal de comandos, pero usarlo junto a un editor de textos como VSCodium facilita mucho el aprendizaje. Y además, hace las cosas mucho más faciles si estamos escribiendo en un lenguaje de programación, aunque no sea el caso de mi ejemlo.

Para entender todo esto lo mejor va a ser seguir avanzando.

Git, una vez más

Entonces ya abrí mi carpeta “nuevo_tutorial” en VSCodium. Y ya empecé mi nueva repo con el comando git init.

Tambien ya le di un nombre de usuario y un mail de referencia a mi cuenta.

A continuación voy a crear mi documento de texto, la pieza central de mi trabajo llamado “apunte.txt”, y voy a hacerlo con el siguiente comando:

touch apunte.txt

Si tu sistema operativo es Linux, vamos a estar usando algunos comandos una y otra vez. Si te interesa leer más sobre eso, tambien tengo una guía para empezar a utilizar la terminal.

Pero volviendo al tema, este nuevo documento de texto por ahora se encuentra sin contenido, aunque ya voy a remediar eso en unos minutos.

Mientras tanto ya puedo notar algo interesante. El editor de texto presenta el archivo apunte.txt en color verde. Y cuando pongo el puntero arriba del nombre del mismo me dice que se encuentra “untracked” o “sin rastrear”.

Lo que me da a entender que Git esta al tanto de la creación del documento, es un documento que no existía antes. Esto ocurre tanto utilice un editor como VSCodium o no, pero el editor hace que sea más sencillo notarlo.

Pero que todavía me quedan cosas por hacer para sacarle jugo a todo esto, recién estamos comenzando.

Empezar el seguimiento: pasando al nivel staged

Hasta este momento lo que hice fue hacer un cambio en mi repo. Uno muy pequeño, el de crear mi archivo de texto. O bueno, un cambio muy grande, depende de como quiera interpretarse la acción.

Voy a agregar algo de texto en “apunte.txt” para que no se sienta tan vacío:

Este es el primer renglón, para este apunte que forma parte de un ejemplo.

Ahora ya escribí algo en mi proyecto, y quiero que este sea un punto de control en la historia del documento. En el futuro tal vez quiera volver a empezar desde esta exacta primera frase, y quiero dejarlo señalado. Voy a necesitar usar algunos comandos extra para esto. Puede parecer difícil al principio pero al hacerlo se vuelve más fácil.

En resumen, Git tiene tres “momentos” (por llamarlos de algún modo) en el proceso de crear esos puntos de control. Estos tres momentos o niveles son los de: Modified, Staged y Commited.

Voy a ir avanzando por estos niveles a medida que voy aprendiendo.

Ahora me encuentro en lo que voy a considerar como el nivel uno, o el momento “modified”. El termino modified quiere decir modificado, e indica que existen cosas nuevas en la repo. Estas modificaciones pueden por ejemplo ser archivos nuevos, alterados o nuevo contenido en los documentos.

Como ya dije antes, estas modificaciones todavía no forman parte de ningún punto de control. Y el objetivo de todo esto es crear es crear esos puntos de control. Para hacerlo tengo que mover los cambios de “modified” al estado “staged”.

Según el manual tengo el siguiente comando:

git-status(1)
Show the working tree status.

Manual de Git

Lo que quiere decir es que, invocando esta comando, puede ver el estado de como van avanzando los cambios a través de los niveles en mi trabajo.

Entonces escribo:

git status

Y la terminal me devuelve:

On branch master
No commits yet
Untracked files:
(use "git add …" to include in what will be committed)
apunte.txt
nothing added to commit but untracked files present (use "git add" to track)

Voy a revisar lo de “On branch master” en mayor profundidad luego, pero como adelanto puedo saber que me esta diciendo que me encuentro en la rama principal de la repo.

Por otra parte “No commits yet” me confirma lo que ya conocía, que no hay todavía ningún commit creado en esta repo.
Lo más importante en este instante se encuentra analizando:

Untracked files:
(use "git add …" to include in what will be committed)
apunte.txt
nothing added to commit but untracked files present (use "git add" to track)

Bien, volviendo a lo anterior esto me informa que hay un archivo incluido a la repo (apunte.txt) pero que todavía esta “untracked” o sin seguimiento.

Y también me dice que hacer para pasarlo al nivel “staged”, que se podría pensar como “subirlo al escenario” o empezar a seguirlo usando el comando “git add”.
Voy a hacerlo:

git add apunte.txt

Nada parece ocurrir, pero si vuelvo a usar git status, la terminal me dice:

On branch master
No commits yet
Changes to be committed:
(use "git rm --cached …" to unstage)
new file: apunte.txt

Esto viene a decirme que el nuevo archivo apunte.txt ya esta siendo seguido. Según el manual:

git-add(1)
Add file contents to the index.

Manual de Git

El archivo fue agregado al índice. Recordemos que este es el paso previo al commit, aun no hay puntos de control creados.

También puedo remover de este nivel al documento con el comando:

git rm --cached apunte.txt

Hacer esto devuelve mi documento al estado sin seguimiento en el que se encontraba anteriormente, por fuera del nivel staged.

Commits: un nuevo punto de control

Por lo que entiendo hasta ahora, los cambios que hicimos en la repo están casi listos para entrar al tercer y último nivel. Ya casi son parte de los commits.

Estos commits son los puntos de control propiamente dichos. Similar a poner una marca en la hoja de un libro, para poder recuperar la lectura luego. Dejamos una marca en el camino, y podemos recuperarla para ver como estaba el proyecto en ese momento.

Para conseguir esto utilizo el comando que en la terminal aparece por:

git-commit(1)
Record changes to the repository.

manual de git

Lo que me dice el manual es que este comando guarda o graba los cambios en el repositorio. Es justo lo que necesito.

Otra cosa que puedo hacer, aunque es más bien una formalidad, es acompañar de la opción -m al comando para poder agregarle un comentario. Este comentario va a decir lo que hice con el archivo, y me va a servir como referencia para poder entender lo que hice con mayor facilidad. Esto resuelve lo que decía antes, cuando generaba muchos archivos de un mismo proyecto en una carpeta nunca terminaba de saber que es lo que había hecho en cada uno.

Entonces el comando terminado me queda:

git commit -m "[archivo apunte.txt creado y primer párrafo agregado]"

Si no funcionó bien, es posible que nos devuelve el error:

*** Please tell me who you are.
Run
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
to set your account's default identity.
Omit --global to set the identity only in this repository.

Es posible que olvidáramos agregar el nombre e nuestra cuenta al principio. Podemos hacerlo ahora, incluso omitiendo la opción “–global” para que el nombre solo aplique a este repositorio.

Lo siguiente que pudo pasar es que cuando originalmente intentamos agregar estos datos, escribimos el comando:

git config --global user.mail “nuestro correo”

En lugar de:

git config --global user.email “nuestro correo”

Sin agregar la “e” en “email”. Si, fue el primer error que cometí. Al volver a agregar mi correo agregando la letra flatante el problema se resolvió.

Listo, eso quedó solucionado.

Al salir todo bien, recibo por respuesta algo como:

[master (root-commit) 1c88802] [archivo apunte.txt creado y primer párrafo agregado]
1 file changed, 1 insertion(+)
create mode 100644 apunte.txt

Y principalmente me dice que un archivo fue cambiado (“apunte.txt” fue agregado) y que existió una inserción. Por esto entiendo que se refiere al primer párrafo que escribí en el texto.

Entonces con el comando “git commit” conseguí hacer mi punto de control. Pero hasta este momento este es mi único commit, por lo que no puedo moverme entre ellos. Voy a agregar un párrafo más a mi “apunte.txt” y luego voy a generar otro commit para luego poder alternar entre los mismos.

Entonces escribo:

Este es el segundo párrafo para un ejemplo bastante poco creativo de lo que es la creación de un apunte.

Pero esto ya lo revisé antes, no puedo hacer el commit directamente sin antes pasar por el nivel de staged. Entonces si hago:

git status

Me dice que:

On branch master
Changes not staged for commit:
(use "git add …" to update what will be committed)
(use "git restore …" to discard changes in working directory)
modified: apunte.txt
no changes added to commit (use "git add" and/or "git commit -a")

Una vez más hay un cambio que agregar, por el nuevo párrafo. Por eso vuelvo a pasar al documento al nivel de staged con el comando:

git add apunte.txt

Alternativamente si tuviera que registrar cambios en múltiples documentos en lugar de uno solo, puedo escribir

git add .

El punto funciona como una wildcard global, que incluye a todos los archivos que pueden ser movidos a staged dentro de la repo.

Y ahora si hago el commit con:

git commit -m "[segundo párrafo agregado en apunte.txt]"

Lo que sigue es revisar que commits existe en esta repo. Eso lo hago con el comando git-log, del que el manual me dice:

git-log(1)

Show commit logs.

Manual de Git

Este comando nos muestra un registro de los commits. Entonces escribo en la terminal:

git log

Y me devuelve:

commit e8a0d1bae50 (HEAD -> master)
Author: Gustavo <Gustavo@mail>
Date:   Fri Oct 7 23:54:07 2022 -0300
    [segundo párrafo agregado en apunte.txt]

commit 1c88802a587
Author: Gustavo <Gustavo@mail>
Date:   Fri Oct 7 23:34:36 2022 -0300
    [archivo apunte.txt creado y primer párrafo agregado]

Y ahí me aparecen de forma descendente los dos puntos de control que hice. Cada uno tiene su propio registro particular, el nombre de cuenta y el comentario explicativo que lo acompaña.

Con todo esto completado, puedo tomar un pequeño descanso y volver luego con…

Más commits, nuevos y no tan nuevos

¿En qué momento hacer un nuevo commit? Hoy me encuentro realizando estos puntos de control según los ejemplos me lo demanda, para poder entender como funcionan.

De hecho, al guardar un documento voy a notar que si uso el comando “git status”, Git me avisa que hay cambios realizados. Estos cambios fueron guardados en el archivo, guardados por medio del programa que estoy utilizando para trabajar. Pero estos todavía no agregados todavía al commit, no forman parte aun de ningún punto de control.

Guardar algo y crear un commit no es lo mismo, tengo que pensar en eso. Más aun, puedo guardar varias veces, agregar algunas de esas modificaciones al nivel staged y luego todas dentro de un commit.

Solo coincide que hasta ahora solo estoy haciendo un cambio por commit. Y hasta ahora no me metí a hablar sobre las “ramas”, algo que va a ampliar esto mucho más.

Pero lo que ahora me interesa es conocer como moverme entre estos commits, para poder usarlos efectivamente como una linea de tiempo que puedo ver.

No voy a repasar de nuevo los pasos por los tres niveles, pero si voy a agregar otro párrafo: Bueno, si voy a pasar por los tres niveles. No esta de más repasarlo.

El primer nivel ocurre cuando hago un cambio, en mi caso agrego un nuevo párrafo:

Un nuevo párrafo, no muy original pero si muy valioso.

El segundo nivel ocurre cuando paso ese cambio al nivel “staged”. Es decir, cuando subo (por expresarlo de algún modo) lo guardado al escenario y lo preparo para que Git lo tenga en cuenta.

Eso lo consigo con el comando:

git add apunte.txt

Y para finalizar, el tercer nivel creando el commit. Para eso en mi caso utilizo este comando:

git commit -m "[tercer párrafo agregado]"

Reviso todos mis puntos de control hasta el momento con el comando:

git log

Ya tengo tres puntos de control, aunque lo que me devuelve este comando es algo difícil de leer. Puedo mejorarlo con el agregado de la opción “–oneline”, lo que va a conseguir que cada punto de control y comentario aparezca resumido en una única linea de texto.

git log --oneline

Y eso me devuelve:

c28fe45 (HEAD -> master) [tercer párrafo agregado]
e8a0d1b [segundo párrafo agregado en apunte.txt]
1c88802 [archivo apunte.txt creado y primer párrafo agregado]

Mucho más fácil de leer.

Entonces, voy a volver al primero de ellos: el momento en el que solamente había un párrafo creado. El código que necesito aparece al principio del log, en este caso es: 1c88802.

Puedo volver a este punto de control con el comando “git checkout”, que según el manual dice:

git-checkout(1)
Switch branches or restore working tree files.

manual de git

Lo que entiendo es que “checkout” me permite revisar un commit anterior. En principio solo revisarlo en modo lectua, no modificarlo ni abrir una rama nueva.

Para usarlo, le agrego el código de identificación del commit a revisar:

git checkout 1c88802

Y si reviso el texto, puedo ver que me esta mostrando el documento como lo tenía en ese párrafo.

Pero ocurren también otras cosas, cosas que van a traer nuevas oportunidades y que voy a considerar a continuación.

(Apunte en proceso de escritura, volvé luego para ver como sigue.)

Dejar una respuesta