Previous slide Next slide Toggle fullscreen Open presenter view
Introducción a sistemas de control de versión distribuidos
Hugo O. Barrera <hugo@whynothugo.nl>
UNPSJB, Oct. 2024
Contenidos
Parte 1 :
Sistemas de control de versión distribuidos.
Git: conceptos y uso básico.
Parte 2:
Compartir cambios con git.
Forjas y platforms de colaboración.
Code Review.
Sistemas de control de versión
Control de versión ("version control"), también llamado:
control de revisión ("revision control")
control de fuentes ("source control")
gestión de código fuente ("source code management")
Sistemas de control de versión
Almacena versiones del mismo código a lo largo del tiempo.
Sistemas de control de versión
Permite:
Ver versiones anteriores del código.
Comparar diferencias entre versiones.
Revertir cambios.
Aplicar cambios de distintas fuentes.
Ejemplos
Wikipedia
Procesadores de texto
Hojas de cálculo
Editores colaborativos online
Sistemas de control de versión centralizados
Servidor central.
Un único punto de falla.
Requieren conectividad para ser usados.
Ejemplos
Wikipedia
SVN ("Apache Subversion")
CVS ("Concurrent Versions System")
Google Docs
Sistemas distribuidos
Ubicado en distintas computadoras.
No hay un servidor central.
Requieren coordinación entre participantes.
Sistemas de control de versión distribuidos
Cada desarrollador tiene una copia completa de todo:
Del código
Del historial de cambio.
Permite trabajar offline (incluyendo consultar historial).
Operaciones más rápidas (no necesita conectarse a un servidor)
No hay un único punto de fallas.
Backups implícitos.
Sistemas de control de versión distribuidos
Ejemplos
GNU Bazaar, bzr
git
Mercurial, hg
got
jujutsu, jj
git
git es un sistema de control de versión distribuido.
Creado para desarrollar Linux.
Enfocado en rapidez e integridad de datos.
Escala a miles de desarrolladores trabajando en paralelo.
El modelo no depende de ningún servidor.
Software libre y de código abierto (GPL-2.0-only
).
git
Git no guarda archivos, guarda cambios.
Patches
patch es un formato para representar cambios:
@@ -1,6 +1,6 @@
# git
-**git** es un sistema de control de versión distirbuido.
+**git** es un sistema de control de versión distribuido.
- Creado para desarrollar Linux.
- Enfocado en rapidez e integridad de datos.
Git no elimina archivos
deleted file mode 100644
@@ -1,8 +0,0 @@
-# git
-
-**git** es un sistema de control de versión distribuido.
-
-- Creado para desarrollar Linux.
-- Enfocado en rapidez e integridad de datos.
-- Escala a miles de desarrolladores trabajando en paralelo.
-- El modelo no depende de ningún servidor.
Git no elimina archivos
No es ideal para archivos binarios grandes.
Ver: git-annex
.
Repositorios
Directorio donde se guardan archivos y se rastrea sus cambios a lo largo del
tiempo.
Tiene un subdirectorio .git
, que contiene todo el historial de cambios y
otros metadatos.
Flujo de trabajo básico
Inicializar repositorio.
Escribir código.
Preparar cambios (git add
)
"Commitear" cambios (git commit
).
Modificar código.
Preparar cambios (git add
)
"Commitear" cambios (git commit
).
...
Los primeros dos pasos pueden intercambiarse en orden.
Flujo básico: Inicializar repositorio
Inicializar directorio actual:
git init
Inicializar otro directorio:
git init path/a/un/directorio/
En IDEs, editores o TortoiseGit:
Git Create Repository here
Flujo básico: Preparar cambios
Agregar cambios para la siguiente versión.
Equivalent a SQL INSERT
o UPDATE
dentro de una transacción.
Flujo básico: Preparar cambios
> git add -p
diff --git a/demo.md b/demo.md
index e440d87..ebc8717 100644
--- a/demo.md
+++ b/demo.md
@@ -1,6 +1,6 @@
-**git** es un sistema de control de versión distirbuido.
+**git** es un sistema de control de versión distribuido.
- Creado para desarrollar Linux.
- Enfocado en rapidez e integridad de datos.
(1/1) Stage this hunk [y,n,q,a,d,e,p,?]?
Flujo básico: Preparar cambios
git reset
deshace todos los git add
.
Flujo básico: Commitear cambios (git commit
).
Crea un nuevo "commit"; una nueva versión.
"Guarda" esta versión en el historial de cambios.
Equivalente a SQL COMMIT
.
Incluye un mensaje descriptivo.
Un "commit"
Una versión del código.
Cada commit tiene un o más commits ancestros.
Un "commit"
El identificador es un hash (SHA-256), e.g.:
af7b396becf4416d5bcadf60dacf18752e2daeba
Típicamente se usan 7-8 dígitos, e.g.: af7b396
Es el hash del contenido del commit junto con el hash de los commits
ancestros.
Integridad de los datos es una característica de primera clase.
Los números secuenciales no sirven en sistemas distribuidos.
Clonar un repositorio
git clone
permite clonar un repositorio existente.
Usa otros protocolos como transporte:
ssh
: seguro, el más común.
https://
: menos eficiente, generalmente sólo lectura.
git://
: inseguro, sin autenticación.
file://
: sólo funciona localmente.
...
Remotos ("remotes")
Un remoto es la ubicación de otra copia del repositorio.
Al clonar un repositorio, la copia nueva tiene un remoto origin
.
origin
apunta a la ubicación de donde se clonó el repositorio.
Información sobre remotos se guardan dentro de .git
.
Un repositorio puede tener cero, uno o más remotos.
Push y Pull
git push
: empuja (manda) commits a un remoto.
git pull
: trae commits de un remoto.
Por defecto, ambas operaciones interactúan con el remoto origin
.
Actividad 1
Clonar el repositorio https://git.sr.ht/~whynothugo/breadscript
.
Corregir los errores de ortografía en el archivo pan.md
.
Commitear los cambios.
Configuración básica
git config --global user.name "Hugo Osvaldo Barrera"
git config --global user.email "hugo@whynothugo.nl"
git config --global color.ui true
Actividad 1.2
¿Qué hace git log
?
¿Y git log -p
?
Actividad 1.3
¿Qué hace git blame pan.md
?
Actividad 1.3
Comparen commits entre participantes.
Divergencia
Juan crea un repositorio con 3 commits y lo publica.
María clona el repositorio y crea un cuarto commit.
Carlos clona el repositorio original, y crea otro cuarto commit.
Los commits de María y Carlos tienen los mismos ancestros, pero distinto hash.
Los números secuenciales no sirven en sistemas distribuidos.
Divergencia local: branches
Branches ("ramas") permiten trabajar en varias lineas de historia paralelas.
El branch predeterminado es main
/master
.
Hay un branch activo a la vez (git branch --show-current
).
HEAD
es una alias para "branch activo".
Permiten trabajar en distintas funcionalidades en paralelo.
Permite experimental sin afectar el branch main
.
Son la base para colaboración en equipo.
Branches
Un branch es un puntero a un commit.
El archivo .git/refs/heads/main
que contiene el id del commit.
Branches
Crear y activar un branch nuevo: git checkout -b mi_branch_nuevo
.
Activar un branch existente: git checkout main
En caso de conflictos, aborta la operación.
Branches remotos
Son branches que existen en un remoto.
Branches remotos
Los branches remotos son visible con git branch -a
.
Tienen el formato de origin/main
(o remotes/origin/main
).
git fetch
trae nuevos commits y branches remotos sin modificar el branch
activo.
Convergencia: unir dos branches
Dos mecanismos para conciliar dos branches:
Merge ("unir").
Rebase ("volver a base").
Merge ("unir")
Crea un commit con dos ancestros.
Es el mecanismo más sencillo.
El historial de versiones resultante es no-lineal.
Merge ("unir")
git merge OTRO_BRANCH
crea un nuevo commit en el branch actual.
Une al branch actual con OTRO_BRANCH
.
OTRO_BRANCH
permanece intacto.
El nuevo commit tiene dos ancestros.
Si hay conflictos, deben ser resueltos a mano.
Rebase ("volver a base")
Re-escribe commits, cambiando su ancestro.
Es más complejo en caso de muchos commits o muchos conflictos.
El historial de versiones resultantes es lineal.
Rebase ("volver a base")
git rebase OTRO_BRANCH
re-escribe la historia del branch actual.
Usa como base los commits presentes en OTRO_BRANCH
.
Agrega los commits que sólo están presentes en el branch actual.
Re-escribe la historia de estos commits para que sean lineares usando
OTRO_BRANCH
como base.
OTRO_BRANCH
permanece intacto.
Si hay conflictos, deben ser resueltos a mano.
Pueden haber conflictos en cada commit re-escrito.
Actividad 2
Usando el repositorio clonado...
Unir los cambios del branch origin/agua-tibia
.
Actividad 2.1
¿Qué hace git log --graph
?
Conflictos
Dos branches divergentes modifican la misma línea (o líneas cercanas).
Resolución de conflictos
Merge require resolver conflictos una sola vez.
Rebase require resolver conflictos por cada commit re-escrito que tenga
conflictos.
Merge tiende a ser más fácil.
Actividad 3
Usando el repositorio clonado...
Unir el branch origin/azucar
.
Puntero a un commit específico.
Opcionalmente, puede tener una firma digital.
Típicamente: releases.
git tag v1.0.0
git push origin v1.0.0
git push --tags
git fetch --tags
Random names
Juan
María
Carlos
Sofía
- Extra space at the beginning of unaltered lines.
- Some tools highlight changed words.
- Trivia: diff: June 1974, unified diff: January 1990.
- Nada es agregado implícitamente.
TODO: best practices for messages.
passive voice
explains WHAT it does, not HOW
TODO: leave visible commands here
Code editors allow surfacing blame info easily
TODO: it would be IDEAL to have a tree graph here!
- Al crear un nuevo commit en el branch actual, se actualiza el branch.
- Se puede modificar un branch para que apunte a un nuevo commit -> rewrite
history
TODO: example of what this looks like
TODO: do they need git-fetch here?
TODO: este branch cambia sólo la primera línea, sin conflicto con el ejercicio
anterior.
TODO: this branch needs to branch from `main`, and conflicts due to the changes
in `agua-tibia`.
TODO: git reset --hard was useful for going back when students make a mistake,
perhaps it should be explained to?
TODO: git rev-list --count HEAD
TODO: git commit --amend
TODO: rebase -i ?