Git avanzado

Licencia de Creative Commons mario@mariogl.com

Temario

  • Conceptos iniciales

  • Instalación y configuración

  • Fundamentos y arquitectura interna de Git

  • Commits

  • Conflictos

  • Branching

  • Repositorios remotos

  • Interfaces gráficas

  • Submódulos

  • Pull Requests

Git avanzado

Conceptos iniciales

Git avanzado

Git avanzado

Conceptos iniciales

  • Qué es el control de versiones

  • VCS centralizados / distribuidos

  • CLI vs GUI

  • Branching

Git avanzado

Instalación y configuración

Git avanzado

Instalación

 

  • Notepad++

  • Git

  • Marcar o asegurarse de que está marcado:

    • Git Bash Here

    • Use Notepad++ as Git's default editor

    • Use Git from the Windows Command Prompt

    • Checkout Windows-style, commit Unix-style etc.

    • Use MinTTY

    • Enable Git Credential Manager

  • Crear una cuenta en Bitbucket (con un email real)

Git avanzado

Configuración

  • Variables de configuración
    • Sistema (S.O.): git config --system
    • Global (usuario): git config --global
    • Local (proyecto): git config [--local]
  • Guardar una variable de configuración:
    • git config [tipo] nombre_variable valor
    • Por ejemplo: git config --system user.name "Mario González"
  • Leer una variable de configuración:
    • git config [tipo] nombre_variable
    • Por ejemplo: git config --global user.name
  • Listar todas las variables de configuración
    • git config [tipo] --list
  • Archivos de configuración
    • git config [tipo] --list --show-origin

Git avanzado

Configuración inicial

  • Configuración proxy:
    git config --global http.proxy http://username:password@host:port
    git config --global https.proxy http://username:password@host:port
  • Configuración usuario:
    git config --global user.name "Mario González"
    git config --global user.email mario@mariogl.com

Git avanzado

Fundamentos de Git

Git avanzado

Fundamentos de Git

  • Snapshots (commits)

  • Repositorio

  • Working directory

  • Stage

Git avanzado

Fundamentos de Git

  • Referencias

    • Ramas

    • HEAD

    • Tags

  • .gitignore (generador)
  • Añadir tag:
    git tag nombre_tag

Git avanzado

Commits

Git avanzado

Preparando el commit

  • Añadir nuevos archivos al índice (empezar a versionar):
    git add path

  • Quitar del índice (desversionar):
    git rm --cached path

  • Añadir modificaciones al staging area:
    git add path

  • Ver las tres zonas: git status

  • Quitar modificaciones del staging area:
    git reset HEAD path

  • Deshacer cambios del Working Directory:
    git checkout -- path

  • Borrar archivos: git rm 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

Preparando el commit

Git avanzado

El commit

  • Hash SHA-1

  • Autor / commiteador

  • Fecha

  • Mensaje

  • Padre/s

Git avanzado

El log

  • git log [rama] para ver el histórico de commits

  • git log --branches para ver el log de todas las ramas

  • Referencias en el log

  • Ver el log compacto con git log --oneline

  • Ver bifurcaciones con git log --graph

  • Ver un commit con git show

Git avanzado

El log

  • Cómo referenciar a un commit

    • Por su nombre: hash SHA-1

    • Por su posición respecto al HEAD:
      HEAD^, HEAD^2...
      HEAD~, HEAD~2...

    • Por su posición en el listado de reflog: HEAD@{n}

Git avanzado

El log

  • Saltar a otro commit o rama con git checkout

  • Borrar commits con git reset

  • Ver el histórico de HEADs con git reflog

  • Culpar con git blame path

  • Apartar cambios provisionalmente con git stash

    • git stash [push -m "Mensaje"]

    • git stash list

    • git stash show stash@{n} -v

    • git stash apply [stash@{n}]

    • git stash pop [stash@{n}]

    • git stash drop [stash@{n}]

Git avanzado

Conflictos

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

Branching

Git avanzado

Ramas

Git avanzado

Ramas

  • Referencia

  • La rama master

  • Listar ramas

  • Crear una rama con git branch

  • Ir a una rama con git checkout

  • Crear rama e ir a ella con git checkout -b

  • Borrar una rama con git branch -d

  • Renombrar una rama con git branch -m

Git avanzado

Ramas - merge

Git avanzado

Ramas - merge

  • Fusionar ramas

  • Volcar el trabajo de una rama en otra

  • Objetivo: que una rama tenga los commits de otra

  • Fast forward: no crea un nuevo commit

  • Merge a tres bandas: crea un nuevo commit

  • Conflictos: lanzar siempre git status

  • Simulación

Git avanzado

Ramas - rebase

Git avanzado

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

  • Simulación

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

Repositorios remotos

Git avanzado

Servidores GIT - repositorios remotos

Git avanzado

Repositorios remotos

  • Clonar un repositorio remoto:
    git clone URL [directorio]

  • Los remotes: el remote origin

  • Añadir un remote con git remote add

  • Renombrar un remote con git remote rename

  • Borrar un remote con git remote remove

  • Cambiar la URL de un remote con git remote set-url

  • Tracking branch
    git branch --set-upstream-to nombre_remote/nombre_rama

  • Ver ramas trackeadas:
    git remote show nombre_remote

Git avanzado

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 con git fetch

  • Traer cambios del remoto con git merge

  • Traer cambios del remoto con git rebase

  • git fetch + git merge = git pull

  • git fetch + git rebase = git pull --rebase

  • Subir tags: git push --tags

Git avanzado

Repositorios remotos

  • Borrar ramas del remoto

  • Marcar ramas remotas borradas con git fetch --prune

  • Configurar prune por defecto:
    git config [--global] fetch.prune true

  • Ver lo que voy a enviar en el push:
    git diff origin/master master

Git avanzado

Interfaces gráficas

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

Submódulos

Git avanzado

Submódulos

  • Para cuando hay jerarquía de proyectos/módulos

Git avanzado

Submódulos

  • Añadir un submódulo al módulo padre:

    • git submodule add URL

  • 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 avanzado

  • Actualizar submódulos a la última versión:
    • git submodule update --remote

Pull Requests

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