(Sé que no soy el único que entendió el chiste del título, asi que a hacerse cargo).
Ahora a lo que nos compete: Acá en OnRails no queríamos ser menos :P, y viendo la gran cantidad de blogs que hablan de GIT, no nos queríamos quedar sin nombrarlo.
There’s a new SCM in town.
Los últimos dos años he usado SVN, con algun que otro problema, pero sin realmente tener algo concreto para quejarme. Antes de SVN trabajé como administrador de ClearCase, que es la herramienta de SCM de Rational, que luego fue comprada por IBM. ClearCase (CC) se caracteriza por muchas cosas (muchas negativas), siendo la burocracia una de ellas. Como admin pude experimentar el sufrimiento de laburar con un esquema complejo, y que no facilitaba el trabajo de los desarrolladores. CC permite un montón de operaciones que en SVN son muy difíciles o muy propensas a generar conflictos. En CC se podían crear muy facilmente los “streams”, que no eran otra cosas que branches, justamente uno de los temas que GIT resuelve por sobre SVN.
Hace un mes comencé a meterme con este “nuevo” SCM, me empapé bastante del tema y puedo decirle las caracteristicas que para mi son más relevantes:
Aclaración al margen: Esto no es una guía sino que simplemente intenta transmitir algunas de las sensaciones generadas en las primeras semanas de uso. Recursos sobran a mi entender.
La creación de branches es trivial.
En SVN era necesario hacer “svn copy ../trunk ../branches/mi_branch”, y luego hacer checkout en otro directorio apuntando a la ruta recién creada, terminando así con varios directorios del mismo repo, cada uno apuntando a un branch diferente.
Con GIT es solo cuestión de ejecutar: git branch mi_branch, y luego hacer checkout mi_branch. Si, sin cambiar de directorio. GIT cambia los archivos automáticamente según el branch seleccionado. Quizás con un ejemplo se vea mejor.
(Mi prompt indica el branch actual, si lo quieren usar copien este link en $HOME/.profile)
driven:~/programming/test_app $ git init
driven:~/programming/test_app $ git add . # Agregando archivos, sino git no se hace cargo
driven:~/programming/test_app $ git commit -a -m "Initial Import"
driven:~/programming/test_app (master)$ git branch
* master
driven:~/programming/test_app (master)$ git branch req_23568
driven:~/programming/test_app (master)$ git branch
* master
req_23568
driven:~/programming/test_app (master)$ git checkout req_23568
Switched to branch "req_23568"
driven:~/programming/test_app (req_23568)$
A partir de aquí solo me restaría trabajar en el req_23568, hacer commit lo que sea necesario (los commits son por branch) y luego hacer un rebase del master (nuestro omni presente branch) apuntándolo a req_23568. Cómo sería eso?
driven:~/programming/test_app $ mate . # trabajo, mucho, cambio, pongo, saco
..
driven:~/programming/test_app (req_23568) $ git commit -a -m "Algo 1"
...
driven:~/programming/test_app (req_23568) $ git commit -a -m "Algo 2"
....
driven:~/programming/test_app (req_23568) $ git commit -a -m "Algo 3"
# laburo con repo remoto? Antes deberia hacer un pull.
driven:~/programming/test_app (req_23568)$ git checkout master
driven:~/programming/test_app (master)$ git pull # por default es el origin
driven:~/programming/test_app (master)$ git checkout req_23568 # y vuelvo
driven:~/programming/test_app (req_23568)$ git rebase master # por si alguien estuvo laburando en master
driven:~/programming/test_app (req_23568)$ git checkout master # si todo funciono OK me paso a master
Switched to branch "master"
driven:~/programming/test_app (master)$ git rebase req_23568 # y realizo el rebase
... mucho ruido ... (ojo, muy útil)
driven:~/programming/test_app (master)$
Nota: Se actualizó acorde a lo sugerido por el estimadísimo Luis Lavena.
Lo que hace rebase es interesante. Rebobina el branch MASTER al momento en que se creo el branch REQ_23568, aplica lo cambios del mismo, y luego aplica todos los commits que se hayan aplicado posteriormente en el branch MASTER.
No hay un servidor centralizado.
Cada uno tiene una copia, y es autónoma de la de los demás. Todas las operaciones se realizan localmente y luego se envían los cambios a los repositorios remotos que uno tenga configurado localmente. Obvio, siempre hay que tener permiso, sino no pasa un byte.
Ignorar archivos es una huevada.
Sólo hace falta crear el archivo .gitignore en el root del repo y cargarlo con entradas que pueden incluir el nombre relativo del elemento a excluir, o wildcards más abarcativos.
driven:~/programming/backoffice (tab_container)$ cat .gitignore
.DS_Store
*.log
tmp/**/*
config/database.yml
db/*.sqlite3
db/schema.rb
db/schema.sql
Incluye una herramienta excelente para visualizar los branches y cambios aplicados o no.
Se llama gitk. Incluir el parámetro—all para que muestre información sobre todos los branches, y no solo el actual/current.
Muchas cosas más.
Dejo para cada uno que tenga ganas la tarea de investigar el stash, que a mi entender es una idea excelente. Este Linus la tiene clara.
Ah, además se integra con SVN muy facilmente. Podésusarlo localmente y hacer commit contra un repo SVN cuando termines. Para los demás que usen SVN es transparente.
Conclusión preliminar.
GIT es la evolución obligada luego de SVN. En mi caso me facilitó mucho poder trabajar con ciertos temas que requerían atención inmediata y otros que llevaban un poco más de tiempo de desarrollo.
Un branch para cada cosa. A guardar, a guardar, cada cosa en su branch! (bueh, suficiente, no?)




