Git avanzado

Licencia de Creative Commons mario@mariogl.com

Git avanzado

Índice

Conceptos iniciales

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

Git avanzado

proyecto

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

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

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 [ámbito] nombre_variable valor
    • Por ejemplo: git config --system user.name "Mario González"
  • Leer una variable de configuración:
    • git config [ámbito] nombre_variable
    • Por ejemplo: git config --global user.name
  • Listar todas las variables de configuración
    • git config [ámbito] --list
  • Archivos de configuración
    • git config [ámbito] --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

  • Configuración Notepad++:
    git config --global core.editor "'C:\Program Files (x86)\Notepad++\notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
  • Configuración saltos de línea:
    git config --global core.autocrlf true    (Windows)
    git config --global core.autocrlf input   (UNIX)

Fundamentos y arquitectura interna de Git

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

    • HEAD

    • Ramas

    • Tags

Git avanzado

Fundamentos de Git

  • Tipos de tags:
    • Ligera

    • Anotada

  • Añadir tag ligera:
    git tag nombre_tag [commit]
  • Añadir tag anotada:
    git tag -a nombre_tag -m "Mensaje tag" [commit]

Git avanzado

Fundamentos de Git

Git avanzado

Commits

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 (desversionar):
    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 referencias:
    git log --all

  • Ver ramificaciones en el log:
    git log --graph

  • Crear un alias:
    git config --global alias.milog "log --oneline --all
    --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

Reescritura del histórico

Git avanzado

  • Modificar el último commit:
    git commit --amend

  • Borrar commits:
    git reset

  • Comprimir varios commits en uno:
    git reset --soft + git commit

  • Varios cambios de golpe:
    git rebase -i

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

  • 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

Repositorios remotos

Git avanzado

Servidores GIT - repositorios remotos

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 -v

  • 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

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

Git avanzado

  • Si hay jerarquía de proyectos/módulos

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

  • Actualizar submódulos a la última versión:
    git pull
    git submodule update [nombre_submódulo]

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

Git avanzado