Professional Documents
Culture Documents
Índice
n Introducción
n Lo más básico
n Grafo de commits
n Estados de un fichero
n Clonar un repositorio
n Configuración
n Interacción básica
n Desarrollo de tareas pequeñas
n Otros flujos de trabajo
n Más información
1-2
Introducción
Cliente
fich2 ... Cliente
fich2
...
...
fichN fichN
Desarrollador 1 Desarrollador k
1-3
Introducción
1-4
Introducción
Repositorio de Repositorio de
versiones del proyecto versiones del proyecto
(repositorio local) (repositorio local)
Cliente
... Cliente
Desarrollador 1 Desarrollador k
1-5
Introducción
n Sistemas de control de versiones distribuidos: un primer escenario
(cont)
n La máquina de cada usuario contiene una copia completa (un clon) del
repositorio de control de versiones
n Pueden evolucionar a ritmos distintos
n Flujo de trabajo básico
n [1] Actualizar repositorio local
n [2] Trabajar en una tarea
n [3] Cuando la tarea está completa => commit en el repositorio local
n [4] Publicar el commit local en el repositorio remoto
n [5] Volver a [1]
n Flujo similar al de un sistema de control de versiones centralizado
n Pero con más ventajas:
n Cada usuario tiene un clon del repositorio remoto
n Si al hacer [4] no hay conectividad al repositorio remoto, es posible seguir
trabajando en otras tareas, que generarán commits locales
n Además, otras operaciones (e.g. visualizar el log), actúan contra el repositorio
local
1-6
Introducción
n Sistemas de control de versiones distribuidos: un primer
escenario (cont)
n Flujo de trabajo más rico
n [1] Actualizar repositorio local
n [2] Crear rama local para la tarea en la que se va a trabajar
n [3] Quizás descomponer las tarea en subtareas
n Cada subtarea un commit local
n [4] Reagrupar commits (subtareas) en (quizás) uno solo
n [5] Publicar commit de la rama local en el repositorio remoto
n [6] Volver a [1]
n Entre [3] y [4] es posible commutar a otras tareas que “surjan”
(e.g. arreglar un bug), creando las respectivas ramas locales
n Cada rama local (tarea) corresponde a una funcionalidad concreta,
la resolución de un bug, etc.
n O podemos crear ramas locales para las diferentes formas de
enfocar un problema, quedándonos finalmente con la rama que
más nos guste
1-7
Introducción
n Sistemas de control de versiones distribuidos: un segundo
escenario
n Flujo de trabajo distribuido con integrador
...
Repo
local
Repo
local ... Repo
local
1-8
Introducción
n Sistemas de control de versiones distribuidos: flujo de trabajo
distribuido con integrador (cont)
n Idea: un desarrollador (o varios) juega el papel de integrador:
revisa el código del resto de desarrolladores, quizás lo mejora, y lo
integra en la versión oficial del proyecto
n Repositorios remotos
n Existe un repositorio remoto con la versión “oficial” del proyecto
(repositorio remoto principal)
n El integrador puede leer y publicar en él
n El resto de desarrolladores sólo pueden leer
n El resto de desarrolladores tienen sus propios repositorios remotos
n Cada desarrollador clona el repositorio oficial en su repositorio remoto
n El integrador (y posiblemente el resto de desarrolladores) pueden leer del
repositorio remoto de cada desarrollador
1-9
Introducción
n Sistemas de control de versiones distribuidos: flujo de trabajo
distribuido con integrador (cont)
n Implementa sus tareas, las publica en el repositorio remoto
y se lo notifica al integrador
n El integrador lee del repositorio remoto del desarrollador,
1 - 10
Introducción
n Sistemas de control de versiones distribuidos: un tercer
escenario
n Flujo de trabajo distribuido “Dictator and Lieutenants”
n Idea: un integrador principal (dictador) delega sus funciones en
varios integradores secundarios (tenientes)
n Como el escenario anterior, pero con una jerarquía de integradores
n Aplicable a proyectos muy grandes con muchísimos desarrolladores
n El ejemplo más famoso: el kernel de Linux
1 - 11
Introducción
n Sistemas de control de versiones distribuidos: Flujo de trabajo
distribuido “Dictator and Lieutenants” (cont)
...
Repo remoto Repo remoto
Lieutenant 1 Repo
local Lieu 1 ... Lieu i
Repo
local
Lieutenant i
... ...
Repo remoto
Repo
local
Repo remoto
des 1
... des k
Repo
local
Desarrollador 1 Desarrollador k
1 - 12
Introducción
n Conclusiones
n Con los sistemas de control de versiones distribuidos
n Es posible trabajar con un solo repositorio remoto al estilo de
los sistemas de control de versiones centralizados
n Pero con un flujo de trabajo mucho más rico (ramas locales) y con
las ventajas de trabajar sobre un repositorio local
n Es posible que un desarrollador (o un grupo) actúe como
integrador
n Es posible tener una jerarquía de integradores (en proyectos
muy grandes)
n Linus Torvalds creó la versión inicial de Git para dar solución
al control de versiones del kernel de Linux
1 - 13
Lo más básico
n Grafo de commmits
n Estados de un fichero
n Clonar un repositorio
n Configuración
n Interacción básica
1 - 14
Grafo de commits
n Un repositorio se modela como un grafo dirigido acíclico de nodos
n Nodos: commit
n Arcos (vértices): punteros a los nodos padre
n Un nodo con más de un padre, representa un merge
n La mayor parte de los comandos de Git están orientados a actuar sobre el
grafo del repositorio local
n El resto de comandos permiten sincronizar el repositorio local con el remoto
C8 master
experiment C7
refactoring
C6
C5 C4
C3
C2
C1
C0
1 - 15
Grafo de commits
n Entre otras cosas, un commit consta de
n Un identificador único a nivel global (e.g.
8fc64199ee1f8c3b949c6bdf0fa1f4d057f1a220)
n Es un código hash SHA-1 (40 caracteres hexadecimales) calculado a partir del
contenido del commit
n No puede haber dos commits distintos, en el mismo o diferentes repositorios,
locales o remotos, con el mismo identificador
n Por sencillez, podemos emplear los primeros (como mínimo 4) caracteres (e.g.
8fc6419) para referirnos a un commit, siempre y cuando no haya otro commit
en el repositorio cuyo identificador empiece por el mismo prefijo
n Un puntero a una imagen virtual (“snapshot”) del proyecto tras ese commit
(es decir, cómo queda el proyecto tras ese cambio)
n Autor y mensaje
n Uno o varios punteros a los commits padre
n Es posible crear ramas locales
n Una rama es un puntero a un commit
n Conceptualmente, una rama representa un camino particular en el grafo
n Tras clonar un repositorio, existe la rama local master
1 - 16
Directorio de trabajo, staging area y .git
n Directorio de trabajo
n Directorio del proyecto
n Contiene la imagen de una versión concreta del proyecto, es
decir, la snapshot del proyecto asociada a un commit
(normalmente el último de la rama actual)
n Staging area (index)
n Contiene información de lo que irá en el siguiente commit
(ficheros nuevos, ficheros existentes modificados, ficheros
existentes eliminados)
n .git
n Contiene el repositorio local
n Ubicado en el directorio raíz del proyecto
1 - 17
Estados de un fichero
1 - 18
Clonar un repositorio
1 - 19
Configuración
1 - 20
Configuración: ignorar cambios
# Eclipse configuration.
.classpath
.project
.settings/
1 - 21
Interacción básica
n Tarea: añadir un caso de uso en la capa modelo a un proyecto
n Añadir useCase a la interfaz (ya existente) ModelService
n useCase requiere una nueva entidad y su DAO (en un paquete
nuevo)
n Entity
n EntityDao
n EntityDaoHibernate
n Añadir useCase a la clase (ya existente) ModelServiceImpl
n Añadir testUseCase a la clase (ya existente)
ModelServiceTest
n Edición (e.g. con un IDE)
n Añadir Entity, EntityDao y EntityDaoHibernate
n Modificar ModelService, ModelServiceImpl y
ModelServiceTest
1 - 22
Interacción básica: hacer un commit
n git status
# On branch 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: src/main/java/.../ModelService
# modified: src/main/java/.../ModelServiceImpl.java
# modified: src/test/java/.../ModelServiceTest.java
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# src/main/java/.../entity/
no changes added to commit (use "git add" and/or "git commit -a")
1 - 23
Interacción básica: hacer un commit
n git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: src/main/java/.../entity/Entity.java
# new file: src/main/java/.../entity/EntityDao.java
# new file: src/main/java/.../entity/EntityDaoHibernate.java
# modified: src/main/java/.../ModelService.java
# modified: src/main/java/.../ModelServiceImpl.java
# modified: src/test/java/.../ModelServiceTest.java
#
1 - 24
Interacción básica: hacer un commit
n Comprobar build correcta
n git commit
Explicación breve.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: src/main/java/.../entity/Entity.java
# new file: src/main/java/.../entity/EntityDao.java
# new file: src/main/java/.../entity/EntityDaoHibernate.java
# modified: src/main/java/.../ModelService.java
# modified: src/main/java/.../ModelServiceImpl.java
# modified: src/test/java/.../ModelServiceTest.java
#
1 - 25
Interacción básica: hacer un commit
Repositorio
local
Repositorio
local C2 master
master C1
git commit C1
C0
C0
1 - 26
Interacción básica: hacer un commit
1 - 27
Interacción básica: rectificar
1 - 28
Interacción básica: visualizar
n git diff
n Visualizar diferencias
n git log
n Visualizar log de commits
1 - 29
Interacción básica: herramientas gráficas
1 - 30
Interacción básica: publicar cambios
n Normalmente, después de un git clone
n Git asocia la URL del repositorio remoto con el nombre origin
n git remote add permite añadir repositorios remotos adicionales (a
cada uno se le asocia un nombre)
n Crea la rama local master, que inicialmente apunta al mismo sitio
que la rama remota master
n En el repositorio local, las ramas remotas se representan con ramas
locales especiales con la forma <nombre-repo-remoto>/<rama-
remota> (e.g. origin/master)
Repositorio
local
Repositorio
remoto (origin) origin/master C1 master
master C1
git clone url-repo-remoto C0
C0
1 - 31
Interacción básica: publicar cambios
n Publicar cambios de la rama master local a la rama master de
origin
n git push origin master
n Después de un git clone, normalmente la rama local master
está configurada para enviar/recibir los cambios de la rama remota
master del repositorio origin
n En consecuencia, si estamos en la rama master, basta hacer git
push
Repositorio Repositorio
local remoto (origin)
C1 C1
git push
C0 C0
1 - 32
Interacción básica: publicar cambios
n Si alguien hizo un push antes, git push fallará
n Porque el padre de C2 es C1, y el último commit de la rama
master en origin es C3 (y no C1)
Repositorio Repositorio
local remoto (origin)
master C2 C3 master
origin/master C1 C1
git push
C0 C0
1 - 33
Interacción básica: publicar cambios
n Si alguien hizo un push antes, git push fallará
(cont)
n Actualizar ramas master y origin/master
n git pull origin master
n Si estamos en master, basta git pull
n Ocurre un merge
n Arreglar conflictos si necesario
n Modificar ficheros en conflicto
n git add <ficheros en conflicto>
n git commit
n Comprobar build correcta
n git push
1 - 34
Interacción básica: publicar cambios
Repositorio local repositorio remoto (origin)
master C4
C2 C3 origin/master C3 master
git pull C1
C1
[git add+commit]
C0 C0
C2 C3 C2 C3
C1 C1
git push
C0 C0
1 - 35
Interacción básica: publicar una versión
n Etiquetar un commit
n git tag <nombre-tag>
n Publicar un tag
n git push <nombre-repo-remoto> <nombre-tag>
n Publicar una versión del software en master. Ejemplo
n [1] git tag 1.0.0
n [2] git push origin 1.0.0
Repositorio Repositorio
local remoto (origin)
master
C2 1.0.0 1.0.0 C2 master
origin/master
[1] [2]
C1 C1
C0 C0
1 - 36
Interacción básica: ayuda
n Ayuda
n git help <verb>
n man git-<verb>
1 - 37
Desarrollo de tareas pequeñas
n Tarea pequeña
n La hace un único desarrollador en “poco” tiempo
n Ejemplos
n Implementar un caso de uso (o parte)
n Arreglar un bug
n Hacer una mejora pequeña
n Cada tarea la haremos en una rama local
n Sólo existe en el repositorio local
n Pueden tenerse tantas como se quieran
n Podemos trabajar en varias tareas distintas a la vez
n A veces las tareas tienen finalidades distintas (e.g. arreglar un
bug, implementar otro caso de uso, etc.) o la misma (e.g.
distintas formas de enfocar un problema, eligiendo finalmente
la que más nos guste)
1 - 38
Desarrollo de tareas pequeñas: ramas locales
1 - 39
Desarrollo de tareas pequeñas: flujo de trabajo propuesto
C3 caso-de-uso
Repositorio
local
[2] + [3]
C2
master [1] master
origin/master C1 caso-de-uso origin/master C1
C0 C0
1 - 40
Desarrollo de tareas pequeñas: flujo de trabajo propuesto
1 - 41
Desarrollo de tareas pequeñas: flujo de trabajo propuesto
1 - 42
Desarrollo de tareas pequeñas: flujo de trabajo propuesto
# This is a combination of 2 commits.
# The first commit's message is:
[Explicación detallada]
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Not currently on any branch.
# You are currently editing a commit during a rebase.
#
# Changes to be committed:
# (use "git reset HEAD^1 <file>..." to unstage)
#
# modified: ...
# ...
1 - 43
Desarrollo de tareas pequeñas: flujo de trabajo propuesto
Repositorio
local
C3 caso-de-uso
C2 caso-de-uso~1 C4 caso-de-uso
master master
C0 caso-de-uso~3 C0
1 - 44
Desarrollo de tareas pequeñas: flujo de trabajo propuesto
1 - 45
Desarrollo de tareas pequeñas: flujo de trabajo propuesto
Repositorio
local
origin/master C6
origin/master C6
master master
C5 C4 caso-de-uso
C5
C1
C1
C0
C0
1 - 46
Desarrollo de tareas pequeñas: flujo de trabajo propuesto
1 - 47
Desarrollo de tareas pequeñas: flujo de trabajo propuesto
Repositorio
local
origin/master C6 C6
C5 C5
git push
C1 C1
C0 C0
1 - 48
Desarrollo de tareas pequeñas: flujo de trabajo propuesto
n Observaciones
n Podemos trabajar en varias tareas a la vez
n Cada tarea en una rama
n Antes de pasar a otra tarea (git checkout otra-tarea),
el directorio actual tiene que estar limpio
n Si no lo está => git add+commit (ya reagruparemos luego)
n Integración en la rama remota (master, en este caso)
n La integración de tareas pequeñas en la rama remota es lineal
(más sencillo de entender)
1 - 49
Desarrollo de tareas grandes
n Tarea grande
n La llevan a cabo varios desarrolladores colaborativamente
n Ejemplos
n Una nueva característica compleja
n Un refactoring importante de código
n [En el laboratorio] Una tarea que desarrollan todos los
miembros del grupo en un ordenador durante la clase, pero
que no da tiempo a completar, y que se desea terminar
colaborativamente fuera de clase
n Idea
n [1] Uno de los desarrolladores
n Crea una rama local para la tarea
n Opcionalmente, publica uno o varios commits en esa rama local
n Publica la rama local de la tarea en el repositorio remoto => se
crea una rama remota
1 - 50
Desarrollo de tareas grandes
n Idea (cont)
n [2] Todos los desarrolladores (inclusive el que creó la rama
remota)
n Crean una rama local para la rama remota de la tarea de tipo “tracking
branch”
n push en esa rama local envía commits a la rama remota
n pull en esa rama local recibe commits de la rama remota
n Publican commits en la rama local usando el flujo de la interacción
básica o (más profesionalmente) el flujo de desarrollo de tareas
pequeñas
n Usan push para publicar los commits locales a la rama remota
n Usan pull para recibir los nuevos commits de la rama remota
n [3] Cuando la tarea está completada
n Uno de los desarrolladores, hace un merge de la rama de la tarea
sobre la rama de integración principal (master)
1 - 51
Desarrollo de tareas grandes: flujo
1 - 52
Desarrollo de tareas grandes: flujo
Repositorio
local
tarea-grande C2 tarea-grande
C2
master master
origin/tarea-grande
origin/master C1 origin/master C1
C0 C0
1 - 53
Desarrollo de tareas grandes: flujo
n [2] Todos los desarrolladores
n Crean una rama local para la rama remota de la tarea de tipo
“tracking branch”
n Sólo el que creó la rama remota
n git checkout master
n git branch -D tarea-grande
n git checkout tarea-grande
n Asumiendo que no exista esta rama local y que sólo un repositorio
remoto (origin en nuestro caso) tenga la rama con el nombre
tarea-grande, se crea automáticamente la rama local tarea-
grande de tipo “tracking branch” y se hace un checkout
n El resto
n git fetch
n Trae los objetos nuevos de origin (por defecto)
1 - 54
Desarrollo de tareas grandes: flujo
Repositorio
local
C2 origin/tarea-grande
master
master
origin/master C1
origin/master C1
C0
C0
git fetch
1 - 55
Desarrollo de tareas grandes: flujo
Repositorio
local
tarea-grande*
C2 origin/tarea-grande
C2
master origin/tarea-grande
master
origin/master C1 origin/master C1
C0 C0
1 - 56
Desarrollo de tareas grandes: flujo
n [2] Todos los desarrolladores (cont)
n Publican commits en la rama local usando el flujo de la
interacción básica o (más profesionalmente) el flujo de
desarrollo de tareas pequeñas (creando las respectivas
ramas locales e integrando en la rama de la tarea grande)
n Usan la rama de la tarea grande como rama de integración, en
lugar de la rama de integración principal (master)
n Publican commits locales a la rama remota: git push
n Reciben los nuevos commits de la rama remota: git pull
1 - 57
Desarrollo de tareas grandes: flujo
Repositorio
local
tarea-grande*
C3 tarea-grande* C3
origin/tarea-grande
C2 origin/tarea-grande C2
master master
origin/master C1 origin/master C1
C0 C0
git push
1 - 58
Desarrollo de tareas grandes: flujo
1 - 59
Desarrollo de tareas grandes: flujo
Repositorio
local
master
tarea-grande* C3 tarea-grande*
C3
origin/master C4
origin/tarea-grande
origin/tarea-grande
C2 C2
master
origin/master C1 C1
C0 C0
1 - 60
Desarrollo de tareas grandes: flujo
Repositorio
local
master
C5 origin/master
master
C3 tarea-grande*
origin/master C4 C3 tarea-grande*
origin/tarea-grande C4
C2 origin/tarea-grande
C2
C1
C1
C0
C0
1 - 62
Otros flujos de trabajo
n Contribuir a un proyecto en el que no se tiene derecho a hacer
push en el repositorio principal
n Clonar el repositorio remoto principal A
n Hacer un fork del repositorio remoto principal A en otro B al que sí
puede hacer push la persona que va contribuir
n Un fork es otro repositorio remoto que, inicialmente, es una copia
exacta
n Los gestores de repositorios Git (e.g. GitHub, Bitbucket, GitLab, etc.)
permiten hace forks de forma directa
n Añadir el repositorio B al repositorio local
n Crear una rama remota R en B para la tarea que se va a hacer
n Notificar al integrador cuando la tarea esté terminada
n El integrador agrega el repositorio B a su repositorio local e integra
(merge) la rama R en la principal
1 - 63
Más información
1 - 64