03 Git
03 Git
Sistemas de control de versiones: git Se llama control de versiones a la gestión de los cambios que se realizan
sobre documentos, programas o cualquier colección de información.
Rodrigo Lugones
Ejemplos en la vida real:
• Cuaderno de laboratorio.
rlugones@[Link] • Ediciones y revisiones de un libro.
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 1 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 2 / 53
¿Por qué realizar un control de versiones? Curiosidad: ¿cuántas lı́neas de código manejamos?
• Script propio para calcular algunas cosas: ∼ 100
• Código grande propio: ∼ 1 mil
• Aplicación de celular: ∼ 30 mil
• Transbordador espacial: ∼ 400 mil
• Linux Kernel 2.2.0 (1999): ∼ 1,5 millones
• Telescopio Hubble: ∼ 2 millones
El control de versiones le da trazabilidad a nuestro trabajo.
• Google Chrome: ∼ 6,5 millones
¿Y? ¿Para qué queremos eso?
• Mozilla Firefox: ∼ 9,5 millones
• Android: ∼ 12 millones
• Linux Kernel 3.1 (2011): ∼ 15 millones
• Windows 7: ∼ 40 millones
• Large Hadron Collider: ∼ 50 millones
• Facebook: ∼ 60 millones
• Software de un auto: ∼ 100 millones
• Google: ∼ 2000 millones
Fuente
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 3 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 4 / 53
Curiosidad: ¿cuántas lı́neas de código manejamos? Curiosidad: ¿cuántas lı́neas de código manejamos?
• Script propio para calcular algunas cosas: ∼ 100 • Script propio para calcular algunas cosas: ∼ 100
• Código grande propio: ∼ 1 mil • Código grande propio: ∼ 1 mil
• Aplicación de celular: ∼ 30 mil • Aplicación de celular: ∼ 30 mil
• Transbordador espacial: ∼ 400 mil • Transbordador espacial: ∼ 400 mil
• Linux Kernel 2.2.0 (1999): ∼ 1,5 millones • Linux Kernel 2.2.0 (1999): ∼ 1,5 millones
• Telescopio Hubble: ∼ 2 millones • Telescopio Hubble: ∼ 2 millones
• Google Chrome: ∼ 6,5 millones • Google Chrome: ∼ 6,5 millones
• Mozilla Firefox: ∼ 9,5 millones • Mozilla Firefox: ∼ 9,5 millones
• Android: ∼ 12 millones • Android: ∼ 12 millones
• Linux Kernel 3.1 (2011): ∼ 15 millones • Linux Kernel 3.1 (2011): ∼ 15 millones
• Windows 7: ∼ 40 millones • Windows 7: ∼ 40 millones
• Large Hadron Collider: ∼ 50 millones • Large Hadron Collider: ∼ 50 millones
• Facebook: ∼ 60 millones • Facebook: ∼ 60 millones
• Software de un auto: ∼ 100 millones • Software de un auto: ∼ 100 millones
• Google: ∼ 2000 millones • Google: ∼ 2000 millones
Fuente Fuente
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 4 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 4 / 53
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 5 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 6 / 53
Un ejemplo concreto Un ejemplo concreto
Opción 1: Lo más común
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 6 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 7 / 53
1 NS_Solver_Euler
2 NS_Solver_Euler_y_grafico_E
1 $ cat [Link]
2 1: Navier-Stokes con metodo de Euler
3 2: Navier-Stokes con metodo de Euler y grafico de Energia.
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 7 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 8 / 53
Un ejemplo concreto Un ejemplo concreto
Este podrı́a considerarse un casero y primitivo sistema de control de Este podrı́a considerarse un casero y primitivo sistema de control de
versiones. versiones.
Ahora, ¿qué pasarı́a si en la versión 19 del programa encontráramos un Ahora, ¿qué pasarı́a si en la versión 19 del programa encontráramos un
bug que existı́a desde la versión 1? bug que existı́a desde la versión 1?
Si bien podrı́amos pensar soluciones, vemos que los problemas se Si bien podrı́amos pensar soluciones, vemos que los problemas se
multiplican a medida que el proyecto crece. La solución es utilizar alguna multiplican a medida que el proyecto crece. La solución es utilizar alguna
herramienta especializada en controlar versiones. herramienta especializada en controlar versiones.
Hay una infinidad de posibilidades (Mercurial, Subversion, etc). Nos vamos Hay una infinidad de posibilidades (Mercurial, Subversion, etc). Nos vamos
a concentrar en una, la más extendida: git a concentrar en una, la más extendida: git
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 9 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 9 / 53
Este podrı́a considerarse un casero y primitivo sistema de control de La ventaja de utilizar las herramientas adecuadas para el objetivo que uno
versiones. quiere lograr es que, de alguna forma, favorecen (o hasta imponen) una
Ahora, ¿qué pasarı́a si en la versión 19 del programa encontráramos un filosofı́a de trabajo.
bug que existı́a desde la versión 1? Con git vamos a poder:
1 Hacer backup de estados consistentes del proyecto
Si bien podrı́amos pensar soluciones, vemos que los problemas se
multiplican a medida que el proyecto crece. La solución es utilizar alguna
2 Documentar cambios
herramienta especializada en controlar versiones. 3 Seguir los bugs a través de la historia del desarrollo
Hay una infinidad de posibilidades (Mercurial, Subversion, etc). Nos vamos
4 Compartir cambios
a concentrar en una, la más extendida: git 5 Distribuir el desarrollo a muchas personas
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 9 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 10 / 53
Git: Una filosofı́a de trabajo Git: Una filosofı́a de trabajo
¿Y cómo funciona git? ¿Y cómo funciona git?
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 11 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 11 / 53
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 12 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 13 / 53
Git: Una filosofı́a de trabajo Git: Una filosofı́a de trabajo
• Un archivo está en estado no-modificado cuando es exactamente • Un archivo está en estado no-modificado cuando es exactamente
igual al archivo que está guardado en el último snapshot. igual al archivo que está guardado en el último snapshot.
• Modificar un archivo (por ejemplo, cambiar el nombre de una • Modificar un archivo (por ejemplo, cambiar el nombre de una
variable) lo transforma, evidentemente, en un archivo modificado. variable) lo transforma, evidentemente, en un archivo modificado.
• Pero, y esto es muy importante, git no hace seguimiento a un archivo • Pero, y esto es muy importante, git no hace seguimiento a un archivo
sólo porque está en estado modificado. Para que git se haga cargo sólo porque está en estado modificado. Para que git se haga cargo
del archivo modificado lo tenemos que actualizar (o, el término en del archivo modificado lo tenemos que actualizar (o, el término en
inglés, stage). Con todos los archivos actualizados, podemos inglés, stage). Con todos los archivos actualizados, podemos
consolidar el cambio y, en consecuencia, tomar un nuevo snapshot. consolidar el cambio y, en consecuencia, tomar un nuevo snapshot.
• Al hacer esto, los archivos que estaban actualizados ahora forman • Al hacer esto, los archivos que estaban actualizados ahora forman
parte del nuevo snapshot, que pasa a ser el nuevo HEAD del repositorio. parte del nuevo snapshot, que pasa a ser el nuevo HEAD del repositorio.
Es decir que consolidar cambios actualiza automáticamente el HEAD Es decir que consolidar cambios actualiza automáticamente el HEAD
del repositorio, y de esta manera los archivos que se encontraban en del repositorio, y de esta manera los archivos que se encontraban en
el estado actualizado pasan al estado no-modificado. el estado actualizado pasan al estado no-modificado.
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 13 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 13 / 53
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 14 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 15 / 53
Repositorios de git: crear repositorio Repositorios de git: estado de un repositorio
Crear un repositorio
El primer paso es la ardua tarea de crear el repositorio. Para eso creamos Estado de un repositorio
una carpeta en la que queremos iniciar nuestro trabajo (y cambiamos el Para saber en qué estado se encuentra un repositorio:
directorio a esa carpeta) y ejecutamos:
1 $ git init . 1 $ git status
2 On branch master
Esta carpeta va a ser considerada un repositorio de git. 3 No commits yet
¿Y dónde está guardada toda la información del repositorio? 4 nothing to commit (create/copy files and use "git add" to track)
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 16 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 17 / 53
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 18 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 19 / 53
Repositorios de git: agregar archivos Repositorios de git: agregar archivos
Noten dos cosas: El mensaje working directory clean nos dice que no hay archivos en estado
• El flag -m, seguido del mensaje de commit. El mensaje de commit es modificado, ya que el archivo [Link] (que no volvimos a tocar) es
obligatorio. igual al que está guardado en HEAD.
• El commit hash (número hexadecimal, 13aa40c), con el que podemos
referirnos a este snapshot.
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 20 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 21 / 53
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 22 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 23 / 53
Repositorios de git: continuar trabajando Repositorios de git: historia de los snapshots
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 24 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 25 / 53
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 26 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 27 / 53
Repositorios de git: visitar snapshots Repositorios de git: visitar snapshots
Veamos qué hay en la carpeta. Veamos qué hay en la carpeta.
1 $ ls 1 $ ls
2 [Link] 2 [Link]
¿¡CÓMO!? ¿¡Y DÓNDE ESTÁ graficar_E.py!? ¡Perdı́ dos semanas ¿¡CÓMO!? ¿¡Y DÓNDE ESTÁ graficar_E.py!? ¡Perdı́ dos semanas
escribiendo el script para graficar! escribiendo el script para graficar!
Recordemos que el archivo graficar_E.py no existı́a en este snapshot. El Recordemos que el archivo graficar_E.py no existı́a en este snapshot. El
HEAD dejó de ser 9b72f8b y pasó a ser 13aa40c. HEAD dejó de ser 9b72f8b y pasó a ser 13aa40c.
Si ahora queremos volver al snapshot donde está implementado el gráfico Si ahora queremos volver al snapshot donde está implementado el gráfico
de la energı́a, ejecutamos de la energı́a, ejecutamos
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 27 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 27 / 53
Repositorios de git: comentarios antes de continuar Repositorios de git: comentarios antes de continuar
• Los commits son análogos a nuestro SCV casero: Desarrollar una • Los commits son análogos a nuestro SCV casero: Desarrollar una
nueva funcionalidad (consolidar una nueva carpeta en el SCV casero) nueva funcionalidad (consolidar una nueva carpeta en el SCV casero)
lleva mucho tiempo. Entonces, tiene sentido hacer commits lleva mucho tiempo. Entonces, tiene sentido hacer commits
intermedios (no los hacı́amos con el SCV casero porque es mucho intermedios (no los hacı́amos con el SCV casero porque es mucho
laburo). laburo).
• Identifiquen commits “interesantes”: Vamos a tener ciertos • Identifiquen commits “interesantes”: Vamos a tener ciertos
commits que vamos a querer destacar (por ejemplo, nueva commits que vamos a querer destacar (por ejemplo, nueva
funcionalidad totalmente implementada). Para acceder a ellos funcionalidad totalmente implementada). Para acceder a ellos
fácilmente sin necesidad de recordar el hash, podemos etiquetarlos: fácilmente sin necesidad de recordar el hash, podemos etiquetarlos:
git tag v1.0 9b72 git tag v1.0 9b72
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 28 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 28 / 53
Repositorios de git: comentarios antes de continuar Repositorios de git: comentarios antes de continuar
• Sean descriptivos con los commit messages: • Sean descriptivos con los commit messages:
• No hagan un seguimiento de todos los archivos: Los archivos que • No hagan un seguimiento de todos los archivos: Los archivos que
seguimos son los archivos fuente (el código, algún archivo de seguimos son los archivos fuente (el código, algún archivo de
configuración), y no los archivos que se generan a través de la configuración), y no los archivos que se generan a través de la
compilación o ejecución del programa. ¿Y cómo hacemos eso? compilación o ejecución del programa. ¿Y cómo hacemos eso?
Mediante la creación de un archivo, .gitignore Mediante la creación de un archivo, .gitignore
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 29 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 29 / 53
1 $ cat .gitignore
2 # Un comentario. Esta linea es ignorada.
3 # Ningun archivo *.a
4 *.a
5
6 # Pero trackear lib.a, aunque este ignorando los archivos *.a Los grafos de git
7 !lib.a
8
9 # Ignorar archivo TODO, pero no los subdir/TODO
10 /TODO
11
12 # Ignorar todos los archivos en el directorio build/
13 build/
14 # Ignorar archivos doc/*.txt, pero no los doc/server/[Link]
15 doc/*.txt
16 # Ignorar archivos .txt en el directorio doc/ y los subdirectorios
17 doc/**/*.txt
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 30 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 31 / 53
Repositorios de git: la historia como un grafo Repositorios de git: ramas
Ramas
Compliquemos las cosas. Ahora queremos implementar dos funcionalidades
Con estas herramientas y conceptos fundamentales, podemos avanzar un “al mismo tiempo”:
poco más en el entendimiento y la visualización de la historia de un • Crear una pelı́cula que grafique el paso del agua
repositorio.
• Implementar el método numérico Runge-Kutta de orden 4 (en lugar
Usualmente, para ver la historia de un repositorio se utilizan grafos. En
de Euler)
nuestro ejemplo, tendrı́amos la siguiente situación
HEAD
Gráficamente, podemos pensarlo ası́.
13aa ....... 9b72 ????
RK4
NS Euler Graficar E HEAD
Esta visualización del repositorio nos da una mejor idea del desarrollo del 13aa ....... 9b72
código. Para visualizarla en la consola, escribimos git log --graph NS Euler Graficar E
????
Película
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 32 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 33 / 53
Ahora bien, ¿cómo lo hacemos? Mediante la utilización de ramas (branch). Para posicionarnos en la nueva rama, simplemente ejecutamos
Para crear una rama llamada rungekutta4, ejecutamos
1 $ git checkout rungekutta4
1 $ git branch rungekutta4 2 $ git branch
2 $ git branch #esto imprime las ramas existentes 3
3 4 master
4 * master 5 * rungekutta4
5 rungekutta4
master rungekutta4*
master* rungekutta4
13aa ....... 9b72
13aa ....... 9b72 NS Euler Graficar E
NS Euler Graficar E
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 34 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 35 / 53
Repositorios de git: ramas Repositorios de git: ramas
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 36 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 37 / 53
Unir las ramas exige un nuevo snapshot. O sea, cuando hacemos merge nos
pide un commit message.
58d2 3dd1 HEAD
RK4 master*
rungekutta4
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 38 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 39 / 53
Repositorios de git: unir ramas Repositorios de git
Es buena costumbre borrar las ramas una vez que se dejaron de utilizar:
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 40 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 41 / 53
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 42 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 43 / 53
Flujo de trabajo Flujo de trabajo
1 2 6'
main dev
exp. feat.
4''
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 44 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 45 / 53
2.1
2.1.1
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 46 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 47 / 53
Flujo de trabajo: bugs Flujo de trabajo: bugs
¿Y si en la versión 19 del programa nos damos cuenta de que arrastramos ¿Y si en la versión 19 del programa nos damos cuenta de que arrastramos
un bug desde la versión 1? un bug desde la versión 1?
! 2.1 ! 2.1
Bug Bug
Creo una nueva rama para corregir el bug, y lo corrijo en donde Creo una nueva rama para corregir el bug, y lo corrijo en donde
aparece por primera vez. De esta forma, cuando uno ve la historia del aparece por primera vez. De esta forma, cuando uno ve la historia del
repositorio, sabe entre qué versiones estaba presente el bug. repositorio, sabe entre qué versiones estaba presente el bug.
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 47 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 47 / 53
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 48 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 49 / 53
Repositorios remotos Repositorios remotos
Flujo de trabajo
¿Y cómo se hacen?
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 50 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 51 / 53
Repositorios remotos
1 $ git pull
rlugones@[Link]
Una observación: git pull incorpora cambios de un repositorio remoto en
la rama actual. En su implementación por defecto, git pull es
simplemente git fetch seguido de git merge FETCH_HEAD
Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 52 / 53 Rodrigo Lugones Sistemas de control de versiones rlugones@[Link] 53 / 53