Git es un SCV (Sistema de Control de Versiones) distribuido. Fue pensado para el desarrollo de Linux, y actualmente es el SCV más usado.
Para crear un repositorio (en una carpeta vacia) hay que ejecutar el comando git init
Para añadir los cambios al stage (para registrar los cambios)
git add archivo.c // Añade el archivo.c
git add . // Añade todos los archivos modificados
El comando git commit
Permite registrar los cambios ya añadidos al stage.
Cuando registrar un cambio?
- Una nueva feature
- Una correccion de un bug
- Algo que sea unico, y que no dependa de otros cambios
Trucos para mensajes de commit:
- Mensajes cortos (menos de 50 caracteres)
- Describir "¿Qué hace?"
- En caso que se quiera añadir explicaciones se puede, pero después del mensaje del commit
git commit -m "Esto es un commit" // Para hacerlo más rápido
Los commits tienen un hash único y un mensaje.
Para añadir algo más al último commit.
git commit --amend
Para mostrar todos los commits hechos.
git log
git log --oneline // Para mostrar una sola línea
git log --decorate // Para mostrar a que esta apuntando HEAD
git log --graph // Para mostrar un grafo que permita ver las diferentes ramas
Con git status
se puede examinar el estado del repositorio.
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: apuntes-git.md
no changes added to commit (use "git add" and/or "git commit -a")
Con eso prodremos comprobar si hay archivos que se han modificado, que todavia no han sido registrados, y cuales ya han sido registradas (añadidas al stage mediante git add
).
Para git las modificaciones son añadir lineas o quitar lineas. Cuando se modifica una linea se trata como si quitaramos una linea y añadieramos otra.
Sirve para examinar las diferencias entre commits o las modificaciones no registradas.
git diff // Diferencias no registradas
git diff archivo.c // Diferencias no registradas en archivo.c
git diff b4844be f5f0388 // Diferencias entre dos commits
git diff HEAD~2 // Diferencias entre el ultimo commit y dos commits atras
Para revertir cambios que NO estan en el stage. Para modificaciones locales.
git checkout -- archivo.c
También tiene otras funciones, que se comentaran más adelante en el apartado correspondiente a las ramas.
Para revertir cambios que se han añadido en el stage o ya han sido commiteados. Es un comando destructivo.
git reset HEAD archivo.c
De esta manera revertimos los cambios registrados en el stage. En el archivo se quedarían los cambios todavia, pero dejarán de estar registrados. Para deshacerlos hay que usar git checkout
.
Para volver a un commit anterior, y de esa manera dehacer todos los commits posteriores a ese.
git reset f5f0388
De esta manera revertimos los cambios registrados en el commit. Los cambios seguirían todavia, pero dejarán de estar registrados. Para deshacerlos hay que usar git checkout
.
Para volver a un commit anterior, y de esa manera dehacer todos los commits posteriores a ese, pero ademas eliminarlo tanto del stage como de los cambios locales. (Cuidado!)
git reset --hard f5f0388
git reset --hard HEAD~2 //Volver dos commits atras
Para volver a un commit anterior, y de esa manera dehacer todos los commits posteriores a ese, pero manteniendo los cambios registrados en el stage.
git reset --soft f5f0388
Para revertir cambios que se han añadido en el stage o ya han sido commiteados. Es un comando mucho mejor que reset, ya que en vez de pisar los cambios, los deshace, creando un commit nuevo.
git revert HEAD // revertimos el ultimo commit
Para revertir varios commits a la vez:
- Revertimos el primer commit pero sin commitearlo, dejando los cambios en el stage, mediante el flag
--no-commit
:
git revert --no-commit HEAD
- Revertimos el commit anterior a el ultimo revertido
git revert --no-commit HEAD~1
- Indicamos a git que ya hemos terminado de revertear los cambios mediante el flag
--continue
y de esa manera podremos modificar ya el mensaje del commit de revert que auna todos los reverts
git revert --continue
Para trabajar en diferentes partes a la vez y aislarlas entre sí En las ramas se suele desarrollar las diferentestes características o features de nuestra aplicación. Tambien se suele corregir cada bug en una rama diferente. Dentro de cada rama haremos una serie de cambios mediante commits. Cuando hagamos un commit en una rama éste no afectará a las otras ramas, por loque nuestros cambios quedaran aislados del resto.
Para trabajar con ramas se usa el comando git branch
. Si lo usamos sin ningun parámetro servirá para ver las ramas que tenemos.
Para crear una nueva rama .
git branch nombre-nueva-rama
Cambiar a otra rama.
git checkout nombre-rama
Crear rama y cambiar a ella directamente.
git checkout -b nombre-nueva-rama
Renombrar una rama.
git branch -m nombre-viejo nombre-nuevo
Eliminar una rama.
git brach -d nombre-rama
Cuando ya hayamos hecho los cambios necesarios en una rama, habra que fusionar esos cambios con la rama de origen desde la cual generamos la rama nueva. para hacerlo se usa el comando git merge
.
Para juntar ramas (desde la rama de destino, a la que se quiere fusionar los cambios)
git merge rama-origen
Si usa FastForward, basicamente cambia el puntero de la rama destino y pasa a apuntar al ultimo commit de la rama origen, asi la rama de destino tiene todos los cambios que se han hecho en la rama de origen (la rama de origen es la rama que se bifurca de destino).
Solo se puede usar FastForward cuando solo se ha hecho cambios en una de las dos ramas.
Cuando hay cambos en las dos ramas y se desean fusionar, se crea un nuevo commit mediante una estrategia recursiva.
Esto lo hace git automaticamente EXCEPTO cuando en ambas ramas se ha cambiado la misma linea de un archivo.
Puede darse el caso de que al usar la estrategia recursiva se den conflictos al haber modificado la misma linea del archivo. Cuando se producen, git nos avisa de ellos al hacer el merge. Lo que hace git es guardar en el archivo con el conflicto ambas lineas a la vez. Esto hace que nuestro codigo este mal, sea incorrecto o incluso ni compile. Quedaría algo de este estilo:
<<<<<<<<< HEAD
LINEA DE UNA PARTE
=========
LINEA DE OTRA PARTE
>>>>>>>>> nombre-rama
Lo único que habra que hacer es elegir la que queramos, y modificar el archivo dejándolo como queremos.
Después simplemente hay que commitear el resultado mediante git commit