🚀 Dominando GIT

Introducción a GIT
GIT es un sistema de control de versiones. Esto significa que es un sistema que registra los cambios realizados sobre un archivo o conjunto de archivos a lo largo del tiempo. Este tipo de sistemas nos permiten tener un control en el tiempo de nuestro trabajo.
Con GIT podemos controlar todos los cambios que realizados en nuestro código y así tener un control absoluto de todo lo que ocurre, permitiendo volver atrás en el tiempo, abrir diferentes ramas de desarrollo, etc.
Instalación
Se puede obtener GIT para su instalación en la página oficial de Git.
Configuración Inicial
Una vez que git ha sido instalado en nuestro sistema podemos establecer un nombre para identificar nuestros commits en los repositorios locales que tengamos.
git config --global user.name "[firstname lastname]"
Se puede también establecer una dirección de correo electrónico.
git config --global user.email "[valid-email]"
Y por último especificar un color automático de la línea de comando.
git config --global color.ui auto
Por último para revisar estas configuraciones tenemos el siguiente comando.
git config --global --list
Iniciando con Git
Cualquier carpeta de nuestro equipo puede ser un repositorio de git, para convertirlas en un repositorio se hace uso del comando siguiente:
git init
Este comando activa git en la carpeta que será nuestro proyecto y crea un espacio en memoria RAM llamado staging y una carpeta .git que es la encargada de mantener el estado de proyecto de manera local.
Del diagrama anterior podemos rescatar los siguientes conceptos:
- Carpeta del proyecto. Es donde trabajamos de manera local.
-
Staging. Es el lugar donde se guardan temporalmente los cambios, para a través de un
git commitser enviados al repositorio remoto en donde se guardarán definitivamente - Repositorio (.git). Es donde se guarda el historial de cambios de nuestros archivos.
Dentro del sistema de git existen cuatro estados para los archivos:
- Untracket. El archivo no está en git, sólo se encuentra en la carpeta del proyecto, o sea en el disco duro.
- Unstaged. Son archivos que git tiene dentro de su registro de sus cambios pero que se encuentran desactualizados.
-
Staged. Archivos que han sido enviados al staging con el comando
git add. - Tracket. Los archivos que se encuentran registrados en el repositorio, están actualizados y no tienen cambios pendientes.
Una vez que tenemos creado nuestro repositorio podemos empezar a trabajar con el y las acciones básicas que podemos realizar son:
→ Mostrar cuales son los archivos que tienen cambios o son nuevos en el directorio en el que se trabaja.
git status
# Se muestra sólo la información de los archivos afectados
git status -s
# Además muestra la branch actual
git status -sb
→ Añadir los archivos justo como están en este momento al próximo commit.
git add [file]
# Se agregan todos los archivos en el stage
git add *
# Se agregan los archivos con la extensión especificada
git add *.[extension]
# Se agregan todos los archivos dentro de la carpeta especificada
git add /[folder]
→ Realiza el un commit para guardar los cambios actuales del repositorio.
git commit -m "[descriptive message]"
# Hace el commit y añade los archivos solo para archivos que ya tengan un add previo
git commit -am "[descriptive message]"
→ Remover archivos del staged.
git reset HEAD
→ Mostrar el historial de commits del repositorio.
git log
Cambios en los Archivos
Git nos permite analizar los cambios en los archivos de cada proyecto y para esto tenemos principalmente dos comandos.
→ Mostrar los cambios existentes de un archivo.
git show [file]
Este comando es útil cuando queremos identificar cuando se realizaron los cambios recientes de un archivo y en caso de existir un error en el código poder solucionarlo.
→ Mostrar las diferencias entre una versión y otra de un archivo.
git diff commitA commitB
La respuesta de este comando serán las diferencias entre las versiones del commitA y el commitB del archivo.
Ramas
La base de GIT es el uso de ramas (branch), ya que desde que se inicia el repositorio se crea la rama principal con el nombre por defecto master.
Se entiende por rama a una representación lineal de los distintos commits en un periodo de tiempo. Es posible crear una rama para realizar modificaciones a nuestro código son afectar a la rama principal.
Un repositorio con diferentes branches podría ser representado de la siguiente forma.
Los comandos que podemos utilizar para trabajar con las ramas dentro de git son:
→ Lista todas las ramas disponibles.
git branch
→ Crear una nueva branch en el commit actual.
git branch [branch-name]
→ Cambia a otra branch.
git checkout [branch-name]
# *También crea una branch nueva y accede a ella directamente*
git checkout -b [branch-name]
Es importante que antes de hacer un checkout a otra rama, hagamos un add commit al trabajo actual para no perder los cambios.
El comando merge nos permite fusionar dos ramas. Esto se realiza una vez que ya terminamos de hacer cambios en una rama y deseamos por ejemplo integrarlos al master.
→ Une la branch seleccionada con otra branch.
git merge [branch]
→ Eliminar una rama.
git merge -d [branch-name]
# Con -D se fuerza el borrado
git branch -D [branch-name]
Las ramas en git son importantes porque nos permiten independizar los cambios en un proyecto de tal forma que se puedan realizar avances optimizando el tiempo y el orden, además nos permite fusionar dichos cambios sin perder registro de las versiones anteriores.
Viajes en el Tiempo
Una de las características más importantes de git es la capacidad de volver en el tiempo a estados anteriores de nuestro repositorio.
Uno de los comandos que nos ayuda a volver en el tiempo es reset, el cual es un comando peligroso ya que volvemos al pasado sin la posibilidad de volver al futuro ya que borramos todo el árbol de commits hasta el punto en el volvemos.
Hay dos formas de usar este comando, una es con el argumento --hard, el cual borra toda la información que tengamos en el área de staging o usando el argumento --soft, que mantiene allí los archivos del área de staging para que podamos aplicar nuestros últimos cambios pero desde un commit anterior.
→ Permite regresar al commit especificado. Limpia el staging area.
git reset --hard [commit-id]
→ Permite regresar al commit especificado. No limpia el staging area.
git reset --soft [commit-id]
A diferencia del reset que nos borra todo el historial de commits, tenemos el comando checkout que nos deja ir, mirar, pasear y volver sin afectar nuestro árbol de commits.
→ Restaurar una versión previa de un archivo
git checkout [commit-id] [file]
Eliminando Archivos
Git también tiene su propio comando para eliminar archivos sin eliminar el historial de dicho archivo. Esto quiere decir que si necesitamos recuperar el archivo solo debemos “viajar en el tiempo” y recuperar el último commit antes de borrar el archivo en cuestión.
Este comando es rm y hay dos formas de usarlo, con --cached que elimina los archivos del repositorio pero los mantiene en nuestro disco duro y con --forced el cual elimina los archivos tanto de git como del disco duro.
→ Eliminar archivos del repositorio, pero mantenerlos en el disco duro.
git rm --cached [file]
→ Eliminar archivos del repositorio y del disco duro.
$ git rm --forced [file]
Repositorio Remoto
Un flujo de trabajo dentro de git permite realizar el trabajo de forma uniforme y productiva.
Cuando sólo tenemos un repositorio local nuestro proyecto vive únicamente en nuestra computadora por lo que no hay forma de que otras personas colaboren en el.
Una de las principales característica de git es ser colaborativo podemos utilizar los servidores remotos, esto se consideraría un nuevo estado dentro del flujo actual de nuestro proyecto. La descripción gráfica de esto es la siguiente:
Alguno servidores remotos conocidos son: GitHub, GitLab, Bitbucket; y su función es guardar el historial de nuestro repositorio de manera remota y brindarnos un modo de acceso a través de una URL o una llave SSH. Además de permitirnos otras opciones como colaborar con grupos de trabajo, crear ramas, hacer solicitudes de integración, y muchas cosas más.
Para detallar en el uso de los comando utilizaremos a GitHub como ejemplo, ya que no solo es un sistema de gestión de proyectos, sino la red social predilecta para desarrolladores. En general el sistema permite trabajar en colaboración con otras personas de todo el mundo, planificar proyectos y realizar un seguimiento del trabajo. Así mismo es también uno de los repositorios online más grandes de trabajo colaborativo en todo el mundo.
→ Subir un repositorio local a uno remoto.
git remote add origin [url-proyecto]
→ Clonar un repositorio remoto en mi local.
git clone [url-proyecto]
→ Actualizar el repositorio local.
git pull
# *Indicando la rama que se va a actualizar*
git pull origin master
# *Fuerza cambios cunado no hay commits relacionados*
git pull origin master --alow-unrelated-histores
→ Actualizar el repositorio remoto.
git push origin master
Alias
Los alias dentro de git nos permiten crear shorcuts de nuestros comandos más usados. Por ejemplo para obtener un log del repositorio que me permita ver los movimientos entre ramas de forma gráfica deberíamos de usar este comando.
git log --all --graph --decorate --oneline
Pero al ser un comando muy largo de escribir y posiblemente difícil de recordar podemos asignarle un alias de la siguiente manera.
git config --global alias.lg "log --all --graph --decorate --oneline"
Y con esto la próxima vez que deseemos obtener los logs de esa forma sólo tendremos que escribir en nuestra terminal:
git lg
Rebase
La reorganización es el proceso de mover o combinar una secuencia de commits en una nuevo commit base. Esto es muy útil y se visualiza fácilmente en el contexto de un flujo de trabajo de ramas de funciones.
git rebase [branch]
El proceso general se puede visualizar de la siguiente manera:
Desde una perspectiva de contenido, el rebase consiste en cambiar la base de la rama de un commit a otro haciendo que parezca que se ha creado una rama desde un commit diferente.
Es importante entender que, aunque la rama parezca la misma se compone de nuevos commits por completo.
Stash
¿Qué pasa cuando estamos trabajando en la rama A y repentinamente tenemos que movernos a la rama B pero no queremos perder los cambios que tenemos en A pero tampoco hacer un commit porque el código aún esta a medidas?
Para estos casos tenemos el stash. Pero ahora surge otra pregunta ¿Qué es Stash?
Empecemos por explicar que se trata de un comando que congela el estado en el que se encuentra el proyecto en un momento determinado con todos los cambios que tenemos sin commit, y lo guarda en una pila provisional brindándonos las posibilidad de poder recuperarlo más adelante.
→ Creando un stash (salva los cambios y restaura el último commit).
git stash
git stash save
# Agrega un mensaje que se puede visualizar cuando se listan las entradas
git stash save "Mensaje deseado"
→ Restaurar registros.
git stash apply
# *Restaura un registro en específico*
git stash apply stash@{1}
→ Listar todas las entradas en el stash.
git stash list
→ Se saca el último stash para unirlo a la branch.
# *Restaura y borra la primera entrada que hay listada*
git stash pop
# *Restaura y borra una entrada en específico*
git stash pop stash@{1}
→ Elimina el stash.
# *Elimina el primer stash de la lista*
git stash drop
# *Elimina el stash indicado*
git stash drop stash@{1}
→ Guardar todo menos los archivos del stage.
git stash save --keep-index
→ Incluir todos los archivos junto a los que git no les da seguimiento (.gitignore).
git stash save --include-untracked
→ Mostrar información de los cambios en el stash.
# *Primer stash listado*
git show stash
# *Stash en específico*
git show stash stash@{1}
→ Borrar todas las entradas del stash.
git stash clear
Limpiar el Repositorio
Mientras estamos trabajando en un repositorio podemos añadir archivos a él, que realmente no forma parte de nuestro directorio de trabajo, archivos que no se deberían de agregar al repositorio remoto.
El comando clean actúa en archivos sin seguimiento, este tipo de archivos son aquellos que se encuentran en el directorio de trabajo, pero que aún no se han añadido al índice de seguimiento de repositorio con el comando add.
git clean
La ejecución del comando predeterminado puede producir un error. La configuración global de Git obliga a usar la opción force con el comando para que sea efectivo. Se trata de un importante mecanismo de seguridad ya que este comando no se puede deshacer.
→ Revisar que archivos no tienen seguimiento.
git clean --dry-run
→ Eliminar los archivos listados de no seguimiento.
git clean -f
Reconstrucción de Commits
Si el último commit que hicimos tenía un error, por ejemplo de ortografía o quizá se nos olvidó agregar algo al código de ese commit podemos darle solución con el siguiente comando.
→ Modificar el mensaje del commit más reciente.
git commit --amend
→ Modificar el commit más reciente y su mensaje en la misma línea.
git commit --amend -m
Recordar que -m permite escribir un mensaje desde la línea de comandos sin tener que abrir un editor.
→ Modificar el commit sin modificar el mensaje de dicho commit.
git commit --amend --no-edit
El indicador --no-edit permite hacer correcciones el el código sin modificar el mensaje original.
Este comando es una manera práctica de modificar la información más reciente de nuestro repositorio.
No utilizar --amend para reconstruir commits que ya se encuentran en el repositorio remoto. Esto sería una mala práctica.
Reflog
Los registros de referencia también llamados reflogs son una funcionalidad de git que registra todos los eventos del repositorio. Cada vez que el extremo de tu rama se actualiza por cualquier motivo, se añade una nueva entrada a este registro.
→ Mostrar el registro.
git reflog
→ Mostrar el registro relativo a la fecha especificada.
git reflog --relative-date
Reset
Este comando borra toda la información de nuestra rama hasta el punto que le especifiquemos. La invocación predeterminada tiene argumentos implícitos, como lo detallo a continuación:
→ Invocación predeterminada del comando
git reset
→ Invocación con sus argumentos implícitos.
git reset --mixed HEAD
En vez de HEAD, se puede usar cualquier HASH de commit de git.
Además del argumento --mixed tenemos otros dos que son --hard y --soft.
Ahora, detallando un poco cada uno de los argumentos tendríamos lo siguiente:
-
--hard→ Esta es la opción más peligrosa aunque es la que se usa más frecuentemente. Con esta opción todo el trabajo que se encuentra en el staged se pierde y la cabecera de nuestro repositorio apuntará al commit indicado olvidándose de todo lo que sucedió después de ese commit. -
--mixed→ Este es el modo de funcionamiento predeterminado. Se actualizan los punteros del repositorio y todos los cambios que se hayan deshecho en el índice del entorno de ensayo e mueven al directorio de trabajo. -
--soft→ En esta opción a diferencia de la primera todo lo que estaba en el staged se conserva, únicamente actualiza la cabecera del repositorio al commit indicado.
Busqueda
Git permite buscar palabras claves dentro del repositorio. Este comando es el grep y se puede utilizar de la siguiente manera.
→ Buscar una palabra clave
git grep [palabra]
→ Buscar la palabra clave especificando en qué línea se encuentra.
git grep -n [palabra]
→ Buscar la palabra clave especificando cuantas veces se uso dicha palabra en el repositorio.
git grep -c [palabra]
→ Buscar la palabra clave sólo en los commits.
git log -s [palabra]
Uhuuh! Si llegaste hasta aquí gracias por leer el artículo. El contenido del mismo es lo que yo considero las bases y un poquito más para ser un dios en git. Como sabemos manejar estar herramienta siendo dev es un obligado casi siempre por no decir siempre.
Este resumen fue escrito en colaboración con Manuel Gil que es miembro de los Undefined Dev, la cual es una comunidad bastante bonita para que vayan a seguirlos a ambos.
Y terminando con la pausa publicitaría eso es todo, este artículo tendrá una segunda parte ya enfocado en los repositorios en la nube, esperenlo pronto 👌🏻






