En las partes anteriores vimos el control de versiones en local y el trabajo con ramas. En este último capítulo damos el salto a los **repositorios remotos**, creamos **alias** para ir más rápido, guardamos cambios sin comprometerlos con el **stash** y marcamos versiones con **tags**. 🎸 💾 #GITandRoll
📚 **Esta entrada es parte de la serie _Guía de Git_**, dividida en tres capítulos que se leen en orden:
> * Parte 1: Control de versiones en local
* Parte 2: Ramas
* 👉 **Parte 3: Repositorios remotos, stash y tags**
Trabajando con repositorios remotos
Cuando desarrollamos software no lo solemos hacer solos, solemos trabajar en equipo, por lo que no tiene sentido tener un repositorio local de git, sino tener un repositorio remoto con el que todos trabajemos y compartamos los avances
Nota: El objetivo de este post es explicar git. Para la conexión con repositorios remotos voy a explicarlo con GitHub porque es el servicio de hosting de repositorios git más usado, pero no voy a entrar en profundidad en GitHub
Clonar un repositorio remoto (git clone <repositorio>)
Si empezamos a trabajar en un repositorio que ya ha sido creado, lo primero que tenemos que hacer es clonarlo, para ello lo que tenemos que hacer es git clone <repositorio>, donde <repositorio> puede ser una URL o una dirección SSH. Como ahora mismo todo el tema de los grandes modelos de lenguaje y ChatGPT están muy de moda, vamos a clonar un repositorio opensource creado por la comunidad, Open-Assistant, para ello haremos git clone https://github.com/LAION-AI/Open-Assistant
InputPython!git clone https://github.com/LAION-AI/Open-Assistant.gitCopied
Clonando en 'Open-Assistant'...remote: Enumerating objects: 29769, done.remote: Counting objects: 100% (673/673), done.remote: Compressing objects: 100% (310/310), done.remote: Total 29769 (delta 398), reused 577 (delta 354), pack-reused 29096Recibiendo objetos: 100% (29769/29769), 33.61 MiB | 29.29 MiB/s, listo.Resolviendo deltas: 100% (19967/19967), listo.
Esto nos crea la carpeta Open-Assistant con todo el código del repositorio, podemos entrar adentro y ver todo el código
InputPython!cd Open-Assistant && lsCopied
ansible deploy model safetyassets discord-bots notebooks scriptsbackend docker oasst-data setup.cfgCODEOWNERS docker-compose.yaml oasst-shared text-frontendCONTRIBUTING.md docs pyproject.toml websitecopilot inference README.mddata LICENSE redis.conf
Eliminó la carpeta
InputPython!rm -r Open-AssistantCopied
Enlazar un repositorio local en uno remoto
Si ocurre al revés, si primero empezamos a desarrollar en local y luego lo queremos sincronizar con un repositorio remoto, tenemos que hacer lo siguiente
- Primero crear un repositorio remoto vacío, en mi caso he creado el repositorio
notebook_giten GitHub que más tarde borraré - Obtener la URL del repositorio o dirección SSH
- Sincronizarlos mediante
git remote add origin <URL>
El repositorio vacío que he creado en GitHub se ve así
En mi caso voy a usar la dirección SSH que es git@github.com:maximofn/notebook_git.git
InputPython!cd notebook_git && git remote add origin git@github.com:maximofn/notebook_git.gitCopied
Ya están enlazados, pero para asegurarnos podemos hacer git remote -v
InputPython!cd notebook_git && git remote -vCopied
origin git@github.com:maximofn/notebook_git.git (fetch)origin git@github.com:maximofn/notebook_git.git (push)
Subir los cambios de un repositorio local a un repositorio remoto (git push)
Como hemos dicho, están enlazados, pero si voy a mi repositorio en GitHub se sigue viendo así
Están enlazados el repositorio local y el remoto, pero ahora hay que mandar todos los cambios del repositorio local al remoto, para ello habría que usar git push origin <rama local>:<rama remota>, es decir, como nuestra rama principal se llama main y la rama principal en GitHub se llama main habría que hacer git push origin main:main.
Si te acuerdas git por defecto llamaba a la rama principal master, pero GitHub llama por defecto a la rama principal main por lo que si cada persona llama en su repositorio local a sus ramas de una manera hay que especificar qué rama en local escribe a qué rama en remoto
Se puede configurar la conexión por defecto entre ramas en git, para ello hay que hacer git push --set-upstream origin main. Esto establece relación entre la rama local main y la rama remota main. Una vez hecha esta relación ya solo es necesario hacer git push para subir los cambios que se hacen en local al servidor remoto.
De modo que establecemos la conexión entre ramas
InputPython!cd notebook_git && git push --set-upstream origin mainCopied
Enumerando objetos: 51, listo.Contando objetos: 100% (51/51), listo.Compresión delta usando hasta 12 hilosComprimiendo objetos: 100% (38/38), listo.Escribiendo objetos: 100% (51/51), 4.21 KiB | 2.11 MiB/s, listo.Total 51 (delta 18), reusado 0 (delta 0)remote: Resolving deltas: 100% (18/18), done.To github.com:maximofn/notebook_git.git* [new branch] main -> mainRama 'main' configurada para hacer seguimiento a la rama remota 'main' de 'origin'.
Ahora ya podemos hacer solo git push para subir los cambios locales al repositorio remoto
InputPython!cd notebook_git && git pushCopied
Everything up-to-date
Si ahora volvemos a nuestro repositorio de GitHub, se ve así
Si hacemos un ls en nuestro repositorio local podremos ver que los archivos que tenemos en el repositorio remoto los tenemos en el repositorio local, es decir, hemos sincronizado el repositorio local y remoto
InputPython!cd notebook_git && ls -aCopied
. .. api_keys.py archivo1.py archivo2.py archivo8.py .git .gitignore
Los únicos que no están en el repositorio remoto son api_keys.py, que es el que añadimos al archivo .gitignore, es decir, el que dijimos a git que no siguiera. Y .git, que es donde está la configuración de nuestro repositorio local y que no se tiene que subir al repositorio remoto, porque cada persona tendrá su propia configuración de git y por tanto no se tiene que sincronizar
Descargar los cambios de un repositorio remoto a un repositorio local (git pull)
Ahora vamos a hacer al revés, vamos a bajar los nuevos cambios que se hayan hecho en el repositorio remoto. Si nos fijamos en cómo está el repositorio remoto podremos ver que hay un botón que pone Add a README, por lo que le damos para añadirlo
Al hacer clic se nos abrirá un editor, dejamos lo que ha puesto GitHub y guardamos los cambios dándole al botón de Commit changes...
Nos saldrá una ventana en la que nos pedirá un mensaje de commit, dejamos el que viene por defecto y le damos a Commit changes
Al hacer eso el repositorio se nos quedará así
Se ha creado un nuevo archivo llamado README.md, pero si hacemos ls en el repositorio local no lo encontraremos
InputPython!cd notebook_git && ls | grep READMECopied
Por lo que nos tenemos que traer los cambios del repositorio remoto al local, para ello hay que hacer git pull origin <rama remota> para decirle a git sobre qué rama remota vamos a traer los datos, pero al igual que antes podemos establecer una relación entre la rama remota y la rama local de la siguiente manera git branch --set-upstream-to=origin/<rama local> <rama remota>, pero como nuestra rama local se llama main y la rama remota de GitHub la llama main habría que cambiar lo anterior por git branch --set-upstream-to=origin/main main.
Una vez hecho esto para descargar los nuevos cambios del repositorio remoto al local solo habría que hacer git pull
Vamos a establecer la relación entre ramas con git branch --set-upstream-to=origin/main main
InputPython!cd notebook_git && git branch --set-upstream-to=origin/main mainCopied
Rama 'main' configurada para hacer seguimiento a la rama remota 'main' de 'origin'.
Ahora podemos traer los cambios del repositorio remoto al repositorio local con git pull
InputPython!cd notebook_git && git pullCopied
remote: Enumerating objects: 4, done.remote: Counting objects: 100% (4/4), done.remote: Compressing objects: 100% (2/2), done.remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0Desempaquetando objetos: 100% (3/3), 646 bytes | 646.00 KiB/s, listo.Desde github.com:maximofn/notebook_git679bb49..527e07a main -> origin/mainActualizando 679bb49..527e07aFast-forwardREADME.md | 1 +1 file changed, 1 insertion(+)create mode 100644 README.md
Como vemos, dice que se ha añadido README.md, lo comprobamos haciendo ls
InputPython!cd notebook_git && ls | grep READMECopied
README.md
Tenemos el archivo en local
Sincronizar las ramas remotas y locales
Como hemos visto, hemos tenido que sincronizar las ramas remotas y locales para poder subir y bajar los datos. Sin embargo, si primero creamos el repositorio en GitHub y después lo clonamos, ya no es necesaria dicha sincronización.
Alias
Cada vez que hemos querido hacer un log hemos usado este comando git log --graph --oneline --decorate, sin embargo acordarse de este comando es bastante complicado, de hecho yo no me acuerdo de él, cada vez que lo he querido usar lo he tenido que buscar porque no lo recordaba, por lo que estaría muy bien tener una manera de abreviarlo.
Para esto git ofrece los alias, de manera que puedes crearte alias de los comandos que tú quieras, para ello tienes que hacer git config --global alias.<nombre del alias> "comando"
Por tanto vamos a llamar git tree al comando git log --graph --oneline --decorate, ya que nos permite ver el historial, con la bifurcación y fusión de ramas como si fuese el crecimiento de un árbol, por lo que hacemos git config --global alias.tree "log --graph --oneline --decorate"
**Importante**: No hay que poner la palabra
gitdentro del comando
InputPython!git config --global alias.tree "log --graph --oneline --decorate"Copied
Si ahora nos vamos a nuestro repositorio y hacemos git tree veremos el historial como lo hacíamos antes
InputPython!cd notebook_git && git treeCopied
* 527e07a (HEAD -> main, origin/main) Create README.md* 679bb49 archivo1.py con el merge resuelto|\| * 32851c3 archivo1.py en rama rama_con_conflicto* | 53f909b archivo1.py en rama main|/* 52acb97 Merge squash de los commits de la rama branch_squash* 274529c Merge branch 'branch_no_fast_forward' into main|\| * 8df3429 (branch_no_fast_forward) file2| * e4e23c9 file1* | 8bdf4d8 file3|/* 94149fc (branch_fast_forward) Eliminado hola.py* 4484e70 Eliminado archivo4.py* 564ccfb (new_branch2) Commit con el archivo 8* 5168f78 Eliminado archivo7.py* 4bb9d75 (new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py
Como vemos, se ha creado nuestro alias
Alias de comandos existentes de git
Se pueden crear alias de comandos que ya existen en git, de hecho, es una práctica que usa mucha gente, sobre todo para abreviar, por lo que vamos a hacer uno. Vamos a hacer un alias del comando git status y lo vamos a renombrar como git st de la siguiente manera git config --global alias.st "status"
InputPython!git config --global alias.st "status"Copied
Lo probamos ahora
InputPython!cd notebook_git && git stCopied
En la rama mainTu rama está actualizada con 'origin/main'.nada para hacer commit, el árbol de trabajo está limpio
Ya tenemos el comando git status simplificado a git st
Alias de comandos que no son de git
Podemos crearnos alias de comandos que no sean de git, por ejemplo, porque creamos que git necesita ese nuevo comando, se hace igual con la excepción de que el comando tiene que ir precedido de !, es decir, sería git config --global alias.<nombre del alias> "!comando"
Cuando hemos visto los conflictos, hemos visto que git nos decía dónde estaban, pero para solucionarlos tenemos que editar el código nosotros mismos, por lo que podemos crear un alias de git de manera que podamos abrir un archivo con el editor de textos que queramos, en mi caso voy a crear un alias que me abrirá los archivos con vscode para ello tengo que hacer git config --global alias.code "!code"
InputPython!git config --global alias.code "!code"Copied
Lo probamos
InputPython!cd notebook_git && git code README.mdCopied
Tras hacer esto, se me ha abierto README.md en VSCode
Lista con todos los alias
En caso de no acordarnos de los alias que hemos creado podemos ver la configuración global de git, pero como esto puede ser un poco abrumador porque nos da mucha información, podemos filtrar para que nos muestre solo los alias que hemos creado, para ello usamos git config --get-regexp ^alias\.
InputPython!git config --get-regexp ^alias.Copied
alias.tree log --graph --oneline --decoratealias.st statusalias.code !code
Obtenemos los alias que hemos creado
Pero aún mejor, podemos crear un alias para obtener los alias, para ello hacemos git config --global alias.alias "config --get-regexp ^alias\."
InputPython!git config --global alias.alias "config --get-regexp ^alias."Copied
Si ahora hacemos git alias
InputPython!git aliasCopied
alias.tree log --graph --oneline --decoratealias.st statusalias.code !codealias.alias config --get-regexp ^alias.
Obtenemos la lista con todos nuestros alias
Almacén stash (git stash)
Supongamos que estamos trabajando en una rama, tenemos varios archivos modificados, no hemos hecho commit, y por la razón que sea tenemos que pasar a otra rama. Por ejemplo, estamos en una rama desarrollando una nueva funcionalidad, y la tenemos que dejar a medias porque hay un bug crítico en la rama main
Una solución sería hacer un commit para guardar los cambios y volver más adelante. Pero a lo mejor hemos dejado el código a medias y no queremos hacer un commit. Así que para ello se inventó el stash, que es como un almacén, donde dejas almacenado tu código para luego poder volver a recuperarlo.
Es una pila, eso quiere decir que lo último que entra es lo primero en salir
Veamos cómo hacerlo, en primer lugar, creamos una nueva rama que vamos a llamar new_feature
InputPython!cd notebook_git && git branch new_featureCopied
Cambiamos a ella
InputPython!cd notebook_git && git switch new_featureCopied
Cambiado a rama 'new_feature'
Vamos a modificar archivo2.py y archivo8.py
InputPython!cd notebook_git && echo "print('new_feature')" >> archivo2.py && echo "print('new_feature')" >> archivo8.pyCopied
Hacemos un git status para comprobar que se hayan modificado
InputPython!cd notebook_git && git statusCopied
En la rama new_featureCambios no rastreados para el commit:(usa "git add <archivo>..." para actualizar lo que será confirmado)(usa "git restore <archivo>..." para descartar los cambios en el directorio de trabajo)modificados: archivo2.pymodificados: archivo8.pysin cambios agregados al commit (usa "git add" y/o "git commit -a")
Vamos a meter a archivo8.py al área de staged
InputPython!cd notebook_git && git add archivo8.pyCopied
Volvemos a hacer un git status
InputPython!cd notebook_git && git statusCopied
En la rama new_featureCambios a ser confirmados:(usa "git restore --staged <archivo>..." para sacar del área de stage)modificados: archivo8.pyCambios no rastreados para el commit:(usa "git add <archivo>..." para actualizar lo que será confirmado)(usa "git restore <archivo>..." para descartar los cambios en el directorio de trabajo)modificados: archivo2.py
Como vemos tenemos dos archivos modificados, de los cuales uno de ellos además está en el área de staged. Si ahora tuviésemos que cambiar de rama, para no perder los cambios podríamos hacer un commit, o guardarlos en el almacén stash, así que vamos a hacer esto último mediante git stash
InputPython!cd notebook_git && git stashCopied
Directorio de trabajo y estado de índice WIP on new_feature: 527e07a Create README.md guardados
Si ahora volvemos a hacer git status, veamos qué pasa
InputPython!cd notebook_git && git statusCopied
En la rama new_featurenada para hacer commit, el árbol de trabajo está limpio
Ya no aparecen los archivos con modificaciones, es como si hubiéramos hecho un commit
**Importante**: Los archivos nuevos creados, que nunca han sido seguidos por Git, no se irán al almacén, por lo que con los archivos nuevos es necesario, al menos, hacer primero un
git add
Si yo ahora creo un archivo nuevo y lo intento llevar al almacén, me dará un error
InputPython!cd notebook_git && touch archivo9.pyCopied
InputPython!cd notebook_git && git statusCopied
En la rama new_featureArchivos sin seguimiento:(usa "git add <archivo>..." para incluirlo a lo que se será confirmado)archivo9.pyno hay nada agregado al commit pero hay archivos sin seguimiento presentes (usa "git add" para hacerles seguimiento)
InputPython!cd notebook_git && git stashCopied
No hay cambios locales para guardar
InputPython!cd notebook_git && git statusCopied
En la rama new_featureArchivos sin seguimiento:(usa "git add <archivo>..." para incluirlo a lo que se será confirmado)archivo9.pyno hay nada agregado al commit pero hay archivos sin seguimiento presentes (usa "git add" para hacerles seguimiento)
Como vemos archivo9.py no lo ha guardado en el almacén, por lo que habría que haberlo añadido con git add.
InputPython!cd notebook_git && rm archivo9.pyCopied
Todo al almacén stash (git stash -u -a)
Como hemos visto solo se mandan al almacén los archivos a los que git les está haciendo seguimiento, pero si tenemos nuevos archivos creados, o archivos ignorados, no se mandarán, así que para solucionar esto podemos usar los flags -u o --include-untracked para que manden los nuevos archivos a los que git aún no ha hecho seguimiento, y el flag -a o --all para incluir todo, incluso los archivos ignorados
Lista de almacenes (git stash list)
Como hemos comentado, el almacén actúa como una pila, por lo que si hacemos uso de este almacén muchas veces, en realidad vamos a tener una lista de almacenes, y para ver los que tenemos almacenados podemos usar git stash list
InputPython!cd notebook_git && git stash listCopied
stash@{0}: WIP on new_feature: 527e07a Create README.md
Como vemos, solo tenemos una, que nos indica la rama (on new_feature), el último commit (Create README.md) y un identificador (527e07a)
Almacén con descripción (git stash push -m <descripción>))
Como hemos visto, la lista nos devuelve la rama y el último commit, pero esta información solo nos vale para saber desde dónde hemos empezado a modificar antes de guardar en el historial. Además nos devuelve un identificador que no nos dice mucho, así que podemos añadir una primera descripción al stash con git stash push -m <descripción>
Primero hacemos un git status para ver qué tenemos sin commitear
InputPython!cd notebook_git && git statusCopied
En la rama new_featureArchivos sin seguimiento:(usa "git add <archivo>..." para incluirlo a lo que se será confirmado)archivo9.pyno hay nada agregado al commit pero hay archivos sin seguimiento presentes (usa "git add" para hacerles seguimiento)
Tenemos archivo9.py, pero recordemos que nunca ha sido seguido por git, por lo que para incluirlo en un stash tenemos que usar el flag -u o el flag -a, de modo que creamos un nuevo stash con una descripción con el comando git stash push -u -m <descripción>
InputPython!cd notebook_git && git stash push -u -m "archivo9.py"Copied
Directorio de trabajo y estado de índice On new_feature: archivo9.py guardados
Sacamos la lista del stash
InputPython!cd notebook_git && git stash listCopied
stash@{0}: On new_feature: archivo9.pystash@{1}: WIP on new_feature: 527e07a Create README.md
Ya aparece el nuevo de manera mucho más clara
Recuperar el último stash (git stash pop)
Como hemos dicho, el stash es una pila con almacenes, por lo que a la hora de recuperarlos lo haremos igual que una pila, recuperando siempre el último.
Para recuperar el último stash tenemos que hacer git stash pop
Primero hacemos un git status para ver qué no tengamos ningún cambio pendiente
InputPython!cd notebook_git && git statusCopied
En la rama new_featurenada para hacer commit, el árbol de trabajo está limpio
Ahora recuperamos el último stash
InputPython!cd notebook_git && git stash popCopied
En la rama new_featureCambios a ser confirmados:(usa "git restore --staged <archivo>..." para sacar del área de stage)nuevos archivos: archivo9.pyDescartado refs/stash@{0} (0246b0e922f654e7fc68cfeaf26e24fc511feb37)
Si volvemos a hacer git status, veremos que volvemos a tener archivo9.py pendiente de hacer un commit
InputPython!cd notebook_git && git statusCopied
En la rama new_featureCambios a ser confirmados:(usa "git restore --staged <archivo>..." para sacar del área de stage)nuevos archivos: archivo9.py
Y si comprobamos la lista de stash veremos que ya solo tenemos uno
InputPython!cd notebook_git && git stash listCopied
stash@{0}: WIP on new_feature: 527e07a Create README.md
Eliminar un stash (git stash drop <posición>)
Si queremos eliminar un stash, tenemos que hacer git stash drop <posición>, donde <posición> es la posición que ocupa el stash en la lista.
Obtenemos la lista de los stashs
InputPython!cd notebook_git && git stash listCopied
stash@{0}: WIP on new_feature: 527e07a Create README.md
En nuestro caso solo tenemos uno y en la posición 0 (stash@{0}), por lo que para eliminarlo tendríamos que hacer git stash drop 0, sin embargo no lo voy a hacer porque lo voy a eliminar ahora después con otro comando
Eliminar todos los stash (git stash clear)
Si queremos vaciar la lista entera de stash tenemos que hacer git stash clear
InputPython!cd notebook_git && git stash clearCopied
Si ahora pedimos la lista de stash
InputPython!cd notebook_git && git stash listCopied
No obtenemos nada porque hemos eliminado todo
Vamos a dejar todo como estaba, hacemos un git status para recordar los cambios que teníamos pendientes
InputPython!cd notebook_git && git statusCopied
En la rama new_featureCambios a ser confirmados:(usa "git restore --staged <archivo>..." para sacar del área de stage)nuevos archivos: archivo9.py
Vemos que estamos en la rama new_feature y que tenemos archivo9.py pendiente de hacer un commit. Como lo hemos creado para el ejemplo, lo eliminamos y volvemos a la rama principal
InputPython!cd notebook_git && git reset archivo9.pyCopied
InputPython!cd notebook_git && rm archivo9.pyCopied
InputPython!cd notebook_git && git switch mainCopied
Cambiado a rama 'main'Tu rama está actualizada con 'origin/main'.
Tags
Cuando estamos desarrollando código llegan momentos en los que generamos versiones, por ejemplo la v1.1, v1.2, etc. Para tener esto más controlado Git nos proporciona los tags.
Crear un tag nuevo (git tag -a <nombre_de_etiqueta> -m "<mensaje>")
Para crear un tag tenemos que hacer git tag -a <nombre_de_etiqueta> -m "<mensaje>"
Por ejemplo, vamos a crear un tag en la versión actual del repositorio, para ello haré git tag -a v_tag -m "Tag con el repositorio en la parte final, en la que explicamos los tags"
InputPython!cd notebook_git && git tag -a v_tag -m "Tag con el repositorio en la parte final, en la que explicamos los tags"Copied
Lista de tags (git tag)
Para ver los tags que hemos creado podemos hacer git tag
InputPython!cd notebook_git && git tagCopied
v_tag
Crear un tag de un commit antiguo (git tag -a <nombre_de_etiqueta> -m "<mensaje>" <hash>)
Hagamos un git tree para ver el histórico
InputPython!cd notebook_git && git treeCopied
* 527e07a (HEAD -> main, tag: v_tag, origin/main, new_feature) Create README.md* 679bb49 archivo1.py con el merge resuelto|\| * 32851c3 archivo1.py en rama rama_con_conflicto* | 53f909b archivo1.py en rama main|/* 52acb97 Merge squash de los commits de la rama branch_squash* 274529c Merge branch 'branch_no_fast_forward' into main|\| * 8df3429 (branch_no_fast_forward) file2| * e4e23c9 file1* | 8bdf4d8 file3|/* 94149fc (branch_fast_forward) Eliminado hola.py* 4484e70 Eliminado archivo4.py* 564ccfb (new_branch2) Commit con el archivo 8* 5168f78 Eliminado archivo7.py* 4bb9d75 (new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py
Aunque no lo pone en la descripción, cuando hicimos el commit 4bb9d75 fue cuando terminamos la parte de control de versiones de manera local, por lo que también estaría bien tener un tag de ese momento. Para ello lo que tenemos que hacer es crear un tag añadiendo el hash de ese momento
InputPython!cd notebook_git && git tag -a v_local -m "Tag con el repositorio en la parte de control de versiones de manera local" 4bb9d75Copied
Si ahora hacemos un listado de los tags, aparece el nuevo
InputPython!cd notebook_git && git tagCopied
v_localv_tag
Y si vemos el historial de commits
InputPython!cd notebook_git && git treeCopied
* 527e07a (HEAD -> main, tag: v_tag, origin/main, new_feature) Create README.md* 679bb49 archivo1.py con el merge resuelto|\| * 32851c3 archivo1.py en rama rama_con_conflicto* | 53f909b archivo1.py en rama main|/* 52acb97 Merge squash de los commits de la rama branch_squash* 274529c Merge branch 'branch_no_fast_forward' into main|\| * 8df3429 (branch_no_fast_forward) file2| * e4e23c9 file1* | 8bdf4d8 file3|/* 94149fc (branch_fast_forward) Eliminado hola.py* 4484e70 Eliminado archivo4.py* 564ccfb (new_branch2) Commit con el archivo 8* 5168f78 Eliminado archivo7.py* 4bb9d75 (tag: v_local, new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py
En el punto del historial donde hemos creado el tag, ahora aparece el tag que hemos creado * 4bb9d75 (tag: v_local, new_branch) Commit con el archivo 7
Cambiar entre tags (git reset --hard <tag> o git reset --soft <tag>)
Al igual que nos podemos mover entre distintos commits del historial, también nos podemos mover entre tags. Esto tiene la ventaja de que podemos movernos a otro momento del historial sin tener que saberse el hash, con saber el nombre del tag que hemos puesto en ese momento podemos movernos simplemente haciendo git reset --hard <tag> o git reset --soft <tag>
Primero vamos a hacer un ls para ver los archivos que tenemos
InputPython!cd notebook_git && lsCopied
api_keys.py archivo1.py archivo2.py archivo8.py README.md
Hacemos un git tree también para ver en qué momento del historial estamos
InputPython!cd notebook_git && git treeCopied
* 527e07a (HEAD -> main, tag: v_tag, origin/main, new_feature) Create README.md* 679bb49 archivo1.py con el merge resuelto|\| * 32851c3 archivo1.py en rama rama_con_conflicto* | 53f909b archivo1.py en rama main|/* 52acb97 Merge squash de los commits de la rama branch_squash* 274529c Merge branch 'branch_no_fast_forward' into main|\| * 8df3429 (branch_no_fast_forward) file2| * e4e23c9 file1* | 8bdf4d8 file3|/* 94149fc (branch_fast_forward) Eliminado hola.py* 4484e70 Eliminado archivo4.py* 564ccfb (new_branch2) Commit con el archivo 8* 5168f78 Eliminado archivo7.py* 4bb9d75 (tag: v_local, new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py
Ahora cambiamos al punto en el que hemos creado el tag v_local mediante git reset --hard v_local
InputPython!cd notebook_git && git reset --hard v_localCopied
HEAD está ahora en 4bb9d75 Commit con el archivo 7
Si ahora volvemos a hacer un ls vemos que no tenemos los mismos archivos
InputPython!cd notebook_git && lsCopied
api_keys.py archivo1.py archivo2.py archivo4.py archivo7.py hola.py
Si además vemos el historial, vemos que hemos cambiado de momento del historial
InputPython!cd notebook_git && git treeCopied
* 4bb9d75 (HEAD -> main, tag: v_local, new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py
Para volver al último momento del historial, como hemos creado también un tag, valdrá con hacer git reset --hard v_tag
InputPython!cd notebook_git && git reset --hard v_tagCopied
HEAD está ahora en 527e07a Create README.md
Volvemos a ver el historial para comprobar que hemos vuelto al último momento del historial
InputPython!cd notebook_git && git treeCopied
* 527e07a (HEAD -> main, tag: v_tag, origin/main, new_feature) Create README.md* 679bb49 archivo1.py con el merge resuelto|\| * 32851c3 archivo1.py en rama rama_con_conflicto* | 53f909b archivo1.py en rama main|/* 52acb97 Merge squash de los commits de la rama branch_squash* 274529c Merge branch 'branch_no_fast_forward' into main|\| * 8df3429 (branch_no_fast_forward) file2| * e4e23c9 file1* | 8bdf4d8 file3|/* 94149fc (branch_fast_forward) Eliminado hola.py* 4484e70 Eliminado archivo4.py* 564ccfb (new_branch2) Commit con el archivo 8* 5168f78 Eliminado archivo7.py* 4bb9d75 (tag: v_local, new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py