Git: Aprovecha las ventajas del control de versiones distribuido
1. Aprovecha las ventajas del control
de versiones distribuido
Iñaki Arenaza
iarenaza@mondragon.edu
Creative Commons https://twitter.com/iarenaza
Attribution Non-commercial Share Alike https://linkedin.com/in/iarenaza
3.0 Spain License
2. Descargar la presentación
Puedes descargar la presentación desde
http://www.slideshare.net/iarenaza/git-aprovecha-
las-ventajas-del-control-de-versiones-distribuido
O puedes usar el siguiente código QR:
2
3. Objetivos
Proporcionar una base teórica y práctica de
los conceptos en los que se basan los SCM
distribuidos.
Ser capaz de realizar las tareas habituales
de un SCM con Git.
Conocer y aplicar las ventajas del modelo
de trabajo de los SCM distribuidos.
3
4. Programa
Características principales de Git
Introducción a los conceptos manejados por Git:
repositorios, objetos, estados, referencias, ramas,
etc.
Instalación de Git en Windows y Linux
Configuración básica de Git en Windows y Linux
Creación de repositorios nuevos con Git
Operaciones básicas con Git
Trabajo con repositorios "remotos"
Propuesta de un modelo de trabajo distribuido
Otras operaciones con Git
4
5. Sistemas de Control de Versiones
Centralizados (CVCS)
Ejemplos: CVS, Subversion, Perforce, SourceSafe, ...
Fuente: http://progit.org/book/ch1-1.html (CC-BY-NC-SA 3.0)
5
6. Sistemas de Control de Versiones
Distribuidos (DVCS)
Ejemplos: git, Mercurial, Bazaar, BitKeeper,...
Fuente: http://progit.org/book/ch1-1.html (CC-BY-NC-SA 3.0)
6
8. (Algunas) características de git
(Casi) todas las operaciones son locales
Git tiene integridad fuerte (sha1)
Git (generalmente) sólo añade datos al
repositorio
8
9. Los tres espacios y tres estados
Fuente: http://progit.org/book/ch1-3.html
(CC-BY-NC-SA 3.0)
Modified* Staged Committed
9
10. Los tres espacios
El directorio git (repositorio) es donde git
almacena los metadatos y la base de datos
de objetos para tu proyecto.
El directorio de trabajo es una copia de
trabajo de una versión del proyecto.
El área de preparación (staging area) es un
archivo que almacena información sobre lo
que se guardará en el próximo commit.
Antes se le llamaba “el índice” (index).
10
11. Los tres estados
Confirmado/no modificado (committed): los
datos están almacenados de manera
segura en el repositorio.
Modificado (modified): se ha modificado el
archivo pero todavía no se ha confirmado.
Preparado (staged): se ha marcado para
confirmación un archivo modificado en su
versión actual.
11
12. Los “tres + 1” estados
El estado
3+1
Fuente: http://progit.org/book/ch2-2.html (CC-BY-NC-SA 3.0)
12
13. Terminología de git
En los ejemplos siguientes $GIT_DIR
contiene la ruta de un repositorio git dado
objeto: unidad de almacenamiento en git.
Se identifica de forma unívoca por el SHA1 de su
contenido.
Por tanto, un objeto es inmutable.
13
14. Terminología de git (cont.)
nombre de objeto o identificador de objeto:
identificador único del objeto (de 40 octetos con
la representación hexadecimal del SHA1 de su contenido)
base de datos de objetos: almacena un
conjunto de objetos (habitualmente en
$GIT_DIR/objects/).
ref o referencia: cadena de 40 octetos con
el identificador de un objeto, o un nombre
simbólico (que se almacena en $GIT_DIR/refs/) que
denota o “apunta” un objeto particular.
14
15. Terminología de git (cont.)
revisión: estado concreto de una serie de
ficheros y directorios que ha sido
almacenado en la base de datos de
objetos. Se hace referencia a él por medio
de un objeto de tipo commit (ver más
adelante)
padre: un objeto commit contiene una lista
(potencialmente vacía) de objetos commit
que representan a sus predecesores lógicos
en la línea de desarrollo, esto es, sus los
objetos commit padre.
15
16. Terminología de git (cont.)
Repositorio (directorio git): colección de
referencias y base de datos de objetos
(alcanzables desde dichas referencias).
Puede contener además algunos meta datos
adicionales usados por determinas órdenes de git.
Puede contener una copia de trabajo de una
revisión.
repositorio desnudo (bare): repositorio que
no tiene una copia de trabajo.
Los ficheros de git que normalmente estarían
presentes en el subdirectorio oculto .git están
presentes en el propio directorio del repositorio.
16
17. Terminología de git (cont.)
árbol de trabajo o copia de trabajo: Una
revisión extraida (checked out) del
repositorio, para poder trabajar con ella.
índice: una colección de ficheros con
información de stat(2)*, cuyos contenidos
están almacenados como objetos.
El índice es una versión almacenada intermedia del
árbol de trabajo.
* stat(2) es la llamada del sistema Unix que nos proporciona
información de un fichero como su tamaño, sus fechas de
creación, modificación y acceso, sus permisos, etc.
17
18. Tipos de objetos de git
blob: objeto sin tipo, para representar una
ristra de octetos (un fichero)
tree: lista de nombres y permisos, junto con
las referencias de objetos blob (un
directorio)
También puede tener referencias a otros objetos de
tipo tree asociados, con lo que puede representar
árboles de directorios con ficheros.
IMPORTANTE: Si un directorio en disco no
contiene ningún fichero (“blob”) git no creará un
objeto de tipo “tree” para representarlo ni
guardará su existencia o estado.
18
19. Tipos de objetos de git (cont.)
commit: información de una revisión dada
guardada en el repositorio. Incluye:
los identificadores de los padres del objeto,
la persona que ha realizado el commit de la
revisión (nombre + email),
el autor de la revisión (nombre + email),
la fecha de la misma,
un mensaje de texto arbitrariamente largo
asociado,
el objeto tree que corresponde al directorio raíz de
la revisión.
19
20. Tipos de objetos de git (cont.)
tag: identifica de forma simbólica a otros
objetos y puede ser usado para firmar
éstos. Contiene:
el nombre y tipo de otro objeto,
un nombre simbólico (el de la propia tag)
puede contener un mensaje asociado.
opcionalmente puede incluir una firma digital (en
formato PGP). En este último caso se denomina un
"objeto de etiqueta firmada".
Las etiquetas normales se pueden modificar (para
que apunten a otro objeto), pero las firmadas no.
20
21. Tipos de objetos de git (cont.)
Fuente: http://progit.org/book/ch3-1.html (CC-BY-NC-SA 3.0)
21
22. Tipos de objetos de git (cont.)
Fuente: http://progit.org/book/ch3-1.html (CC-BY-NC-SA 3.0)
22
23. Terminología de git (cont.)
rama: línea activa de desarrollo.
El commit más reciente de una rama se denomina
la punta de dicha rama. La punta de la rama se
referencia por medio de una cabeza.
La copia de trabajo está siempre asociada a una
rama (la rama "actual" o "checked out") y la
cabeza especial “HEAD” apunta a esa rama.
cabeza: una referencia con nombre, que
apunta al objeto commit de la punta de una
rama.
Las cabezas se almacenan en $GIT_DIR/refs/heads/,
(salvo que se usen referencias empaquetadas).
23
24. Terminología de git (cont.)
checkout: acción de actualizar parte o todo
el árbol de trabajo con un objeto árbol o
blob desde la base de datos de objeto
Además actualiza el índice y la referencia HEAD si
se ha cambiado de rama.
24
25. Terminología de git (cont.)
1 Supongamos este estado “inicial”
Fuente: http://progit.org/book/ch3-1.html (CC-BY-NC-SA 3.0)
25
27. Terminología de git (cont.)
3 master sigue siendo la rama
activa en la copia de trabajo
Fuente: http://progit.org/book/ch3-1.html (CC-BY-NC-SA 3.0)
27
28. Terminología de git (cont.)
4 Ejecutamos:
$ git checkout testing
testing pasa a ser la rama
activa en la copia de trabajo
Fuente: http://progit.org/book/ch3-1.html (CC-BY-NC-SA 3.0)
28
32. Terminología de git (cont.)
merge: fusionar los contenidos de otra
rama (potencialmente desde un repositorio
externo) en la rama actual.
Si la rama es de otro repositorio, primero se hace
un fetch* de la rama y después se fusiona en la
rama actual.
La fusión puede crear un nuevo objeto commit si
una de las ramas no es un ancestro de la otra.
Si una es ancestro de la otra, simplemente se
mueve la referencia de la cabeza de la rama
fusionada (fast-forward merge).
32
33. merge: escenario 1
1 Supongamos este estado “inicial”
Fuente: http://progit.org/book/ch3-2.html (CC-BY-NC-SA 3.0)
33
39. Operaciones en el área de trabajo
Crear nuevas ramas locales (ultra rápido
y baratísimo en disco):
$ git branch ref-nueva-rama ref-o-etiqueta-existente
Extraer una rama al área de trabajo:
$ git checkout ref--existente
Consultar la rama activa:
$ git branch (es la que aparece marcada con un '*')
Mostrar el estado del área de trabajo:
$ git status
Marcar cambios para commit:
$ git add fichero1 fichero2 ...
$ git rm fichero3 fichero4 ...
39
40. Operaciones en el área de trabajo
Mostrar diferencias con el área de preparación
o con HEAD:
$ git diff
$ git diff HEAD
Mostrar diferencias con otras ramas:
$ git diff ref-existente
$ git diff ref-existente-1..ref-existente-2
Hacer commit de los cambios (marcados):
$ git commit
Usar gitk para visualizar el historial de una rama:
$ gitk ref-existente
Usar gitk para visualizar el historial de todas las
ramas:
$ gitk --all
40
41. Operaciones en el área de trabajo
Resetear el área de trabajo y el área intermedia
al estado de HEAD (o cualquier otra referencia):
$ git reset --hard HEAD
Resetear el área de preparación al estado de
HEAD (o cualquier otra referencia):
$ git reset --mixed HEAD
Mover la referencia de HEAD a otro commit sin
tocar ni el área de trabajo ni el área intermedia:
$ git reset --soft HEAD~
41
42. Trabajo con repositorios remotos
clone: obtener una copia local completa* de un
repositorio git remoto.
* las cabezas de
las ramas remotas
son inamovibles**
en la copia local
Fuente: http://progit.org/book/ch3-5.html (CC-BY-NC-SA 3.0) 42
43. Trabajo con repositorios remotos (cont.)
fetch: obtener la cabeza de una rama (o
varias) desde un repositorio remoto,
copiando los objetos falten y moviendo
la(s) cabeza(s) remota(s).
Fuente: http://progit.org/book/ch3-5.html (CC-BY-NC-SA 3.0) 43
44. Trabajo con repositorios remotos (cont.)
Fetch: alguien hace cambios en el
repositorio remoto
1
Fuente: http://progit.org/book/ch3-5.html (CC-BY-NC-SA 3.0) 44
45. Trabajo con repositorios remotos (cont.)
Fetch: ejecutamos fetch e incorporamos
esos cambios en nuestro repositorio
2
Fuente: http://progit.org/book/ch3-5.html (CC-BY-NC-SA 3.0) 45
46. Trabajo con repositorios remotos (cont.)
pull: hacer un fetch seguido de un merge
en la rama local con la rama remota
configurada.
push: enviar los objetos de la rama local
que no están en la rama remota a la que
hace referencia el pull, y actualizar la
cabeza de la rama remota.
Es la acción complementaria de pull.
Si la cabeza de la rama remota no es un ancestro
de la cabeza de la rama local, el push falla*.
(*) Podemos forzar el push, pero rescribimos el
historial del repositorio (¡es una posible fuente de
problemas si el repositorio es compartido!)
46
62. Creación repositorio compartido
Configurar rama local para hacer pull desde
repositorio compartido
$ git config branch.mdl22-ldap-refactor.remote
compartido
$ git config branch.mdl22-ldap-refactor.merge
refs/heads/mdl22-ldap-refactor
62
65. Creación repo nuevo desarrollador
Crear ramas locales de trabajo
$ git branch mdl22-ldap-refactor
compartido/mdl22-ldap-refactor
$ git checkout mdl22-ldap-refactor
65
66. Una propuesta de modelo de trabajo con
las ramas
Propuesto por Vincent Driessen en su blog
http://nvie.com/posts/a-successful-git-
branching-model/
Se puede descargar el PDF (licencia CC-BY)
con el esquema de ramas propuesto desde
http://github.com/downloads/nvie/gitflow/Gi
t-branching-model.pdf
La descripción del modelo en el blog
explica no sólo los “cómos” sino también
los “porqués”.
66
67. Otras operaciones con git
Reescritura del historial de una rama
(“haciendo limpieza”).
rebase: re-aplicar una serie de cambios
desde una rama en la cabeza de otra rama
diferente, y hacer que la cabeza de esa
otra rama apunte al resultado.
¡OJO! Reescribe el historial de la rama.
Puede ser problemático en ramas publicadas en
repositorios compartidos.
67
68. rebase: reescritura del historial
1 Estado “inicial”. master es
la rama activa en el directorio
de trabajo.
Fuente: http://progit.org/book/ch3-6.html (CC-BY-NC-SA 3.0)
68
69. rebase: reescritura del historial (cont.)
2 merge tradicional de
“master” y “experiment”:
$ git merge experiment
Fuente: http://progit.org/book/ch3-6.html (CC-BY-NC-SA 3.0)
69
70. rebase: reescritura del historial (cont.)
3 rebase de “experiment” sobre
“master”
$ git checkout experiment
$ git rebase master
Fuente: http://progit.org/book/ch3-6.html (CC-BY-NC-SA 3.0)
70
71. rebase: reescritura del historial (cont.)
4 merge de “master” y
“experiment” tras el rebase:
$ git merge experiment
(es un simple 'fast-forward')
Fuente: http://progit.org/book/ch3-6.html (CC-BY-NC-SA 3.0)
71
72. Reescritura del historial
IMPORTANTE: No hace rebase de los
cambios de una rama si ésta ha sido
publicada en otro repositorio, a menos que
se sea consciente de las implicaciones.
Estamos creando nuevos objetos y
cambiando los ancestros de los commits
existentes en la rama.
Creará confusión y caos a quienes hayan
clonado nuestro rama (repositorio) si han
creado sus propios commits a partir de
nuestra rama.
72
73. Reescritura del historial
Conviene aplicarla sólo a la rama activa
(evita sorpresas):
$ git checkout wip-mdl22-enrol-db-refactor
$ git rebase MOODLE_22_STABLE
Si hay conflictos, solucionar a mano, y
decirle a git qué hemos arreglado y que
continue el proceso:
$ editar enrol/database/config.html
$ git add enrol/database/config.html enrol/database/enrol.php
$ editar xxxx
$ git add xxxxx
$ git rebase --continue
Podemos abortar en todo momento:
$ git rebase --abort
73
74. Rescritura “interactiva” del historial
Permite elegir (¡y reordenar!) los commits
que vamos a rebasar.
$ git checkout wip-mdl22-enrol-db-refactor
$ git rebase -i MOODLE_22_STABLE
Nos deja en un editor con la lista de los
commits y unas palabras clave para indicar
como tratar cada commit.
Además de usar las operaciones marcadas
por las palabras clave, podemos reordenar
los commits simplemente cambiando el
orden de las líneas.
74
75. Rescritura “interactiva” del historial
pick 72ed614 MDL-30935_in_lti_change_role_from_instructor
pick 3360b13 MDL-31251 documentation : fix incorrect docs
pick 8150fd9 Automatically generated installer lang files
pick a97d4da Automatically generated installer lang files
pick 0dde394 weekly release 2.3dev
pick 45b6c23 MDL-28585 LDAP doesn't handle password expiration
# Rebase 1609f3c..45b6c23 onto 1609f3c
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
75
76. Otras operaciones con git
Creación de parches monolíticos:
$ git checkout mdl22-enrol-db-refactor
$ git diff MOODLE_22_STABLE > mdl22-enrol-db-refactor.diff
Creación de series de parches:
$ git checkout mdl22-enrol-database-refactor
$ git format-patch -o serie-enrol-db MOODLE_22_STABLE
$ git format-patch -o -s -10 MOODLE_22_STABLE
76
77. Algunos trucos bajo la manga
(bonus track ☺)
git add --interactive
git cherry-pick
git stash [save | list | show | apply | remove | clear]
git bisect
git blame
git gc, git prune, git fsck
.git/hooks/*
77
78. Algunas direcciones de interés
Página oficial de Git:
http://www.git-scm.org/
Libro Pro Git:
http://progit.org/book/
Página de msysgit (Git para Windows)
http://code.google.com/p/msysgit/
Página de TortoiseGit (GUI para Windows):
http://code.google.com/p/tortoisegit/
http://code.google.com/p/tortoisegit/wiki/UsingPuTTY
Página de Egit (plugin para Eclipse):
http://www.eclipse.org/egit/
http://www.eclipse.org/downloads/compare.php
Página de SourceTree (Git para MacOSX):
http://www.sourcetreeapp.com/
78
79. Algunas direcciones de interés
Git Cheat Sheets:
http://devcheatsheet.com/tag/git/
A successful Git branching model
http://nvie.com/posts/a-successful-git-branching-model/
github/GITORIOUS:
https://github.com/ y https://gitorious.org/
gitosis:
https://secure.wikimedia.org/wikibooks/en/wiki/Git/Gitosis
http://thinkshout.com/blog/2011/03/lev/redmine-and-gitosis-project-management-nirvana
gitolite:
https://github.com/sitaramc/gitolite
Gerrit:
https://code.google.com/p/gerrit/
79