Git avanzado
Git avanzado
Conceptos iniciales
Qué es el control de versiones
Git avanzado
Conceptos iniciales
Qué es el control de versiones
Git avanzado
develop
experimento
develop
Conceptos iniciales
Qué es el control de versiones
VCS centralizados / distribuidos
Línea de comandos vs. interfaces gráficas
Branching
Git avanzado
Conceptos iniciales
Git avanzado
master
develop
feature
feature2
Git avanzado
Instalación
Git avanzado
Configuración
Git avanzado
Configuración inicial
Git avanzado
Git avanzado
Fundamentos de Git
Working directory
Repositorio
Git avanzado
Working directory
Repositorio
(.git)
Fundamentos de Git
Working directory
Repositorio
Commits (snapshots)
Git avanzado
Working directory
Repositorio local
Fundamentos de Git
Working directory
Repositorio
Commits (snapshots)
Stage
Git avanzado
Working directory
Repositorio local
Stage
archivo1.java
archivo1.java
archivo1.java
archivo1.java
archivo2.java
archivo2.java
archivo1.java
archivo2.java
archivo2.java
Fundamentos de Git
Referencias
Ramas
HEAD
Tags
Git avanzado
Fundamentos de Git
Ligera
Anotada
Git avanzado
Fundamentos de Git
Git avanzado
Git avanzado
Preparando el commit
Añadir nuevos archivos al índice (empezar a versionar):
git add <path>
Añadir modificaciones al stage:
git add <path>
Información sobre el estado de las tres zonas:
git status
Quitar modificaciones del stage:
git reset HEAD <path>
Deshacer cambios del Working Directory:
git checkout -- <path> (operación irreversible)
Git avanzado
Preparando el commit
Borrar archivos:
git rm path
Sacar un archivo del repositorio sin borrarlo en el Working Directory:
git rm --cached path
Git avanzado
Preparando el commit
Hacer el commit:
git commit [-m "Mensaje"]
Evitar mensajes genéricos como "Cambios", "Nuevo archivo", "Correcciones", "CSS", "Merge"...
Modificar el último commit:
git commit --amend
No hacer --amend si el commit ya se había subido al remoto
Git avanzado
El commit
Autor / commiteador
Fecha
Mensaje
Padre/s
Hash SHA-1
Git avanzado
El log
Git avanzado
Ver el histórico de commits:
git log [rama]
Ver el log compacto:
git log --oneline
Ver el log de todas las ramas:
git log --branches
Ver ramificaciones en el log:
git log --graph
Crear un alias:
git config --global alias.milog "log --oneline --branches --graph"
Ver el contenido de un commit:
git show <commit>
El log
Cómo referenciar a un commit
Por su identificador: hash SHA-1
Por su posición respecto al HEAD:
HEAD^, HEAD^2...
HEAD~, HEAD~2...
Por el nombre de una rama
Por su posición en el listado de reflog: HEAD@{n}
Git avanzado
El log
Saltar a otro commit o rama:
git checkout <commit o rama>
Borrar commits:
git reset <commit> [--soft|--mixed|--hard]
Ver el histórico de HEADs con git reflog
Culpar con git blame path
Git avanzado
El log
Apartar cambios provisionalmente
git stash [push -m "Mensaje"]
git stash list
git stash show [stash@{n}] [-p]
git stash apply [stash@{n}]
git stash pop [stash@{n}]
git stash drop [stash@{n}]
Git avanzado
Cómo deshacer
Git avanzado
Deshacer cambios en el Working Directory
Deshacer subidas al stage
Deshacer commits
Deshacer un commit --amend
Deshacer un reset
Resolver problemas derivados del Detached HEAD
Ignorar archivos que ya están siendo versionados
Git avanzado
Conflictos
Cuando hay dos versiones de código y Git no puede decidir cuál es la definitiva
Diferencias en formato del archivo (tabulaciones, codificación, saltos de línea...)
Pueden aparecer en cualquier operación que implique fusión de código: merge, rebase, cherry-pick, pull
Siempre que aparezcan conflictos, primero lanzar git status
Git espera a que resolvamos los conflictos y le demos la orden de cerrar la operación
Los conflictos se delimitan por marcas en los archivos
Git avanzado
<<<<<<< HEAD
↑
// Código del commit o rama
// adonde apunta el HEAD
↓
=======
↑
// Código del commit o rama
// que estoy intentando fusionar con HEAD
↓
>>>>>>> develop
Conflictos
Git avanzado
Conflictos
Si queremos resolverlos a mano, editamos el texto, borramos las marcas y dejamos el código definitivo.
Para usar una interfaz gráfica específica para resolver conflictos:
git mergetool
Ejemplo: configurar KDiff3
git config --global merge.tool kdiff3
git config --global mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
Git avanzado
Conflictos
Una vez resueltos los conflictos, se lo comunicamos a git mediante git add path
Para terminar la fusión en un merge o en un pull:
git commit
Para terminar la fusión en un rebase:
git rebase --continue
Para terminar la fusión en un cherry-pick:
git cherry-pick --continue
Git avanzado
Git avanzado
Ramas
Git avanzado
Ramas
Referencia
La rama master
Múltiples ramas
Git avanzado
Ramas
Listar ramas:
git branch
Crear una rama:
git branch nombre_rama [commit]
Ir a una rama:
git checkout nombre_rama
Crear rama e ir a ella:
git checkout -b nombre_rama
Borrar una rama:
git branch -d/-D nombre_rama
Renombrar una rama:
git branch -m nombre_antiguo nombre_nuevo
Git avanzado
Ramas - merge
Git avanzado
HEAD
develop
C1
C2
C5
C6
C7
C3
C4
Ramas - merge
Fusionar ramas
Volcar el trabajo de una rama en otra
Objetivo: que una rama tenga los commits de otra
Tipos de merge:
Fast forward: no crea un nuevo commit, sin conflictos
Merge a tres bandas: crea un nuevo commit, posibilidad de conflictos
Conflictos: lanzar siempre git status
Git avanzado
Ramas - rebase
Git avanzado
HEAD
develop
C1
C2
C5
C6
C7
C3
C4
Ramas - rebase
Aplicar una rama al final de otra
Volcar el trabajo de una rama en otra
Objetivo: que una rama tenga los commits de otra
No crea un nuevo commit
Conflictos por pasos: lanzar siempre git status
No hacer rebase si ya se ha subido la rama al remoto
Git avanzado
Ramas - cherry-pick
Aplicar un commit aislado a una rama
No se aplican los commits anteriores
Modificador -x para que añada al mensaje "Cherry-picked from XXXX"
Conflictos: lanzar siempre git status
Git avanzado
Ramas - mover referencias
git branch -f nombre_rama [<commit>]
git reset <commit> --hard
Si sólo queremos avanzar la referencia de una rama hasta un commit más avanzado:
git merge rama_destino
Git avanzado
El modelo git flow
master branch
develop branch
feature branch
bugfix branch
hotfix branch
release branch
Git avanzado
El programa git flow
Instalación (en Windows ya viene instalado con Git)
Empezar a usar git flow en un repositorio:
git flow init
Iniciar rama:
git flow tipo_rama start nombre_rama
Cerrar rama:
git flow finish
Git avanzado
Git avanzado
Servidores GIT - repositorios remotos
Azure DevOps / Team Foundation Server
Git avanzado
Repositorios remotos
Git avanzado
Los remotes: el remote origin
Añadir un remote:
git remote add nombre_remote URL_remote
Renombrar un remote:
git remote rename nombre_actual nuevo_nombre
Cambiar la URL de un remote:
git remote set-url nombre_remote URL_remote
Borrar un remote:
git remote remove nombre_remote
Repositorios remotos
Git avanzado
Clonar un repositorio remoto:
git clone URL [directorio]
Ver ramas remotas:
git branch -a
Trackear rama:
git branch --set-upstream-to nombre_remote/nombre_rama
Ver ramas trackeadas:
git branch -vv
Repositorios remotos
Enviar cambios al repositorio remoto:
git push nombre_remote nombre_rama
Trackear la rama al hacer el push:
git push -u nombre_remote nombre_rama
Sincronizar mi copia local del remoto:
git fetch
Traer cambios del remoto:
git fetch + git merge = git pull
git fetch + git rebase = git pull --rebase
Si siempre queremos pull --rebase:
git config --global pull.rebase true
Subir tags al remoto:
git push --tags
Git avanzado
Repositorios remotos
Borrar ramas del remoto
Marcar ramas remotas borradas:
git fetch --prune
Configurar prune por defecto:
git config [--global|--system] fetch.prune true
Ver lo que voy a enviar en el push:
git diff origin/master master
Git avanzado
Git avanzado
GUI para Git
Git GUI y gitk (instaladas con Git)
Git avanzado
GUI para Git
Git avanzado
GUI para Git
Git avanzado
GUI para Git
Git avanzado
GUI para Git
Plugin EGit para Eclipse
Git avanzado
GUI para Git
Team Explorer de Visual Studio
Git avanzado
Git avanzado
Git & Maven
Git avanzado
Git & Maven - Submódulos
Git avanzado
Añadir un submódulo al módulo padre:
git submodule add URL [subcarpeta]
Clonar un módulo padre con sus submódulos:
Método 1: git clone URL --recurse-submodules
Método 2:
git clone URL
git submodule init
git submodule update
Git & Maven - Maven SCM plugin
Git avanzado
Integra a Maven con Git
Cuando hacemos una release con Maven, también añade un commit y un tag al repositorio Git
Nos permite lanzar comandos Git en cualquier fase
Configuración en el pom.xml:
<project ...>
...
<scm>
<url>https://bitbucket.org/git-valencia-2/facturas/src/master</url>
<connection>scm:git:https://mariogl@bitbucket.org/git-valencia-2/facturas.git</connection>
<developerConnection>scm:git:https://mariogl@bitbucket.org/git-valencia-2/facturas.git</developerConnection>
</scm>
...
</project>
Git avanzado
Pull Requests
En equipos grandes
El repositorio remoto tiene permisos de sólo lectura en la rama develop
Los miembros no pueden mergear sus ramas a develop
Se sube la rama propia de feature y se solicita el merge a través de la interfaz del servidor
Hay un encargado (o varios) de revisar las peticiones de PR, y de realizar el merge de las ramas a develop
Git avanzado
Links
Git avanzado
Git avanzado