Tabla de Contenidos
Anexo: Sistemas de Control de Versiones
El control de versiones es un sistema que registra los cambios realizados sobre un archivo o conjunto de archivos a lo largo del tiempo, de modo que puedas recuperar versiones específicas más adelante.
Se usan para registrar cualquier tipo de archivos, y comparar cambios a lo largo del tiempo, revertir a un estado anterior del proyecto, ver en qué momento se introdujo un error, etc.
Tenemos dos arquitecturas principales a través de la que podemos clasificar distintos SCVs:
Arquitectura Centralizada
Los desarrolladores usan un repositorio central al que acceden mediante un cliente en su máquina. Tienen un único servidor que contiene todos los archivos versionados, y varios clientes que descargan los archivos desde ese lugar central. Durante muchos años éste ha sido el estándar para el control de versiones. La desventaja más obvia es el servidor centralizado como único punto de fallo. Si ese servidor se cae o pierde los datos, se pierde el trabajo.
- Subversion SVN (Código Abierto)
- Visual SourceSafe (Propietario)
Arquitectura Distribuida
En un SCV distribuido los clientes no sólo descargan la última instantánea de los archivos: suben completamente el repositorio. Cada vez que se descarga una instantánea (versión del proyecto), en realidad se hace una copia de seguridad completa de todos los datos. Así, si un servidor muere, cualquiera de los repositorios de los clientes puede copiarse en el servidor para restaurarlo.
- GIT (Codigo Abierto)
- Mercurial (Codigo Abierto)
GIT
Es un SCV distribuido creado como necesidad durante el desarrollo de núcleo de Linux. El creador es Linus Torvalds, creador también del núcleo de Linux.
Servidores de Repositorios
Para almacenar las versiones de nuestro código necesitamos un servidor de control de versiones basado en Git. Actualmente hay distintas opciones que ofrecen servicios comerciales y también servicios gratuitos, con algunas limitaciones, pero perfectamente válidos para trabajar en nuestros pequeños proyectos. Las versiones gratuitas de los siguientes servicios ofrecen:
- GitHub: repositorios públicos ilimitados.
- BitBucket: repositorios públicos y privados ilimitados.
- GitLab: repositorios públicos y privados ilimitados.
En nuestro caso usamos BitBucket porque permite la creación de repositorios privados, además de públicos como GitHub. Todos los servicios funcionan de forma similar y nos permite crear una cuenta de usuario gratuita.
Funcionamiento de Git
Git guarda una copia completa del estado de los ficheros de nuestro proyecto en cada versión (commit). Esta información se almacena en la base de datos local (repositorio local), y posteriormente se puede sincronizar con otros repositorios remotos.
En Git, los ficheros tienen 2 estados principales:
- Ficheros fuera de seguimiento (untracked)
- Ficheros bajo seguimiento (tracked)
- Ficheros Untracked. Cuando creo o añado ficheros nuevos a mi repositorio local estos están fuera de seguimiento. También están fuera de seguimiento los que no estaban bajo seguimiento en la última versión; último commit (confirmación).
Los ficheros que están bajo seguimiento pueden tener 3 estados (unmodified, staged, modified)
- Ficheros Staged (Preparados para confirmación) : Cuando añado ficheros untracked mediante el comando (git add) para que formen parte de la siguiente confirmación, estos pasan a estar pendientes de confirmación, preparados, (staged). Estos cambios no estarán confirmados hasta que haga commit.
- Ficheros unmodified (Sin modificar): Justo despues de hacer un commit (crear una versión), todos los ficheros que estaban pendientes de confirmación (staged), se almacenan en la base de datos local de Git. En ese momento todos los ficheros están sin ninguna modificación, que quiere decir que no hay modificaciones desde la última versión.
- Ficheros modified (Modificados): Si modifico un fichero unmodified, este pasará a estado modified indicando que debo de volver a añadirlo (git add) parar prepararlo (staged) para la siguiente confirmación (commit).
Todo este trabajo se realiza en el repositorio local y se almacena en la base de datos local de Git. Independientemente de esto, puedo sincronizar el estado de mi repositorio local (directorio en mi equipo), con un repositorio remoto (fuera de mi equipo).
Instalación y configuración de Git
Al configurar GIT por primera vez, como mínimo debemos configurar nuestra identidad para realizar commits (Confirmar una version). Esto se debe hacer una sola vez, después de instalar Git. Para ello abrimos un terminal Bash y ejecutamos:
git config --global user.name "Fernando Valdeon" git config --global user.email fvaldeon@email.com git config --list #Nos permite ver todas las propiedades de configuracion de Git.
Si no indico la opción - - global la configuración es solo para el repositorio local (Debo haber creado primero el repositorio local)
En el siguiente video-tutorial podemos ver como instalar y configurar GIT.
Manejo de Git
Para entender completamente el funcionamiento de Git debemos leer los capitulos 2 y 3 del libro Pro Git Book. Podemos descargarlo desde su web oficial en inglés o leerlo online en español.
En los siguientes dos videos se muestra el uso de las principales operaciones que nos ofrece Git junto con el servidor de repositorio BitBucket.
IMPORTANTE: Al crear un repositorio remoto en bitbucket, indicar no crear el fichero README.md.
Git ofrece tanto integración en un terminal de Windows (cmd), como en un terminal de Linux (Bash). Los siguientes comandos están centrados en el manejo del terminal de Linux (bash):
Comandos Bash | Función |
---|---|
ls | Muestra el contenido del directorio actual |
ls -a | Muestra el contenido del directorio actual con los fichero ocultos |
pwd | Muestra la ruta del directorio en el que estoy |
cd [directorio] | Me permita cambiar de directorio |
directorios . y .. | Representan el directorio actual y su padre, respectivamente |
rm [nombre_archivo] | Elimina un archivo |
rm -r [nombre directorio] | Elimina un directorio con su contenido |
touch [nombre_fichero] | Crea un fichero de texto plano con dicho nombre] |
mkdir [nombre_directorio] | Crea un directorio vacío con dicho nombre] |
clear | Limpia el terminal de comandos |
Trabajo en repositorio local
- Crear un repositorio local. Se ejecuta solo una vez, y con ello indico que en dicho directorio se llevará un control de versiones (se convierte en repositorio). Para ello crea un directorio oculto (.git) que contiene la información que Git necesita para registrar las versiones.
git init
- Estado actual del repositorio. Indica los cambios que ha habido en el directorio (repositorio) desde la última versión realizada. Muestra los nuevos ficheros añadidos al repositorio o fuera de seguimiento, los modificados y los eliminados, desde el último comit.
git status
- Incluir archivos o directorios para la siguiente versión. Permite añadir archivos que están fuera de seguimiento (untracked) o que han sido modificados (modified) y prepararlos para el siguiente commit.
git add [nombre_fichero_o_directorio] # Ó si quiero añadir todo el contenido de mi repositorio local: git add .
Mientras que no se confirmen (commit) las modificaciones, se puede restaurar el estado inicial con el comando git reset.
- Confirmar las modificaciones. Crea una nueva versión Con los archivos que están bajo seguimiento dentro de mi repositorio. Debemos indicar siempre un mensaje descriptivo.
git commit -m "Descripción del commit"
Sincronización repositorio local - remoto
- Sincronizar con un repositorio remoto. Añade las modificaciones que hay en mi repositorio local a un repositorio remoto, con el fin de tener los dos repositorios sincronizados (identicos). Debemos indicar la dirección de nuestro repositorio remoto (url) o su alias, si le hemos asignado uno.
git push [dirección_repositorio_remoto] master #Ejemplo git push https://bitbucket.org/fvaldeon/repopruebadam1 master
- Actualizar nuestro repositorio local con los cambios mas recientes que tiene uno remoto. Cuando nuestro repositorio remoto está más actualizado que nuestro mismo repositorio local, debido a que hemos sincronizado desde un repositorio local en otro equipo, debemos descargar los último cambios para incluirlos en nuestro repositorio local.
git pull [repositorio_remoto] master #Ejemplo git pull https://bitbucket.org/fvaldeon/repopruebadam1 master
Cuando hacemos git pull se descargan esos nuevos ficheros y se intentan unir con los ficheros de nuestro repositorio local. Desde el terminal de Git se abre el editor de texto de linux (Vi). Para salir de él pulsamos las teclas (:wq!).
- Obtener una copia de mi repositorio remoto. Usaré este comando cuando en mi ordenador no tengo una copia de mi repositorio. Uso la url de mi repositorio remoto para traerme una copia en local, y poder seguir trabajando. Esto genera un repositorio local idéntico al remoto.
git clone [repositorio_remoto] #Ejemplo git clone https://bitbucket.org/fvaldeon/repopruebadam1
Una vez que hayamos clonado un repositorio desde una url, dicha url se almacena como el alias origin
. Desde ese momento puedo omitir la url, y usar el alias origin
para hacer push o pull.
Gestión de repositorios remotos
Dentro de cada repositorio local de Git, puedo asociar la dirección de mi repositorio remoto a un alias. Así no necesito recordar la url, sino el alias.
- Añadir un repositorio remoto la gestión de Git de mi respositorio local.
git remote add [alias] [dirección_remoto]
- Como norma general en Git, el repositorio remoto con el que tengo pensado trabajar principalmente se llama origin:
git remote add origin [dirección_remoto]
- Mostrar los repositorios remotos vinculados a mi repositorio local.
git remote
- Además puedo mostrar mis repositorios remotos y mostrar su dirección.
git remote -v
Obtener versiones anteriores
Cuando queremos obtener una versión anterior de nuestro proyecto podemos consultar el log de nuestro repositorio local. Cada confirmación (commit) crea una versión. Al restaurar a una versión anterior, el estado (ficheros y directorios) de mi repositorio local se cambia por lo que había en el momento de crear dicha versión.
git log #Muestra un historial con las versiones git log --oneline #Muestra un historial resumido
Obtenemos la siguiente salida, que representa todos los commits realizados en mi repositorio local y el mensaje que se incluyó.
git log --oneline b8b6a2d (HEAD -> master, origin/master, origin/HEAD) Readme y gitignore actualizados e8ad0df LoginYFichConf y JListSuprimir subidos 0a46d10 Actualizado README 256d909 Proyecto VehiculosMVC terminado ffa9848 Correccion en la organizacion de packages 3dee7c5 Proyecto terminado. No guarda ni carga en fichero.
Si nos fijamos en el código generado en cada confirmación (columna de la izquierda), podemos emplearlos para restaurar una versión anterior:
git checkout 3dee7c5
También podemos restaurar únicamente un archivo a una versión anterior:
git checkout 3dee7c5 prueba.txt
Ignorar archivos en las versiones
Es bastante frecuente que en los proyectos que tengo en mi repositorio local tengo archivos o directorios que no quiero tener en seguimiento(versiones). Es el caso del directorio /bin o de los ficheros .class de Java.
El fichero .gitignore es un fichero de texto que podemos crear en nuestro repositorio local y que indica qué ficheros se excluirán del seguimiento y sincronización con nuestro repositorio remoto.
- .gitignore
# Ficheros generados Java *.class # Carpetas que contienen ficheros generados bin/ out/
El fichero .gitignore debería ser sincronizado con el resto de ficheros del repositorio remoto.
Borrar archivos de las versiones
- Borrar archivos ya confirmados. Si tengo actualmente ficheros en mis versiones que no quiero que sigan en mi proyecto, debo borrarlos de git y posteriormente volver a confirmar. Debo tener en cuenta que dichos archivos también desaparecerán de mi repositorio local.
git rm [fichero] git rm -r [directorio con archivos] git commit -m "Archivos borrados"
- Eliminar archivos de la versión. Se usa cuando lo que quiero es únicamente eliminar algunos archivos de las versiones de git, pero quiero que permanezcan en mi repositorio local. Es normalmente útil cuando se me olvida incluir algo en mi fichero .gitignore
git rm -r --cached [fichero o directorio]
Trabajar con ramas
- Crear una nueva rama
git branch develop
- Cambiar de rama
git checkout develop
- Fusionar ramas
git checkout master git merge develop
Con el siguiente tutorial interactivo podemos practicas todos los conceptos visto aquí y también el manejo con ramas: https://learngitbranching.js.org/
Git como Herramienta de Despliegue
ToDO
© 2024 Fernando Valdeón