22 enero 2013

De romances y asiaticas - ¿Qué es Git?... y un ejemplo.

Uno de los problemas con que uno se encuentra como desarrollador, es el de llevar el control del código fuente de sus programas.

Con seguridad les ha ocurrido alguna vez, que se encuentran trabajando un código, modifican un archivo y se dan cuenta que tal vez no era lo que querían hacer. Algo que luego de un tiempo se termina convirtiendo en una experiencia muy frustrante y estresante.

A causa de lo anterior, hace ya bastante tiempo se inventaron los denominados sistemas de versionado o de control el versión, estos programas nos permiten llevar el control de los archivos de código fuente de tal manera que podamos realizar modificaciones y regresar o modificar algo que habíamos editado previamente.

Durante algún tiempo estuve utilizando Subversion, sin embargo desde hace relativamente poco me topé con git. Este es un sistema de control de fuentes. desarrollado originalmente por Linus Torvalds para administrar las fuentes del Kernel de Linux y me parece extremadamente poderoso por varias razones que les explicaré en esta entrada.

En esta ocasión voy a tratar de comentarles algunos beneficios de un sistema de versionado, como este puede servirles incluso a otros profesionales ajenos a la informática y les explicaré con un ejemplo sencillo como utilizar la funcionalidad básica de git utilizando el ejemplo de "romances y asiaticas". Solo lamento defraudarlos ya que esta tampoco es una entrada sobre mujeres.

Habiendo dicho esto... ¡¡Comencemos!!

¿Por qué utilizar un sistema de versionado?


Un sistema de versionado es el SUEÑO de muchísimas personas. Imaginen que ustedes puedan llevar el registro de todos y cada uno de los cambios que se han hecho a un archivo o más importante aún, a un conjunto de archivos desde que fueron creados. Y les estoy hablando de un solo archivo como el control de cambios de Microsoft Word, sino llevar el registro de cambios en conjuntos de miles y miles de archivos a la vez. ¿No se convencen todavía? Les dejo unos cuantos hipotéticos casos de uso:

  • El contador que lleva sus registros en hojas de Excel podría permitirse crear una fotografía mes a mes de sus archivos en Excel sin necesidad de guardar 40,000 carpetas diferentes, así no solo tendría sus registros actuales sino un registro en el tiempo de como estaban las cosas antes.
  • Un abogado en un departamento legal donde almacenan versiones digitales de contratos o documentos legales de sus clientes, pueden ir observando como estos van cambiando durante el tiempo y si quieren revisar la versión original de un contrato podrían hacerlo rápidamente sin ningún problema.
  • Un diseñador gráfico que trabaja para su cliente y presenta un boceto inicial, luego este le dice que quiere una modificación, imaginen que guardan cada modificación del boceto y luego de un mes de trabajo y 15 versiones después el cliente les dice que quiere regresar al original. Con un sistema de versionado es tan fácil como decirle que uno quiere regresar a la versión original del archivo y listo, todo sin necesidad de tener 20,000 archivos dando vueltas por ahí.

Por último: si trabajan en desarrollo de software, donde los sistemas de versionado se han venido utilizando desde hace años, les permite llevar un control detallado de todos los cambios que se hacen al código fuente de su aplicación.

¿Que es git?


Resumiendo de manera breve: git es un software para versionado y manejo de código fuente totalmente distribuido, es decir, se encarga de llevar un registro de las modificaciones o "versiones" (de ahí el nombre) de un conjunto de archivos al que comúnmente se le llama repositorio. La parte de "distribuido" se refiere a que no depende de un servidor central como en otros sistemas como Subversion. Los cambios a las fuentes se pueden trabajar de manera local ya que cada usuario tiene una copia completa del repositorio en su computadora, si así se requiere se pueden enviar los cambios a servidores remotos.

A diferencia de otros sistemas de versionado, git no lleva registro de cambios individuales a los archivos sino que ve todos los archivos como un solo conjunto grande de datos y cada vez que guardamos una nueva versión git "toma una fotografía instantánea" (conocido como snapshot) del conjunto de archivos, busca los cambios y los almacena en una base de datos interna. Ok realmente es más complejo que esto pero solo es para que se hagan una idea.

¿Por qué git?


Si bien existen muchísimos sistemas de versionado, Git es un sistema creado por el mismo Linus Torvalds para llevar el control de versiones del código fuente del Kernel de Linux.

Para que se hagan una idea de que tan "mounstroso" es el proyecto del kernel de Linux, este cuenta con más de 25,000 archivos y cuenta con contribuciones de miles de personas diariamente alrededor del mundo. Todos esos registros de cambios al código fuente se realizan por medio de Git.

¿Cómo lo hace? Si bien no es el tema de esta entrada, se los resumo rápido: "Utilizando redes de confianza". Cada componente del kernel de Linux tiene comunidades de colaboradores quienes conforman redes de confianza, los cambios se van distribuyendo entre los colaboradores hasta que escalan hasta el propio Linus Torvalds, obviamente Linus no revisa todos y cada uno de estos cambios ya que colaboradores de confianza cercanos a él, se han encargado de revisar los de sus propias redes de confianza. El Kernel "oficial" no es más que la versión que mantiene Linus Torvalds, literalmente no existe un nodo o repositorio central en las fuentes del Kernel. Tal vez otro día, con un poco más de tiempo les explico en detalle como un proyecto tan grande funciona si la necesidad de centralizar nada.

Regresando nuevamente al tema, existe otra razón por la cual recomiendo git y lo explico en la siguiente sección:

Git está diseñado para ser distribuido


Una de las características más importantes en git es que se maneja como un repositorio "local", todos los archivos y sus versiones se guardan en la computadora en que se estén trabajando. Git también cuenta con comandos que nos permiten "empujar" nuestra versión a un servidor remoto o "clonar" repositorios desde Internet a nuestra computadora.

Sin embargo con git no es necesario estar conectado a Internet o tener acceso al servidor donde están las fuentes para poder utilizar toda la funcionalidad de un sistema de control de versiones.

Ustedes pueden irse de vacaciones a una isla paradisíaca desconectada del mundo y como buenos geeks pueden agregar una nueva característica a su programa a la orilla de la playa y no tendrán ningún problema.

La otra razón de peso para usar git es la que explico a continuación:

Está diseñado para trabajar con múltiples "ramas de desarollo" (branches)


El manejo de "ramas", en español sería como algo versiones de la aplicación, pero vamos a usar su nombre en ingles "branch" para no crear confusiones.

Un branch no es nada más que una forma fácil de referirse a una versión del código. Por ejemplo: podrían tener en su código tres ramas:

  • "estable" y almacenar ahí únicamente código que esta probado y listo para producción.
  • "desarollo" donde se encuentren las versiones de prueba o que no están listas para publicarse porque no han sido probadas. 
  • "experimental" donde coloquen el código con funcionalidad nueva que no haya sido probada y que no saben ni siquiera si va a ser incluida en el software.

Git es tan poderoso en el manejo de ramas, que si ustedes quisieran crear una rama para cada cambio que realicen al código, podrían hacerlo.... Pero no se los recomiendo.

Lo más importante y es su punto fuerte es que permite "unir" las ramas de manera muy sencilla.

Tomando instantáneas del código


La otra razón por la que git es muy de mi agrado personal, es que te "motiva" a guardar constantemente tu trabajo, el mismo Linus recomienda hacer los "commit" (comando utilizado para guardar una instantánea en el repositorio), tan seguido como puedas.

Uno de los mayores problemas en los sistemas de versionado tradicionales es que al ser centralizados tienes que tener mucho cuidado al momento de realizar un "commit". La razón es que ya que todos están trabajando en el mismo código es posible que tus cambios afecten los de alguien mas, en el mejor de los casos el programador es quien resuelve las inconsistencias, en el peor un tercero debe de resolver las diferencias lo que te obliga a esperar que revisen tu código.

Esto provoca que los desarrolladores se vuelvan muy "temerosos" de hacer commits hasta que están seguros de que sus cambios no van a afectar los de los demas.

Git en cambio crea un repositorio local, lo que te permite hacer instantáneas cuantas veces quieras teniendo la seguridad de que no molestarás a nadie.

Luego, incorporar cambios desde otros o hacia otros repositorios es sumamente sencillo ya que git es muy "inteligente" y en la mayoría de casos resuelve automáticamente los problemas de inconsistencias.

Obviamente hay casos en que se requiere la intervención humana por ejemplo cuando se ha trabajado bajo un mismo "trozo" de código, pero en la mayoría de las ocasiones git incorpora los cambios de manera completamente automatizada.

Tal vez me he extendido demasiado, pero antes de picar código quería que conocieran algunas de las bondades de "git". Ahora espero que estén convencidos y podamos comenzar a trabajar en un ejemplo sencillo:

A ensuciarse las manos con las "romances y las asiaticas"


(Diablillo interno: Eres un picarón Mario)

Ahora vamos a tocar esto de las romances y las asiaticas. Y con "esto" me refiero a que vamos a imaginar que somos los administradores de un proyecto sumamente importante en el mundo de la informática: Traducir ¡Hola Mundo! a lenguas romance (lenguas derivadas del latin) y a lenguas asiaticas.

De aquí en adelante voy invitarte a que vayas ejecutando los comandos y observes el resultado. Al final de esta entrada puedes descargar una versión del repositorio que he usado de ejemplo por si quieres curiosear.

Inicializando nuestro repositorio "Hola Mundo"


Antes de comenzar a usar GIT necesitamos crear una carpeta para nuestro proyecto, en este caso se llamara "holamundo":
~$ mkdir holamundo
~$ cd holamundo

Inicializar el repositorio se realiza con el comando "git init":
$ git init

El siguiente mensaje nos indicará que el repositorio ha sido inicializado:
Initialized empty Git repository in /home/usuario/holamundo/.git/

Una vez inicalizado el repositorio crea un archivo llamado "holamundo.txt" con el siguiente contenido:
¡Hola Mundo!

Antes de hacer nuestra primera "instantánea" con el comando commit, vamos a configurar git con nuestro nombre y correo electrónico, esto sirve para registrar nuestros cambios en el código.

Primero establecemos nuestro nombre real:
~/holamundo$ git config --global user.name "Mario Gomez"

Y luego nuestro email:
~/holamundo$ git config --global user.email mario.gomez@teubi.co

Agregando archivos a nuestro repositorio:


Git solo realiza el seguimiento de los archivos agregados al repositorio, para agregar archivos podemos usar el comando "git add":
~/holamundo$ git add holamundo.txt

Revisando los cambios a realizar


Si queremos revisar cuales archivos se han modificado antes de tomar la instantánea podemos hacerlo con el comando "git status":
~/holamundo$ git status

La salida deberá ser similar a la siguiente: 
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   holamundo.txt
#

Noten como al inicio aparece el texto "On branch master".

Cuando creamos un repositorio automáticamente se crea una rama principal, esta es la rama denominada "master". Mientras no creemos nuevas ramas nuestros cambios se guardarán por defecto en la rama principal.

Pueden notar como aparece holamundo.txt entre los "cambios" a ser guardados.

Tomando nuestra instantánea


Para guardar la instantanea en el repositorio utilizamos el comando "commit":
~/holamundo$ git commit

Se abrirá un editor de texto con la información que se mostraba en "git status", debemos de escribir un mensaje. Se recomienda que coloquemos una breve explicación de los cambios que se han hecho. Para que sigamos en línea con el ejemplo escribamos lo siguiente:
Instantanea inicial de HolaMundo

Un mensaje de confirmación nos indicará que los cambios se han guardado en el repositorio:
[master (root-commit) 9236a0c] Instantanea inicial de HolaMundo
 1 file changed, 1 insertion(+)
 create mode 100644 holamundo.txt

Luego de hacer "commit" podemos estar seguros que nuestros cambios se  han guardado dentro del repositorio.

Modificando y agregando más archivos


Abramos nuevamente nuestro archivo holamundo.txt y modifiquemolo de manera que quede como se muestra a continuación:
¡Hola Mundo!
En lenguas romance:
En lenguas asiáticas:

Creamos ahora un archivo llamado README.txt en el directorio holamundo y coloquemos adentro el siguiente texto:
Este es el proyecto HolaMundo.
Este proyecto tiene por objetivo guardar distintas versiones de "Hola Mundo" en lenguas romances y asiáticas.

Intentamos ahora hacer otro "commit"
~/holamundo$ git commit

Ups.. Parece que algo no funcionó ¿no?. Si han segido las instrucciones git les ha mostrado el siguiente mensaje:
# 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:   holamundo.txt
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    README.txt
no changes added to commit (use "git add" and/or "git commit -a")

El mensaje "no changes added to commit" dice que no hemos agregado cambios para almacenar. Ahora es el momento en que seguramente te estás haciendo la pregunta: ¿Pero acaso no hemos modificado holamundo.txt y creado un nuevo README.txt?.

Sí, lo hemos hecho, pero git es muy respetuoso y no agregará un archivo a la instantánea a menos que nosotros se lo indiquemos de manera explicita.

Para agregar individualmente los archivos al repositorio podemos utilizar nuevamente el comando "add" como se muestra en el siguiente ejemplo:
~/holamundo$  git add holamundo.txt
~/holamundo$ git add README.txt

Al ejecutar nuevamente status podremos observar como ahora si hay cambios que se guardarán en la próxima instantánea y el archivo README.txt está marcado como nuevo.
~/holamundo$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    new file:   README.txt
#    modified:   holamundo.txt
#

Realicemos ahora un nuevo "git commit" para guardar los cambios y coloquemos el siguiente texto en el mensaje para el registro de cambios:

Agregado README.txt y agregado idioma dentro de holamundo.txt

Si todo funciona bien, se mostrará el siguiente mensaje:

[master bbda490] Agregado README.txt y agregado idioma dentro de holamundo.txt

 2 files changed, 4 insertions(+)
 create mode 100644 README.txt

Revisando el historial de cambios


Hasta ahora todo muy bonito. ¿Pero como sabemos que cambios se han realizado? El comando "git log" nos presenta una lista de los cambios realizados al repositorio, si han seguiro correctamente las instrucciones se mostrará algo como siguiente:

~/holamundo$ git log

commit bbda490ea5a6ad12386b5d72aeeec63a666bed9a
Author: Mario Gomez <mario.gomez@teubi.co>
Date:   Tue Jan 22 13:52:34 2013 -0600

    Agregado README.txt y agregado idioma dentro de holamundo.txt


commit 9236a0c556f4eb00e2ceb7fbd69caa196a6eb8a3
Author: Mario Gomez <mario.gomez@teubi.co>
Date:   Tue Jan 22 13:47:20 2013 -0600

    Instantanea inicial de HolaMundo
Podemos revisar todos los commit hechos a nuestro repositorio llamando al comando "log".

Regresando a una versión anterior


Pueden notar como cada "commit" tiene un código asociado. para regresar a una versión anterior utilizaremos ese código. En su computadora deberán usar el código que les aparezca. Por ejemplo si escribimos

~/holamundo$ git checkout 9236a0c556f4eb00e2ceb7fbd69caa196a6eb8a3

La salida nos mostrará lo siguiente:
Note: checking out '9236a0c556f4eb00e2ceb7fbd69caa196a6eb8a3'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 9236a0c... Instantanea inicial de HolaMundo

Si revisamos los archivos con un "ls" veran la magia del versionado de fuentes:
~/holamundo$ ls
holamundo.txt

¿Y nuestro README.txt? ¿Ha desaparecido? No, sigue en el repositorio, pero al ejecutar el comando "checkout" con un commit específico le estamos diciendo a git que nos muestre el repositorio completo al tomar esa instantanea.

Si utilizamos el código del ultimo "commit" que realizamos podemos regresar a la ultima versión guardada:
~/holamundo$ git checkout bbda490ea5a6ad12386b5d72aeeec63a666bed9a

la salida nos mostrará algo como lo siguiente:
Previous HEAD position was 9236a0c... Instantanea inicial de HolaMundo
HEAD is now at bbda490... Agregado README.txt y agregado idioma dentro de holamundo.txt

Si verificamos los archivos con "ls" podremos observar como nuestro README.txt ha regresado:
~/holamundo$ ls
README.txt  holamundo.txt

Utilizando TAGs


El identificador de la instantánea es un código hexadecimal difícil de memorizar. Podemos fácilmente agregar "etiquetas" a los commits para recuperarlos fácilmente luego.

Primero egresemos a nuestra versión inicial
~/holamundo$ git checkout 9236a0c556f4eb00e2ceb7fbd69caa196a6eb8a3

Previous HEAD position was bbda490... Agregado README.txt y agregado idioma dentro de holamundo.txt
HEAD is now at 9236a0c... Instantanea inicial de HolaMundo

Ahora agregemos un tag anotado para identificarlo
~/holamundo$ git tag -a v0.1 -m "Version inicial"

Vamos a la última versión:
~/holamundo$ git checkout bbda490ea5a6ad12386b5d72aeeec63a666bed9a

Y agregamos el tag correspondiente:
~/holamundo$ git tag -a v0.2 -m "Version 0.2"<

Si utilizamos el comando "git tag" podemos ver todas las versiones disponibles:
~/holamundo$ git tag
v0.1
v0.2

Ahora hacer un checkout es muchísimo más sencillo. Por ejemplo:
~/holamundo$ git checkout v0.1
Previous HEAD position was bbda490... Agregado README.txt y agregado idioma dentro de holamundo.txt
HEAD is now at 9236a0c... Instantanea inicial de HolaMundo
~/holamundo$ git checkout v0.2
Previous HEAD position was 9236a0c... Instantanea inicial de HolaMundo
HEAD is now at bbda490... Agregado README.txt y agregado idioma dentro de holamundo.txt

Les recomiendo que vayan agregando etiquetas a sus commit cuando sientan que han agregado una funcionalidad que piensen que van a necesitar revisar luego. Utilizar los tags facilita enormemente el trabajo.

Solo tengan en consideración que las etiquetas se almacenan de manera local, al enviar nuestras modificaciones a un repositorio remoto este no almacenará los tags

Creando "ramas"


Recuerdan lo que mencione al principio de los "branch" o ramas de desarrollo. Les voy a mostrar ahora las capacidades de git para incorporar cambios de ramas de desarrollo de maera automática

Asumamos ahora que somos los creadores del proyecto HolaMundo y le pedimos a dos amigos que son muy versados uno en lenguas romance y otro en lenguas asiaticas que nos ayuden a traducir nuestro "Hola Mundo" a las lenguas correspondientes.

Nuestra rama para las romances


Para simplificar las cosas vamos a asumir que estamos trabajando en la misma computadora.

Primero creamos un "branch" para nuestro amigo experto en lenguas romances llamado "romances".

Crear ramas es sumamente sencillo en git, simplemente ejecutamos el comando "git branch", siguiendo el ejemplo:
~/holamundo$ git branch romances

Nuestro amigo llega mas tarde ese día y se pone  a trabajar en el proyecto, luego de investigar un poco decide incorporar su cambios. y hace "checkout" a la rama de romances.
~/holamundo$ git checkout romances

Un mensaje nos confirmará que estamos en la rama "romances":
Switched to branch 'romances'

Desde este momento todos los cambios que realicen se aplicaran únicamente a la rama "romances".

Si ejecutamos "git branch" nos mostrará la lista de las ramas existentes y nos marcará con un * la rama en la que nos encontramos actualmente:
~/holamundo$ git branch
  master
* romances

Hagamos las veces de nuestro amigo y abramos el archivo holamundo.txt y agreguemos algunos HolaMundo en lenguas romance:
¡Hola Mundo!
En lenguas romance:
Español: ¡Hola Mundo!
Italiano: Ciao a tutti!
Português: Olá mundo!
Français: Bonjour tout le monde!
Català: Hola Món!
En lenguas asiaticas:


Noten que solo hemos llenado el espacio de las "lenguas romance" y hemos dejado lo demás igual. Es una buena práctica solo modificar lo que nos interesa y lo demás dejarlo tal y como lo encontramos. Si bien no estamos usando la línea "En lenguas asiaticas" no nos hace estorbo y por tanto la dejamos ahí. Es la regla y no la excepción asumir que las cosas están dentro del código por algun motivo.

Hacemos un commit, pero esta vez utiliza el parámetro "-a" para que agregue los cambios de manera automática.
~/holamundo$ git commit -a

Podemos utilizar este mensaje:
Agregados Hola Mundo en lenguas romance.

Un mensaje nos confirmará que los archivos han sido modificados.
[romances da95ef0] Agregados Hola Mundo en lenguas romance 
 1 file changed, 5 insertions(+)

Luego, ese día viene nuestro otro amigo experto en lenguas asiaticas, como no queremos que sobreescriba el trabajo realizado de nuestro amigo experto en lenguas romance, antes de regresar hacemos un checkout al archivo original.
~/holamundo$ git checkout master

Nuestra rama para las asiáticas


Luego repetimos el procedimiento para que nuestro amigo escriba los Hola Mundo en lenguas asiaticas.
~/holamundo$ git branch asiaticas
~/holamundo$ git checkout asiaticas 

Dentro de esta rama abre el "HolaMundo.txt" y agrega los "hola mundo" para japonés y chino.
¡Hola Mundo!
En lenguas romance:
En lenguas asiaticas:
中国語 ハローワールド
漢語 你好世界
汉语 你好世界

Como derivamos de la rama principal y no de la rama "romance" nuestro holamundo.txt aparecía inicialmente vacío. Hacemos para este ejemplo  checkout de la rama "master" porque no estamos interesados en lo que este sucediendo en la rama "romances". Esto es parte de la magia de mantener el código en distintas ramas.

Hacemos el commit:
~/holamundo$ git commit -a

agregando el siguiente mensaje:
Agregado Hola Mundo, en japones, chino simplificado y tradicional.

Nos mostrará un mensaje confirmando las modificaciones:
[asiaticas a3c863e] Agregado Hola Mundo, en japones, chino simplificado y tradicional
 1 file changed, 3 insertions(+)

Uniendo ramas


Ahora nuestro repositorio tiene tres ramas. Podemos verificar esto fácilmente haciendo checkout a cada una hacemosde las ramas y revisando el contenido del archivo HolaMundo.txt luego de cada checkout.
~/holamundo$ git checkout master

holamundo.txt:
¡Hola Mundo!
En lenguas romance:
En lenguas asiáticas:

Rama "romances"
~/holamundo$ git checkout romances

holamundo.txt:
¡Hola Mundo!
En lenguas romance:
Español: ¡Hola Mundo!
Italiano: Ciao a tutti!
Português: Olá mundo!
Français: Bonjour tout le monde!
Català: Hola Món!
En lenguas asiáticas:

Rama "asiáticas"
~/holamundo$ git checkout asiaticas

holamundo.txt:
¡Hola Mundo!
En lenguas romance:
En lenguas asiáticas:
中国語 ハローワールド
漢語 你好世界
汉语 你好世界

Y aquí es donde viene la "magia de git", vamos a unir las dos nuevas ramas a la principal con el comando "merge". Imaginen que este es un proyecto grande de traducción de documentos, nuestra versión "principal" está en español, pero tenemos a dos personas trabajando una en la rama "romances" y la otra en la rama "asiaticas".

Primero nos vamos a la rama "master" que queremos incluya los cambios en estas nuevas ramas:

~/holamundo$ checkout master

Luego comenzamos a incorporar los cambios, intentemos primero con las lenguas romance.

~/holamundo$ git merge romances

Nos mostrará el mensaje siguiente:
Updating bbda490..da95ef0
Fast-forward
 holamundo.txt | 5 +++++
 1 file changed, 5 insertions(+)

El mensaje "fast-forward" aparece cuando hacemos "merge" de una rama que se deriva directamente de la que estamos trabajando.

Si revisamos ahora nuestro "HolaMundo.txt" contendrá lo siguiente:
¡Hola Mundo!
En lenguas romance:
Español: ¡Hola Mundo!
Italiano: Ciao a tutti!
Português: Olá mundo!
Français: Bonjour tout le monde!
Català: Hola Món!
En lenguas asiáticas:

Como pueden notar git realizo en este caso la incorporación del contenido de manera automática.

Ahora incorporemos los cambios de la rama "asiaticas". En este caso nos pregunta porque deseamos unir la rama.
~/holamundo$ git merge asiaticas

Lo que ha sucedido es que estamos intentamos unir una rama derivada de una versión "master" que ya no existe. En este caso solo debemos explicar la razón de la unión o usar el mensaje por defecto.

Una vez guardamos el archivo se mostrará el mensaje:
Auto-merging holamundo.txt
Merge made by the 'recursive' strategy.
 holamundo.txt | 3 +++
 1 file changed, 3 insertions(+)

Revisemos el contenido actual de holamundo.txt:
¡Hola Mundo!
En lenguas romance:
Español: ¡Hola Mundo!
Italiano: Ciao a tutti!
Português: Olá mundo!
Français: Bonjour tout le monde!
Català: Hola Món!
En lenguas asiáticas:
中国語 ハローワールド
漢語 你好世界
汉语 你好世界

¿Recuerdan que les mencioné que Git era "inteligente"? ¿Han notado como en ningún momento le hemos tenido que indicar a donde "unir" los cambios y aún así los ha incorporado correctamente?

Según explica el propio Linus Torvalds, esta facilidad de unir ramas es algo que hace "único" a Git. Y que lo hace ideal para trabajar con proyectos tan distribuidos como el Kernel de Linux.

Un ejemplo de la vida real de este tipo de "merge": Cuando se incorporaron los cambios del kernel de linux usado por Android a la rama oficial del kernel Linux mantenida por Linus Torvalds.

Actualizando los cambios en las ramas.


Un último ejemplo es el de incorporar los cambios de la rama principal a las sub ramas. Imaginemos que ahora queremos continuar trabajando pero el jefe de proyecto nos ha dicho que se ha actualizado la rama principal.

Si soy un buen muchacho intentaré obtener la última versión para realizar cambios antes de continuar trabajando. Puede que haya algo de lo que me deba enterar.

Esta parte es sumamente sencilla. Solo hacemos los merge correspondientes desde cada una de las ramas:

Para romances:

Cambiamos a la rama "romances":
~/holamundo$ git checkout romances

Incluimos los cambios de la rama principal:
~/holamundo$ git merge master 
Updating da95ef0..e7e7107
Fast-forward
 holamundo.txt | 3 +++
 1 file changed, 3 insertions(+)

Para asiaticas:

Cambiamos a la rama "asiatiacas":
~/holamundo$ git checkout asiaticas

Incluimos los cambios de la rama principal:
~/holamundo$ git merge master
Updating a3c863e..e7e7107
Fast-forward
 holamundo.txt | 5 +++++
 1 file changed, 5 insertions(+)

En este caso ambas operaciones aparecen como "Fast-forward" ya que los cambios pueden aplicarse directamente desde la rama principal hacia las sub ramas.

¿Que más puede hacer Git?


En esta entrada hemos revisado la funcionalidad local de git. Sin embargo git posee poderosas herramientas para trabajar con repositorios externos.

Un proveedor de hospedaje de repositorios sumamente popular es GitHub, este servicio nos permite hospedar nuestro código versionado por git. Si bien git es un sistema distribuido la ventaja de usar GitHub es que podemos colaborar o podemos encontrar colaboradores que nos ayuden a trabajar en nuestro código.

Si queremos mantener nuestro código privado github también nos da la posibilidad de contratar "hospedaje" privado al que solo usuarios autorizados tengan acceso.

Usar github y trabajar repositorios remotos es un tema que da para otra entrada completa en el blog.

Solo para dejarlos con la curiosidad pueden "clonar" el ejemplo que hemos utilizado en esta entrada ejecutando el siguiente comando:
~/holamundo$ git clone https://github.com/mxgxw/holamundo

Si todo sale bien les mostrará un mensaje como el siguiente:
Cloning into 'holamundo'...
remote: Counting objects: 21, done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 21 (delta 3), reused 18 (delta 3)
Unpacking objects: 100% (21/21), done.

Con ese simple comando ahora tienen una copia del repositorio.

Esta entrada es bastante larga, pero realmente git da para libros (y los hay). Recuerden todo desarrollador que se sienta orgulloso de serlo debe saber utilizar algún sistema de control de fuente.

No habiendo nada mas que decir por ahora... ¡Hasta pronto!


1 comentario:

Nicolás dijo...

muy expeditivo gracias