Git del día-a-día… Guía práctica de comandos por casos de uso

Ésta es una recopilación de casos de uso y los comandos correspondientes de Git. Normalmente nos encontramos ante ciertos casos y debemos realizar ciertas acciones.

Aquellas acciones que repetimos mucho se nos quedan grabadas y los comandos nos vienen solos… pero otras, me veo siempre buscando cuál era el dichoso comando, para quedarme con cara de tonto leyendo cuál era (por tercera vez esa semana jajaja)

Así que vamos con ellos, de más simple a más complejo

1. Empiezo proyecto y tengo ya un repositorio subido para clonar

cd mis/proyectos/
git clone <url> nombre-del-proyecto

Donde <url> es la url que nos ofrece GitHub o Bitbucket o lo que usemos y nombre-del-proyecto será el nombre del directorio que lo contenga

2. Ya he clonado el proyecto pero no veo el código que necesito

cd nombre-del-proyecto
git branch <rama>

Seguramente necesites moverte a una rama concreta del repositorio

3. Alguien ha hecho cambios y quiero tenerlos en mi código

git pull

O la versión larga

git fetch
git merge

4. He modificado archivos y quiero guardarlos en Git

git add .

O seleccionamos sólo aquellos que queramos guardar

git add <archivo1> <archivo2>

Y para «commitearlos»

git commit -m "Mensaje del commit"

5. He modificado sin querer un archivo y quiero dejarlo como estaba

Para todos los archivos

git reset --hard 

Para un archivo concreto

git checkout HEAD -- <archivo>

6. He «commiteado», pero quiero deshacerlo

Deshacer el commit y quedarme con los cambios en el código para poder volver a hacer commit

git reset --soft HEAD~1

Deshacer el commit y borrar los cambios en el código

git reset --hard HEAD~1

7. Estoy en una rama, he hecho cambios… hago pull pero no me deja continuar

El pull nos dice «error: your local changes to the following files would be overwritten by merge» y no nos deja continuar. Es decir que hemos modificado el mismo archivo que se quiere traer con el pull y nos avisa que perderíamos nuestros cambios.

git stash save <nombre-stash> -u

Guardamos temporalmente en la pila de stash todos los archivos modificados incluyendo los que aún no tienen seguimiento con -u (o también que es lo mismo –include-untracked).

git pull

Ahora nos dejará porque los cambios los hemos apartado en el stash

git stash apply <n>

Con git stash list veremos el listado de stashes para seleccionar que queremos aplicar en <n>

Puede ocurrir que al aplicar el stash surjan conflictos, simplemente hay que resolverlos con cuidado como cualquier otro conflicto

8. Han surgido conflictos ¿cómo los resuelvo manualmente?

Tras hacer un pull puede ocurrir que si hemos tocado las mismas líneas en local y en remoto, tengamos que decidir nosotros y no git, qué líneas son las que se deben conservar (ya que se han modificado «simultáneamente»).

git status

Con git status veremos qué archivos están modificados y esperando a que resolvamos el conflicto.

Si los editamos veremos estos símbolos

<<<<<<< HEAD

(código que existe ahora mismo en nuestra rama o commit en cuestión)

======= (centro del conflicto)

(código que nos traemos con el pull o que existe en la otra rama)

>>>>>>> otra-rama-o-commit

Basta con editar y dejar el archivo como deseemos, quitando los símbolos, con nuestra versión solo, la versión que nos traemos, o una mezcla de ambas.

git add .
git commit -m "resolver conflicto"

Continuamos con el merge del pull que se había quedado a la espera del conflicto

git merge --continue

Finalmente, si no hay más conflictos, habrá que subir los cambios

git push

¿Y si algo sale mal al resolver un conflicto o me he equivocado? Podemos deshacerlo todo para repetir todo el proceso con

git merge --abort

9. Tengo cambios y quiero hacer una nueva rama

git checkout -b <nombre-rama>
git add .
git commit -m "mensaje del commit"

git chekout -b crea una rama nueva y podemos hacerlo incluso con cambios pendientes de ser añadidos.

La nueva rama será unicamente local hasta que la subamos al remoto con

git push origin <nombre-rama>

10. Acabo de commitear y se me ha olvidado añadir algo ¿Puedo añadirlo?

git add <archivo1> <archivo2>
git commit --amend --no-edit

Si necesitamos cambiar el mensaje del commit: git commit –amend -m ‘nuevo mensaje’. Podemos hacerlo para cambiar el mensaje del commit sin cambios en el código.

11. ¿Cómo borro una rama que ya no necesito?

Borrar la rama local. Primero vamos a otra rama diferente y luego borramos

git checkout <nombre-otra-rama>
git branch -d <nombre-rama-borrar>

Borrrar rama remota (que ya hemos subido)

git push -d origin <nombre-rama>

12. ¿Puedo añadir un cambio a un commit ya subido?

Sí, pero estaré borrando cualquier commit en medio de mi primer commit y el que esté ahora modificando… por este motivo se aconseja hacer esto solo si estamos en una rama trabajando solos.

Modificamos el commit

git add <archivo1> <archivo2>
git commit --amend --no-edit

Subimos forzosamente

git push -f

13. ¿Cómo puedo unir varios commits en uno solo?

Supongamos que estamos en nuestra rama y hemos hecho varios commits que al revisarlos, vemos que deberían haberse hecho en 1 solo commit… esto podemos hacerlo con un rebase interactivo

git rebase -i <commit-hash>

En esta opción que usamos el <commit-hash>, éste debe ser el commit anterior al que queramos revisar.

También podemos hacerlo así:

git rebase -i HEAD~<numero-commits-a-revisar>

Se nos abrirá un editor de texto con los commits en orden de creación de arriba a abajo y en comentarios, las instrucciones. La parte importante es esta:

pick 52b4d32 Commit1
pick jst2454 Commit2
pick 070c2d3 Commit3
pick 143d20f Commit4

Tendremos que editar el texto, con los comandos (que están explicados en la parte de comentarios debajo de los commits) que normalmente solo usaremos «pick» o «squash» («p» o «s» abreviados). Quedando asi:

pick 52b4d32 Commit1
s jst2454 Commit2
s 070c2d3 Commit3
s 143d20f Commit4

Pick: el commit quedará en el historial

Squash: el commit se combinará con el anterior

Cerramos el editor y se producirán los cambios en el historial de commits. Podemos hacer push.

Importante: estamos modificando el historial de commits… por ello se recomienda sólo cuando estemos modificando el repo local o cuando sea una modificación del repo remoto en una rama que estemos trabajando solo nosotros. De lo contrario un compañero tendrá problemas a la hora de hacer pull o push porque no coincidirán sus commits locales con los remotos…

14 ¿Cómo puedo unir varios commits en uno solo de forma más sencilla que un rebase?

Si son los últimos cambios que hemos hecho y podemos unirlos todos en un solo commit sin necesidad de seleccionar alguno sí y otro no como en el ejemplo anterior, podemos deshacer x commits atrás y volver a commitear:

git reset --soft HEAD~<numero-commits-a-unir>
git commit m "nuevo commit"

15. He subido cambios (commits) a una rama… pero quiero que estén también en otra rama

Usaremos cherry-pick. Para ello hemos de saber los commits que queremos copiar, y entonces

git checkout <rama-destino>
git cherry-pick <commit-hash>

Podemos también copiar un rango de commits con «..»

git cherry-pick <commit-hash-mas-antiguo>..<commit-hash-mas-nuevo>

Puede ser que nos encontremos con conflictos. Los resolvemos manualmente y entonces

git cherry-pick --continue

Y si algo sale mal en el proceso, siempre podemos cancelarlo y volver a empezar

git cherry-pick --abort

Tengo cambios subidos, mergeados, publicados… pero los quiero deshacer

La mejor forma una vez el cambio está subido al repo remoto, es revertirlo (git hace un commit que revierte los cambios y este nuevo commit forma parte del historial, de forma que el resto de compañeros podrán disponer del este cambio también y estará claro que es un «deshacer»)

git revert <commit-hash>

El commit será «Revert ‘<commit-message>'»