Bienvenidos a Git desde cero, esta serie de tutoriales tratar explicar y alejar el miedo que algunos de nosotros sentimos cuando comenzamos a utilizar un controlador de versiones por primera vez.
Qu es Git? Git en pocas palabras es un controlador de versiones distribuido. Para ampliar este significado debemos responder primero la siguiente pregunta. Qu es un controlador de versiones? Un controlador de versiones es un sistema que registra los cambios en un archivo o conjunto de archivos a travs del tiempo para que se puedan recuperar versiones especficas de los mismos ms adelante. Ahora, Por qu es distribuido? Cuando los usuarios descargan la ltima versin de los archivos no solo estn descargando los archivos; sino tambin realizando una copia fiel y exacta (copia de seguridad) del repositorio (carpeta donde se alojan estos archivos) de esta manera si dicho repositorio muere, cualquiera de los usuarios que descargaron estos archivos pueden restaurar el estado de ese del mismo haciendo uso de su copia de seguridad. Por otra parte esto permite que se puedan tener varios repositorios remotos para poder trabajar y colaborar con diferentes grupos de personas al mismo tiempo en un mismo proyecto, cosa que no es posible con los sistemas centralizados. Caractersticas que destacan de Git como control de versiones: Fotografas rpidas, NO diferencias A la hora de guardar la informacin de varios archivos, Git toma una fotografa rpida del estado de los mismos y guarda las referencias de esta fotografa. Luego para ser eficiente revisa los archivos que no fueron modificados y cambia las referencias de los mismos a su versin anterior. Casi todas las operaciones son locales S ya descargaste un repositorio no es necesario estar conectado a una red o conexin a internet para trabajar sobre archivos, todo lo necesario se encuentra en tu computadora. Integridad de la data Git antes de guardar la fotografa del estado de un archivo realiza un checksum de la data. De esta manera es imposible cambiar el contenido de cualquier archivo sin que Git lo note. Git generalmente solo aade data Al trabajar en cualquier archivo y almacenar los cambios se est agregando data a la base de datos de Git. Esto nos da la seguridad de que si estos cambios fueron persistidos es muy difcil que se pierdan. Trabaja con tres estados Lo ms importante para recordar de Git son los tres(3) estados en que los archivos residen: consolidada (committed), modificados y en escenario (stage). Modificado, se han detectado cambios en el archivo pero no se han consolidado. Consolidado, el archivo y su data han sido guardados satisfactoriamente en la base de datos de Git. En escenario se han marcado las modificaciones de un archivo y su prximo paso ser consolidar la data.
Instalacin Ya que conocemos un poco sobre Git, es hora de instalarlo. Dependiendo del Sistema Operativo en que nos encontremos utilizaremos la instalacin apropiada. Mac OS Mtodo Recomendado: Para realizar la instalacin en este Sistema Operativo es recomendable tener instaladoHomebrew. Haciendo uso del Terminal.app y de hombrew, escribimos el siguiente comando: 1 $ brew install git Si el terminal no es de t preferencia puede hacer uso de un cliente de interfaz grfica para realizar la instalacin de Git. El cliente de Github nos facilita esta tarea. Linux Si nos encontramos en distribuciones como Fedora, podemos hacer uso del manejador de paquetes de dicha distribucin y mediante el siguiente comando instalaremos Git: 1 $ yuminstall git-core Si nos encontramos en distribuciones basadas en Debian, tal como Ubuntu, utilizamos el siguiente comando: 1 $ apt-get install git
Windows Si nos encontramos el Windows la manera ms sencilla de realizar la instalacin es descargar el Instalador y seguir los pasos.
Configuracin Ya que tenemos Git instalado, es tiempo de configurarlo. Para esto, tenemos que abrir el Terminal. Configuracin del nombre de usuario Lo primero que debe hacer es decirle a Git cual ser nombre de la persona que har uso de l: 1 $ git config --global user.name "Pedro Perez" Configuracin del email Git hace uso del email del usuario cuando consolida la data, por esta razn necesitamos configurarlo: 1 $ git config --global user.email "pedroperez@ejemplo.com" Podemos revisar que estn bien escritos haciendo uso del siguiente comando: 1 2 3 $ git config --list user.name=Pedro Perez user.email=pedroperez@ejemplo.com Tambin debemos conocer que Git guarda esta informacin dentro del archivo oculto .gitconfig en el Home del usuario. Utilizando el siguiente comando podemos observar la informacin suministramos durante la configuracin: 1 2 3 4 $ cat ~/.gitconfig [user] name =Pedro Perez email =pedroperez@ejemplo.com
Cuenta en Github.com Previamente explicamos que no es necesario estar conectado a una red o tener conexin a internet para poder hacer uso de Git. Con esto no queremos decir que nicamente haremos uso de esta herramienta manera local, sino ms bien queremos que nuestros archivos (cdigo, fotos, etc.) se encuentren tanto en nuestro computador como en un servidor remoto. Por esta razn se recomienda abrir una cuenta en Github.com de manera gratuita para el alojamiento remoto de nuestros archivos.
Comandos bsicos Tenemos Git instalado y listo para usar, ha llegado el momento de conocer los pasos necesarios para la inicializacin de un repositorio, agregar archivos al escenario y consolidarlos. Inicializacin de un repositorio Un repositorio no es ms que una carpeta o conjunto de carpetas que contienen archivos. Podemos crear una carpeta y luego iniciar el repositorio dentro, utilizando los siguientes comandos: 1 2 $ mkdir Ejemplo && cd Ejemplo $ git init . Con el comando git init se crea una carpeta oculta llamada .git (se encuentra dentro de la carpeta Ejemplo) y contiene toda la informacin necesaria para que podamos realizar las versiones (copias de seguridad) de nuestro proyecto. En este punto Git no est llevando el control de ningn archivo. Agregar archivos al escenario Con nuestro repositorio listo, queremos llevar el control de nuestro primer archivo. Para esto debemos crearlo dentro de nuestra carpeta Ejemplo y agregarlo al escenario: 1 2 3 $ touch Archivo1.txt #Creamos el archivo vaco $ echo 'Hola Mundo' >>Archivo1.txt #Le agregamos texto al archivo $ git add Archivo1.txt #colocamos el archivo en escenario Al ejecutar el comando git add Archivo1.txt estamos confirmando (agregando el archivo al escenario) que los cambios que realizamos sobre Archivo1.txt se quieren respaldar la prxima vez que consolidemos la data.
Consolidar la informacin. Para consolidar el archivo previamente creado y puesto en escenario debemos utilizar el siguiente comando: 1 $ git commit -m"Commit Inicial" nota: La bandera -m indica que se debe consolidar el archivo con un mensaje informativo.
Conclusin En este captulo aprendimos los conceptos bsicos de Git; tales como instalacin en mltiples Sistemas Operativos, configuracin desde cero y a persistir informacin en su base de datos. En los prximos captulos iremos conociendo ms comandos y trataremos de ensearle al usuario el flujo de trabajo que utilizamos en Codehero cuando hacemos uso de esta herramienta.
Git desde cero: Registrando cambios. Bienvenidos a un nuevo captulo de Git desde cero en este tutorial hablaremos sobre los siguientes comandos: git clone git status git diff git rm git mv nota: hemos creado un repositorio en Github con el tutorial para que te puedas descargar lo que realizamos y le eches un vistazo.
Clone El comando git clone lo utilizaremos para literalmente realizar una copia de seguridad de lo que se encuentra en el servidor remoto. Como se explic en el captulo pasado cualquiera puede copiar un repositorio completo y hospedarlo en su computador por si ocurre algn imprevisto con el servidor remoto, si se desea contribuir o distribuir un proyecto como es nuestro caso para esta serie de totorales. Cmo realizamos una clonacin de un repositorio? Pues es bastante sencillo. Primero nos dirigimos al directorio donde queremos que se descargue la copia de seguridad (Lo creamos sino existe) y luego utilizando el siguiente comando: 1 2 $ cd ~/CodeHero/tutorial-git $ git clone https://github.com/codeheroco/tutorial-git.git #Clonacin del repositorio. Posterior a la ejecucin del comando podemos observar que se nos descargaron los archivos en nuestro directorio utilizando el comando ls para listar directorios.
Status El comando git status nos identifica si existe un archivo modificado o no en nuestro repositorio. Esto es importante ya que si hacemos memoria del captulo anterior hay que ubicar los archivos en el escenario antes de consolidarlos en la base de datos. Cuando el repositorio no presenta modificaciones y corremos el comando, obtenemos la siguen salida: 1 2 3 $ git status On branch master nothing to commit, working directory clean Pero si ahora agregamos un nuevo archivo y le copiamos texto podemos ver que la salida es bastante diferente: 1 2 3 4 5 6 7 8 $ touch Archivo2.txt $ echo 'Texto para el segundo archivo' >>Archivo2.txt $ git status On branch master Untracked files: #<-- Nos est indicando que tenemos archivos nuevos. (use "git add <file>..." to include in what will be committed) Archivo2.txt #<-- El archivo nuevo del que git no conoce. nothing added to commit but untracked files present (use "git add" to track) Si observamos con detenimiento nos pide que utilicemos el mismo comando de git add que aprendimos en el primer captulo para comenzar a seguir los cambios de este archivo. Vamos a realizarlo! 1 2 3 4 $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) 5 new file: Archivo2.txt #<-- Archivo nuevo Ahora podemos apreciar que Git ha subido al escenario al Archivo2.txt y lo conoce como archivo nuevo. nota: Antes de consolidar los cambios en el Archivo2.txt vamos a comenzar a ver el siguiente comando.
Diff El comando git diff nos identifica todos los cambios de un archivo con respecto a su versin anterior, o mejor dicho nos identifica los cambios de un archivo entre diferentes versiones. Es aqu donde podemos apreciar los cambios realizados que vamos a consolidar en esta nueva versin. Ahora realizando la continuacin de lo que venimos realizando utilicemos el siguiente comando: 1 2 3 4 5 6 7 8 $ git diff --cached #comando utilizado para archivos en el escenario. diff --git a/Archivo2.txt b/Archivo2.txt new file mode 100644 index 0000000..aeaed15 --- /dev/null +++b/Archivo2.txt #Archivo con ms lneas. @@ -0,0 +1 @@ +Texto para el segundo archivo #lneas nuevas Al utilizar el comando observamos que una vez que tenemos el Archivo2.txt en escenario podemos revisar sus diferencias con respecto a una versin anterior (en este caso no existe) pero de igual manera nos indica que al archivo se le agregaron lneas nuevas y nos dice cuales fueron. Ahora si consolidamos el archivo y lo modificamos podemos apreciar como la salida es algo distinta: 1 2 3 4 $ git commit -m"Agregar Archivo2" [master 9322f84] Agregar Archivo2 1 file changed, 1 insertion(+) create mode 100644 Archivo2.txt Si ahora modificamos de nuevo el Archivo2.txt y utilizamos git diff nuevamente veamos lo que sucede: 1 2 3 4 5 6 7 8 9 10 $ echo 'Cambiando la primera linea' >Archivo2.txt $ echo 'Agregando una segunda linea' >>Archivo2.txt $ git diff diff --git a/Archivo2.txt b/Archivo2.txt #diferencia entre versiones index aeaed15..4564504 100644 --- a/Archivo2.txt #Versin anterior con menos lneas +++b/Archivo2.txt #Versin actual con ms lianas @@ -1 +1,2 @@ -Texto para el segundo archivo #Eliminamos sta lnea +Cambiando la primera linea #Agregamos estas dos 11 +Agregando una segunda linea Los signos +y nos indican los cambios realizados sobre el archivo y funciona nicamente como indicativos visuales. An as vemos lo til y fundamental que es ste comando para conocer los nuevos cambios realizados. Ahora vamos a subir estos nuevos cambios al escenario y posteriormente consolidarlos en la base de datos. 1 2 3 4 $ git add Archivo2.txt $ git commit -m"Modificaciones sobre el Archivo2" [master 2e37d7f] Modificaciones sobre el Archivo2 1 file changed, 2 insertions(+), 1 deletion(-) #resumen de cambios Aqu tambin apreciamos un pequeo resumen de los cambios ocurridos. Un archivo cambi, tuvo 2 lneas insertadas y una borrada.
Rm El comando git rm es un comando particular, a mi juicio poco utilizado pero importante conocer sobre l. Al igual que el comando Rm de Unix sirve para borrar un archivo pero en este caso sirve para agregar al escenario el archivo que vayamos a borrar. Veamos el siguiente ejemplo: 1 2 3 4 5 6 7 8 9 10 $ rmArchivo1.txt #borramos el archivo. $ git status #On branch master #Changes not staged for commit: #NO se encuentra en escenario # (use "git add/rm<file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # deleted: Archivo1.txt #Archivo eliminado pero no en escenario # no changes added to commit (use "git add" and/or "git commit -a") Podemos observar que al utilizar el comando rm de Unix (en mi caso) hemos borrado satisfactoriamente el Archivo1.txtpero esto an no se encuentra en escenario. 1 2 3 4 5 6 7 8 $ git rmArchivo1.txt $ git status #On branch master #Changes to be committed: #En escenario # (use "git reset HEAD <file>..." to unstage) # # deleted: Archivo1.txt # Ahora utilizamos el comando git rm automticamente confirmamos que realmente queremos eliminar dicho archivo. lo ltimo que nos resta es consolidar los cambios. 1 2 3 4 $ git commit -m"Eliminar el Archivo1" [master 0f8a083] Eliminar el Archivo1 1 file changed, 1 deletion(-) delete mode 100644 Archivo1.txt
Mv El comando git mv funciona de la misma manera que el comando git rm, confirma cualquier cambio de nombre o movimiento de un archivo. En esta oportunidad vamos a simplificar un paso no utilizando el comando mv del sistema operativo sino directamente iremos por el comando de Git. 1 2 3 4 5 6 7 8 9 10 11 12 $ git mv Archivo2.txt Archivo2_cambio_de_nombre.txt #Cambio de nombre $ git status #On branch master #Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # renamed: Archivo2.txt ->Archivo2_cambio_de_nombre.txt # $ git commit -m"Cambio de nombre del archivo 2" #Consolidar en BD [master 5a13514] Cambio de nombre del archivo 2 1 file changed, 0 insertions(+), 0 deletions(-) rename Archivo2.txt =>Archivo2_cambio_de_nombre.txt (100%) #resumen Este comando realiza el cambio de nombre a nivel de sistema operativo y a su vez confirma los cambios subiendo el archivo al escenario. Para consolidarlos posteriormente.
Git desde cero: Historial, enmendar y regresar cambios. Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre el historial de los cambios en git, como enmendarlos y como regresar una modificacin a su estado anterior utilizando estos comandos: git log (multiples vistas) git commit amend git reset git checkout nota: hemos creado un repositorio en Github con el tutorial para que te puedas descargar lo que realizamos en el curso y le eches un vistazo.
Log Una vez que hemos consolidado varios archivos, el comando git log es utilizado para ver el historial de cambios de nuestro repositorio. Esto incluye informacin sobre el autor de los cambios, el mensaje breve utilizado, la fecha en que se realiz y el nmero de serial (hash) de la informacin consolidada. En este caso utilizaremos los comandos ms utilizados en Codehero para observar los cambios en el historial dentro de nuestros proyectos. Basndonos en lo aprendido en el curso nmero 2 Git desde cero: Registrando Cambios vamos a realizar una clonacin de nuestro repositorio (si es que no lo hemos hecho antes). 1 2 $ cd ~/CodeHero/ #Creamos la carpeta sino existe (mkdir). $ git clone https://github.com/codeheroco/tutorial-git.git #Clonacin del repositorio. Una vez que nos haya concluido la clonacin del repositorio remoto procederemos a utilizar el comando git log para observar el historial de cambios. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 $ git log
Commit Inicial Si hacemos memoria o nos vamos a los dos (2) cursos anteriores podemos observar que sta fue la informacin consolidada en su desarrollo. Esta es una manera algo complicada de apreciar ciertos cambios y no nos ensea los cambios que realizamos sobre los archivos. De necesitar ver un nivel de detalle mayor se puede utilizar el siguiente comando, el cual es un resumn de lo ocurrido en ese cambio: 1 2 3 4 5 6 7 8 9 10 11 12 13 $ git log --stat
#observamos la salida (se encuentra reducida a lo ltimo que se consolido)
Archivo2.txt | 2 -- Archivo2_cambio_de_nombre.txt | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) De requerir ver un nivel de detalle todava mayor como por ejemplo: mostrar las lneas donde ocurrieron los cambios (diferencias) utilizamos el siguiente comando: nota: la bandera -1 se utiliza para observar nicamente lo ltimo que fue consolidado. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $ git log -p -1
diff --git a/Archivo2.txt b/Archivo2.txt deleted file mode 100644 index 4564504..0000000 --- a/Archivo2.txt +++/dev/null @@ -1,2 +0,0 @@ -Cambiando la primera lnea #Se eliminaron estas lneas. -Agregando una segunda lnea diff --git a/Archivo2_cambio_de_nombre.txt b/Archivo2_cambio_de_nombre.txt new file mode 100644 index 0000000..4564504 --- /dev/null +++b/Archivo2_cambio_de_nombre.txt @@ -0,0 +1,2 @@ +Cambiando la primera lnea #Se agregaron estas lneas. +Agregando una segunda lnea Podemos ver que al hacer cambio de nombre del archivo los cambios se marcan como si se hubiese eliminado el primer archivo y se cre otro, etiquetando la informacin sobre el Archivo2.txt como eliminada o borrada y la delArchivo2_cambio_de_nombre.txt como agregada, siendo esta la misma. Por ltimo si lo que queremos es visualizar en el historial de modificaciones en forma grfica para observar el orden en el que se han almacenado los cambios podemos utilizar un mtodo que abrevia de manera cuantiosa el historial. 1 2 3 4 5 6 7 $ git log --pretty=format:"%h - %an - %ar - %s" --graph
* 5a13514 - albertogg - 7 days ago - Cambio de nombre del archivo 2 * 0f8a083 - albertogg - 7 days ago - Eliminar el Archivo1 * 2e37d7f - albertogg - 7 days ago - Modificaciones sobre el Archivo2 * 9322f84 - albertogg - 7 days ago - Agregar Archivo2 * 1b80a91 - albertogg - 7 days ago - Commit Inicial Describiendo la siguiente salida apreciamos lo siguiente los * asteriscos son la representacin grfica de cada cambio almacenado (commit), luego tenemos el nmero de serial (hash) resumido, el autor, el tiempo cuando se realiz y el ttulo del mensaje breve. nota: se puede utilizar git log graph para observar mejor el grfico en este caso. Tambin se pueden mezclar las banderas que utilizamos, es decir podramos utilizar git log pretty=format: %h %an %ar %s graph -2 para ver nicamente los ltimos 2 del historial. Quedar departe del lector jugar y averiguar aun ms banderas o parmetros a utilizar.
Commit amend Frecuentemente cuando trabajamos y consolidamos los cambios olvidamos agregar al escenario algn archivo o simplemente lo modificamos tarde y lo queremos agregar a la informacin consolidada anteriormente. Es aqu cuando entra este comando en accin. Vamos a realizar una serie de cambios, los consolidaremos y agregaremos otro cambio posteriormente. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $ touch README.md $ echo '#Repositorio git para el curso Git desde cero' >>README.md $ git status #omitimos la salida $ git add README.md $ git commit -m"Agregar archivo README.md"
#Ahora modificaremos otro archivo y lo agregaremos.
#En este punto tenemos dos opciones 1) Dejar el mismo mensaje 2) Cambiarlo
$ git commit --amend --no-edit #Dejamos el mismo mensaje $ git commit --amend -m"Nuevo mensaje para el cambio" nota: Es sumamente importante que si los cambios fueron consolidados y enviados al servidor remoto NO se utilice este comando; ya que se modifica el nmero de serial nico de los cambios hechos y vamos a tener un conflicto difcil de resolver.
Reset Qu sucede si agregamos al escenario un archivo que ya no queremos consolidarlo en ese instante? La lgica induce a que lo bajemos del escenario y eso es precisamente lo que hace git reset. Si escribimos git status este comando nos recordar del comando reset en todo momento. Hagamos la prueba modifiquemos nuestro archivo README. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ echo 'Un curso exclusivo de codehero basado en el libro Pro Git' >>README.md $ git add README.md $ git status #On branch master #Your branch is ahead of 'origin/master' by 1 commit. # (use "git push" to publish your local commits) # #Changes to be committed: # (use "git reset HEAD <file>..." to unstage) #Para bajar del escenario # # modified: README.md #
#vamos a bajarlo del escenario, porque no queremos este cambio an.
$ git reset HEAD README.md Unstaged changes after reset: M README.md La salida del comando anterior nos indica lo siguiente: el archivo se encuentra fuera del escenario y presenta modificaciones.
Checkout Qu pasara si ahora nos arrepintiramos de esa ltima modificacin y la quisiramos eliminar? Pues es muy fcil utilizandogit checkout lo devolveremos a su ultimo estado solo basta con emplear el siguiente comando: 1 2 3 4 5 6 7 8 9 10 $ git checkout -- README.md
#si ahora revisamos el status veremos que no existe modificacin alguna.
$ git status #On branch master #Your branch is ahead of 'origin/master' by 1 commit. # (use "git push" to publish your local commits) # nothing to commit, working directory clean nota: el comando status tambin nos recuerda como descartar los cambios en todo momento. El comando checkout no es utilizado nicamente para esto.
Conclusin Durante este captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento bsico y fundamental para utilizar esta fabulosa herramienta. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la prxima semana!
Git desde Cero: Manejo remoto y etiquetas. Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre como manejar un repositorio remoto de git y como crear tags (etiquetas) para enumerar versiones finales tambin llamados lanzamientos. Los comandos de esta semana sern los siguientes: git remote git push git fetch git pull git tag (multiples formatos) nota: hemos creado un repositorio en Github con el curso para que te puedas descargar lo que realizamos en el curso y le eches un vistazo.
Remote (Remoto) Qu es un repositorio remoto? Un repositorio remoto no es ms que una copia de los archivos, carpetas, fotos, etc. qu se encuentran bajo la supervisin de git, y estn respaldados en un sitio externo a nuestro computador (Internet, o una red local domestica/oficina, etc.) Esto nos permite poder colaborar en un proyecto con otros usuarios de manera distribuida; cabe destacar que un repositorio remoto se pueden tener permisos de lectura y escritura o solo lectura. Para nuestro propsito vamos a utilizar el repositorio alojado en Github.com para cumplir nuestra tarea. nota: debemos tomar en cuenta que al realizar una clonacin se genera una carpeta con el nombre del proyecto y posiblemente unos archivos. Por lo que puede ser conveniente realizar un cambio de directorio a uno que se encuentre dentro del HOME del usuario para ahorrarnos inconvenientes. 1 2 3 4 5 6 7 8 9 10 11 12 $ git clone https://github.com/codeheroco/tutorial-git.git Cloning into 'tutorial-git'... remote: Counting objects: 17, done. remote: Compressing objects: 100% (12/12), done. remote: Total 17 (delta 1), reused 16 (delta 0) Unpacking objects: 100% (17/17), done. Checking connectivity... done
#Cambiamos de directorio, al directorio creado. $ cd tutorial-git $ git remote origin Cuando utilizamos el comando git remote podemos observar que nos retorn origin, y esto no es ms que un seudnimo para la direccin https://github.com/codeheroco/tutorial-git.git que viene siendo nuestra direccin remota de donde efectuamos la clonacin. Para observar si esto es cierto de manera detallada utilizamos el siguiente comando: 1 2 3 $ git remote -v origin https://github.com/codeheroco/tutorial-git.git (fetch) origin https://github.com/codeheroco/tutorial-git.git (push) Si tuvisemos otro repositorio del mismo proyecto pero en un servidor de pruebas donde alojamos cdigo que necesitamos ir probando, pudisemos agregar otra direccin remota y enviarle los cambios sin afectar a origin. 1 2 3 4 5 6 $ git remote add servidor-de-pruebas https://github.com/albertogg/tutorial-git.git $ git remote -v origin https://github.com/codeheroco/tutorial-git.git (fetch) origin https://github.com/codeheroco/tutorial-git.git (push) servidor-de-pruebas https://github.com/albertogg/tutorial-git.git (fetch) servidor-de-pruebas https://github.com/albertogg/tutorial-git.git (push) Podemos observar que tenemos ambas direcciones y seudnimos para poder ir a buscar (fetch) y enviar (push) cdigo.
Push Una vez que hemos conectado el repositorio remoto con el local y tenemos cambios consolidados en nuestro computador (local) que deseamos compartir, utilizamos el comando git push [seudnimo] [ramificacin] o en nuestro caso: 1 $ git push origin master
Fetch El comando git fetch es utilizado para ir a buscar los archivos al servidor. Es decir, si estamos trabajando con varias personas en un mismo proyecto es muy probable que cuando nosotros estemos introduciendo un cambio o una funcionalidad, nuestros compaeros tambin estn haciendo lo mismo y a su vez enviando estos cambios a un servidor remoto. Utilizando el comando fetch obtenemos los cambios consolidados que se encuentren en el servidor remoto que hayan sido realizados por nuestros compaeros y los copiamos a nuestro computador. por ejemplo: 1 2 3 4 5 6 7 8 9 $ git fetch origin
#Descargamos los cambios de origin remote: Counting objects: 4, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 3 (delta 0) Unpacking objects: 100% (3/3), done. Fromgithub.com:codeheroco/tutorial-git c250a0f..0022f43 master ->origin/master De esta manera actualizamos nuestra informacin local con la informacin que se encuentre remota. Pero no ser reflejada en el git log hasta que la unamos con nuestro rbol de trabajo (ramificacin). nota: si utilizamos el comando fetch y no se encuentran cambios en el servidor el comando no retorna nada. ste cambio fue introducido por nuestro amigo J onathan (autor de los how to de codehero) en el mismo fue agregado un archivo ms, nicamente para efectos de demostracin.
Pull ste comando es muy similar al anterior aunque realiza dos funciones simultneas. git pull realiza un fetch ms un merge. Del comando merge hablaremos ms adelante, de esta manera se descarga los cambios que se encuentren en el repositorio remoto y los unifica con los cambios que tengamos en nuestro equipo. nota: utilizando este comando puede que ocurran conflictos. Explicaremos como resolverlos ms adelante cuando hablemos del comando merge. Para tener una idea de lo que realiza este comando basta con emplearlo. 1 2 3 4 5 6 7 $ git pull
#Cmo previamente habamos descargado los cambios utilizando #fetch obtuvimos la siguiente salida.
First, rewinding head to replay your work on top of it... Fast-forwarded master to 0022f43897359daf973985a140a087c849b2bb0f. Posterior a la ejecucin hemos actualizado nuestro repositorio local haciendo una copia de los cambios en el repositorio remoto y los mismos se ven reflejados inmediatamente en el git log.
Tag El comando git tag es mayoritariamente utilizado para etiquetar versiones importantes dentro del desarrollo. En pocas palabras para marcar un hito/lanzamiento de un producto. En el repositorio remoto de Codehero venimos utilizando tags desde el inicio; esperando a este captulo para ensearos. su funcionalidad. 1 2 3 4 5 6 $ git tag
#mostramos los tags creados, slo si existen. Capitulo-1 Capitulo-2 Capitulo-3 Para crear un tag basta con utilizar el siguiente comando: 1 $ git tag "Capitulo-4" S queremos ver la informacin de este ltimo tag podramos emplear el siguiente comando: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ git show Capitulo-4
#obteniendo la siguen salida commit 0022f43897359daf973985a140a087c849b2bb0f Author: J onathan Wiesel <jonathanwiesel@gmail.com> Date: Wed J ul 10 19:48:51 2013 -0430
jonathan's file added
diff --git a/hola,_soy_jonathan.md b/hola,_soy_jonathan.md new file mode 100644 index 0000000..876f92f --- /dev/null +++b/hola,_soy_jonathan.md @@ -0,0 +1,2 @@ +##Hola, soy J onathan. +##Estoy ayudando a Alberto \ No newline at end of file Una vez que hayamos creado nuevos tags y queramos compartirlos con el repositorio remoto slo debemos emplear el comando pull con la bandera tags de la siguiente manera: 1 2 3 4 $ git push origin master --tags Total 0 (delta 0), reused 0 (delta 0) To git@github.com:codeheroco/tutorial-git.git * [new tag] Capitulo-4 ->Capitulo-4
Conclusin Durante este captulo y en conjunto con los cursos anteriores ahora hemos adquirido el conocimiento bsico y fundamental para manejarnos remotamente con esta fabulosa herramienta. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la prxima semana!
Git desde Cero: Manejo de ramas
Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre cmo manejar las ramas en un proyecto y cules son las mejores prcticas. Los comandos a utilizar esta semana sern los siguientes: git checkout -b git branch -d git merge git branch (mltiples comandos.) nota: hemos creado un repositorio en Github con el curso para que descargues lo que hemos realizamos durante ste curso y le eches un vistazo.
Qu es una rama? S recordamos el primer captulo de git desde cero sabemos que cuando consolidamos cambios, creamos una fotografa del estado actual de la informacin que se encuentra en escenario, luego se descartaban los archivos que no tenan modificaciones y se reverenciaban al estado anterior. Al verificar el estado anterior se comprueba quin es o son padres directos de esta fotografa. Es decir, se busca cules son los cambios que fueron consolidados antes que este y se les referencia como el padre directo. Siguiendo este modelo, lo primero que consolidamos en el proyecto no tiene padre, los cambios consolidados sobre la rama principal tienen un nico padre, y los cambios que provienen de la unin de una o ms ramas tienen mltiples padres. Entonces, retomando Qu es una rama? Una rama es una extensin del rbol o tronco principal. Como buena prctica dentro de las ramas del rbol es donde deberamos introducir los cambios a nuestro proyecto y solo luego de comprobar que dichos cambios funcionan y tienen el comportamiento deseado los unimos con el rbol principal. Esto es porque queremos que el rbol se encuentre lo ms limpio posible. Para comprender esto es necesario realizar un ejemplo.
En la foto apreciamos que es un rbol en lnea recta que no presenta ramificaciones. > Para poder explicar el curso realizaremos los siguientes pasos: Crearemos una rama, trabajaremos sobre ella y guardaremos los cambios. Nos devolveremos a la rama principal y crearemos otra rama. Trabajaremos sobre esta rama, luego guardaremos los cambios y la uniremos con la rama principal. Iremos a la primera rama creada, realizaremos cambios y los guardaremos. Trataremos de unir esta primera rama con la principal y resolveremos los conflictos creados. De esta manera se comprender el uso de todos los comandos de este curso.
Checkout -b El comando checkout -b es el comando corto para crear una nueva rama y cambiarnos a la misma. 1 2 3 $ git checkout -b primera-rama #hemos creado la nueva rama y nos cambiamos Switched to a new branch 'primera-rama' Sobre esta nueva rama introduciremos un cambio sobre el archivo README.md 1 2 3 4 5 6 $ nano README.md
#Agregamos el siguiente texto. Este repositorio conserva absolutamente todo el historial del curso. Se encuentra clasificado por captulos almacenados en etiquetas (tags), para poder observar estos cambios debes revisar el log. Guardamos el archivo y consolidamos los cambios. 1 2 $ git add README.md $ git commit -m"Agregar prrafo al README" Una vez consolidados los cambios nos movemos nuevamente al rbol principal y posteriormente creamos una nueva rama. 1 2 3 4 5 6 $ git checkout master $ git checkout -b segunda-rama
#observamos la salida
Switched to a new branch 'segunda-rama' En este momento si entramos al archivo README.md podremos observar que su estado es el mismo del rbol principal y no tiene la informacin del prrafo que agregamos en la primera rama. Vamos a agregar un pequeo cambio a este archivo y luego los consolidaremos. 1 2 3 4 5 6 7 $ nano README.md
#Agregamos el siguiente texto Para ir a un captulo utilizamos:
$ git tag -l $ git checkout Capitulo-X #Donde X es el nmero del captulo. 8 9 10 11 12
#Subimos los cambios al escenario y los consolidamos.
En este momento el rbol comienza a presentar una ramificacin debido a que existen dos ramas en la cabeza del rbol. Donde solo una de ellas se encuentra de manera lineal.
Merge El comando merge es empleado para realizar la unin de dos ramas. Se debe tener cuidado cuando se realiza el merge ya que es muy probable que ocurran conflictos al ejecutarlo. Los conflictos ocurren cuando se trata de realizar la unin (merge) de dos archivos. stos dos archivos vienen siendo el mismo pero en ramas diferentes y pueden presentar discrepancia cuando se comparan lnea a lnea; de esto ocurrir estamos presenciando un conflicto. Realizaremos el merge de la segunda rama con el rbol principal. No existir conflicto alguno. Para realizar la unin de dos ramas debemos estar ubicados en la rama a la que se le quieren agregar los cambios, en este caso master y luego aplicar la unin. 1 2 3 4 5 $ git checkout master $ git merge segunda-rama
#Podemos apreciar que la unin se realiz correctamente y sin conflictos. Updating 0022f43..bc8fc31 6 7 8 Fast-forward README.md | 5 +++++ 1 file changed, 5 insertions(+)
Branch -d y -D Una vez que unimos la rama y hemos aplicado el cambio correctamente es buena prctica eliminar la rama donde trabajamos, es decir segunda-rama y la eliminamos con el siguiente comando: 1 2 $ git branch -d segunda-rama Deleted branch segunda-rama (was bc8fc31). Utilizando la bandera -d eliminamos la rama unicamente si esta se ha unido. de lo contrario nos arrojar un error. Si queremos desechar la rama completa sin importar la unin utilizamos -D como bandera. >
Resolver conflictos Uniremos la primera-rama y la rama principal master luego de haber unido los cambios de la segunda-rama. Cuando git realice la comparacin lnea a lnea encontr discrepancias y nos indicar que han ocurrido conflictos. Hagamos la prueba: 1 2 3 4 5 6 7 $ git checkout master $ git merge primera-rama
#Ocurri un conflicto Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result. Para resolver este conflicto basta con abrir el archivo con problemas(en nuestro caso README.md) buscar <<<<< >>>>>este tipo de flechas y rayas ====== eliminarlas y ajustar el cdigo o texto adecuadamente.
Acomodamos el texto como ms nos guste.
Revisamos el status de los archivos y apreciamos lo siguiente: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ git status #On branch master #Your branch is ahead of 'origin/master' by 1 commit. # (use "git push" to publish your local commits) # #You have unmerged paths. # (fix conflicts and run "git commit") # #Unmerged paths: # (use "git add <file>..." to mark resolution) # # both modified: README.md # no changes added to commit (use "git add" and/or "git commit -a") Nos dice que tenemos que hacer un commit para consolidar el merge de la unin de las dos ramas. Por otro lado tambin nos indica que el archivo README se encuentra modificado en las dos ramas y fue por esta razn que ocurri el conflicto. Consolidamos los cambios. 1 2 $ git add README.md $ git commit -m"Unin de primera-rama con master"
Podemos apreciar que tenemos una rama que crece del rbol principal y posteriormente se vuelve a unir con el rbol, dejando un lomo sobre el mismo.
Branch El comando branch en git funciona para el manejo de ramas. Existen muchas variaciones de este comando; aqu ensearemos las ms utilizadas. Cmo lo son git branch encargada de listar todas las ramas, git branch -v encargada de mostrar los ltimos comentarios de las consolidaciones que existieron en cada rama. git branch merge ensea nicamente las ramas que fueron unidas y git branch no-merge que muestra las ramas no unidas. 1 2 3 4 5 6 7 8 9 10 11 $ git branch * master primera-rama
$ git branch -v * master 05fe98e [ahead 3] Unin de primera-rama con master primera-rama df0589c Agregar prrafo al README
$ git branch --merged * master primera-rama Al apreciar las salidas arrojadas de dichos comandos observamos que son las ramas que conocemos y trabajos sobre este captulo.
Conclusin En este ltimo captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para utilizar ramas en los proyectos que desarrollemos, ste es un atributo fundamental en el flujo de trabajo de git. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la prxima semana!
Git desde Cero: Manejo de ramas remotas. Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre como manejar las ramas remotas en un proyecto y cuales son las mejores prcticas. Los comandos a utilizar esta semana sern los siguientes: git push (mltiples comandos) git checkout (nuevamente)
Qu es una rama remota? Una rama remota es una referencia al estado de una rama local en un repositorio remoto. Ests ramas generalmente son utilizadas para respaldar funcionalidades en desarrollo (no concluidas) en el repositorio sin afectar el estado de la raz del proyecto. Es decir, si comenzamos a trabajar en un cambio de apariencia para nuestro sitio web, pero no queremos exponerlo hasta que el mismo est concluido y deseamos trabajar tanto en el ordenador de casa como en el de la oficina deberamos crear una rama remota para lograr nuestro cometido. Las ramas remotas tienen como convencin de nombre el siguiente formato: (remoto)/(rama), donde la rama principal en un repositorio remoto se llama origin/master y todas las subramas en el repositorio remoto tendrn el prefijo origin y del otro lado el nombre de la rama que queramos darle; en nuestro caso podra ser primera-rama. Cabe destacar que si nosotros no aplicamos el comando gi t push or i gi n mast er cada vez que queramos respaldar cambios realizados localmente de nuestra rama principal el estado de la rama remota se quedar rezagado.
Push El comando push (empujar) es utilizado para compartir una rama sea la principal o una subrama del proyecto con el mundo. Quiero recordar que las ramas locales no se sincronizan automticamente con las remotas, es un comportamiento que se debe realizar manualmente. Podemos ver este comportamiento como privacidad. Ahora, vamos a comenzar una nueva rama e introducir unos cambios locales y compartirlos con el resto del mundo. 1 2 3 4 5 6 7 8 9 $ git checkout -b arreglos-varios Switched to a new branch 'arreglos-varios'
#una vez creada la rama vamos a crearla en el repositorio remoto.
$ git push origin arreglos-varios Total 0 (delta 0), reused 0 (delta 0) To git@github.com:codeheroco/tutorial-git.git * [new branch] arreglos-varios ->arreglos-varios Vamos a introducir los siguientes cambios. 1 2 3 4 5 6 7 8 $ mv hola,_soy_jonathan.md hola_jonathan.md #cambio de nombre
$ echo 'Estamos agregando unos ligeros cambios al archivo.' >>hola_jonathan.md
#los guardamos
$ git add . #agregamos al escenario todos los cambios. $ git commit -m"Cambio de nombre"
Ahora haremos lo siguiente a partir de nuestra rama arreglos-varios crearemos una nueva rama llamada duplicada-de-arreglos-varios y introduciremos un cambio. Luego de esto empujaremos estos cambios al repositorio remoto desde esta misma rama. Estando en la rama arreglos-varios ejecutamos el siguiente comando para crear una rama duplicada de la misma. 1 2 $ git checkout -b duplicada-de-arreglos-varios Switched to a new branch 'duplicada-de-arreglos-varios'
Introduciremos los siguientes cambios y posteriormente empujaremos hacia la rama arreglos-varios. 1 2 3 4 5 6 7 8 9 $ echo 'Estamos introduciendo un cambio, para utilizarlo en la demostracin.' >>hola_jonathan.md
$ git push origin duplicada-de-arreglos-varios:arreglos-varios Counting objects: 7, done. Delta compression using up to 4 threads. Compressing objects: 100% (6/6), done. Writing objects: 100% (6/6), 605 bytes | 0 bytes/s, done. Total 6 (delta 3), reused 0 (delta 0) To git@github.com:codeheroco/tutorial-git.git 05fe98e..c99705e duplicada-de-arreglos-varios ->arreglos-varios Qu queremos lograr demostrando esto? Lo principal es que una rama local no tiene por qu tener el mismo nombre que una rama remota, esto puede ser confuso pero queremos decir que es algo factible. Lo segundo, podemos realizar seguimiento y colaboracin sin importar nombres de ramas localmente, ejemplo: un compaero nuestro est trabajando en una funcionalidad nueva, y nosotros queremos descargar esa funcionalidad en una rama que tenemos creada local con un nombre distinto podramos hacerle seguimiento y colaborar con l. La tercera es que observando el caso anterior pudisemos simplemente hacerle seguimiento a la rama remota sin tener una rama local en nuestro equipo. Cmo hacemos seguimiento de una rama remota? Generalmente cuando uno clona un repositorio remoto nicamente se comienza a seguir los cambios de master que viene siendo la rama o raz principal del proyecto. para realizarle el seguimiento a una rama remota adicional se utiliza el siguiente comando. 1 $ git checkout --track origin/arreglos-varios Una vez empleado el comando vamos a observar que tenemos en nuestros gi t br anch - r una entrada adicional para *arreglos-varios`. Si ahora quisiramos colaborar en una rama remota haramos lo siguiente: crear una nueva rama llamada a-v a partir de la informacin que se encuentra en el repositorio remoto en la rama arreglos-varios, aplicando el siguiente comando. 1 2 3 $ git checkout -b a-v origin/arreglos-varios Branch a-v set up to track remote branch arreglos-varios fromorigin. Switched to a new branch 'a-v'
Cmo eliminar una rama remota? Muchas veces hemos trabajado y respaldado una rama en el repositorio remoto para realizar una funcionalidad especfica, pero dicha funcionalidad la hemos concluido y unido con master (nuestra rama principal), es aqu cuando nuestra rama secundaria que fue til para el desarrollo de la funcionalidad pierde sentido y algo nos dice que no debera estar ah, entonces decidimos borrarla utilizando el siguiente comando: 1 $ git push origin :arreglos-varios Esto lo que realiza es decirle al servidor que deseche la rama arreglos-varios. El comando es prcticamente idntico al que utilizamos para crear la rama remota, la nica diferencia es que le pasamos el prefijo : antes del nombre de la rama. Este comando es algo confuso pero muy utilizado, por eso es importante que lo memoricen ya que lo estarn utilizando frecuentemente.
Conclusin En este ltimo captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para utilizar ramas remotas en los proyectos que desarrollemos, ste es un atributo fundamental en el flujo de trabajo de git. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la prxima semana!
Git desde Cero: Rebase y Stash.
Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos de otra forma para realizar la unin de ramas llamada rebase , de como almacenar cambios sin tener que consolidarlos y cuales son las mejores prcticas a la hora de utilizar estas herramientas. Los comandos a utilizar esta semana sern los siguientes: git rebase. git stash (mltiples comandos).
Qu es git rebase? Si recordamos en captulos anteriores, especficamente en el captulo 5 hablamos sobre la herramienta merge, dicha herramienta es utilizada para unin de ramas. En Git existen dos estrategias principales para realizar la unin de ramas, la primera es la conocida merge y la segunda es rebase. Esta herramienta al igual que todas tiene sus pro y sus contra, pero en general una vez que aprendamos su flujo de trabajo se darn cuenta que posiblemente la mejor manera de realizar la unin de ramas en git. Qu hace rebase de especial? Cuando nosotros utilizamos esta herramienta para unir ramas, git sencillamente reproduce los cambios que consolidamos uno a uno en nuestra rama de trabajo y los lleva a la rama a donde queremos unirlos, es decir, genera una especie archivos virtuales que vienen siendo nuevas consolidaciones en la rama a la que se le unirn los cambios y los ubica uno detrs del otro en el mismo orden que se realizaron. Utilizando la estrategia de rebase al unir ramas, nos puede ayudar a evitar conflictos, siempre y cuando se realice con commits que no se hayan hecho pblicos, es decir, que no se encuentren en un servidor remoto. Si dichos cambios se encontraran abiertos al pblico y existiera gente trabajando sobre ellos y a nosotros se nos ocurre aplicar un rebase, puede que los compaeros que estn compartiendo el repositorio nos lleguen a odiar, ya que estamos modificando todos los commits y posiblemente el conflicto posterior al rebase sea ms difcil de reparar de lo que piensan. Por lo tanto como regla de oro jamas utilicen rebase posterior a la realizacin de un git push o sobre commitsque ya se encuentren en el repositorio remoto. Pongmonos en marcha y probemos cmo funciona el rebase! 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 $ git checkout master
#Creamos una nueva rama llamada readme-branch $ git checkout -b readme-branch
#Con un editor de texto editamos y escribimos lo siguiente. $ nano README.md
#pegamos el siguiente texto
#Repositorio git para el curso Git desde cero
Este repositorio conserva absolutamente todo el historial del curso. Se encuentra clasificado por captulos almacenados en etiquetas (tags), para poder observar estos cambios debes revisar el log.
Para bajar el repositorio completo con todos los captulos de la serie Git desde Cero, debes clonar el mismo en t equipo con el siguiente comando:
Luego para ir a un captulo en especfico utilizamos el comando:
$ git tag -l #listamos los captulos $ git checkout Capitulo-X #Donde X es el nmero del captulo.
De esta manera estamos cambiando al final del captulo con toda la "solucin" o texto del mismo. Consolidamos los cambios realizados y posteriormente realizamos el rebase de la rama readme-branch a la rama master de la siguiente manera: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $ git status $ git add README.md $ git commit -m"Mejor archivo README"
#aplicamos el rebase.
$ git rebase master Current branch readme-branch is up to date.
#para que los "commits" virtuales se consoliden en master tenemos que #unirlos con el merge.
$ git checkout master Switched to branch 'master'
$ git merge readme-branch Updating c99705e..48eb2db #en este punto esta consolidando en master. Fast-forward README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) Pudisemos tambin aplicar el rebase a una rama sin necesidad de estar ubicados en ella como por ejemplo, estando parados sobre una nueva rama llamada a-v creada a partir de master. Vamos a rebasar la rama readme-branch a master. hagamos la prueba! 1 2 3 4 $ git chechout -b a-v $ git rebase master readme-branch Switched to branch 'readme-branch' #git nos cambia a la rama readme-branch Current branch readme-branch is up to date. #Actualiza virtualmente master 5 6 7 8 9 10 11 12 13 14
#cambiamos de rama $ git co master Switched to branch 'master'
$ git merge readme-branch Updating c99705e..48eb2db Fast-forward README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) Listo ya hemos realizado un merge utilizando primero rebase. Recuerden que como buena prctica debemos o deberamos eliminar las ramas que han sido unidas y por ltimo sino quieren que sus compaeros los odien no vayan a realizar un rebase de una rama pblica!. 1 2 $ git branch -d readme-branch Deleted branch readme-branch (was 48eb2db).
Stash Muchas veces nos encontramos trabajando en una funcionalidad y nos llama un compaero de trabajo pidiendo ayuda o dicindonos que debemos modificar algo inmediatamente y que abandonemos lo que hacemos por un momento. Cuando esto ocurre sabemos que si nos cambiamos de rama los archivos modificados se vienen a la nueva rama y no queremos eso; por otra parte sera una locura realizar un commit incompleto o con cdigo defectuoso ya que esto nos puede traer problemas futuros, es aqu cuando entra en juego nuestro comando git stash. Qu realiza git stash? Simplemente almacena todos nuestras modificaciones y restaura nuestra rama al estado original para que cuando nos cambiemos de rama no nos llevemos los cambios incompletos, posteriormente podemos reaplicar estas modificaciones incompletas o borrar las mismas. Cmo lo utilizamos? Pues muy sencillo, vamos a agregar unos cambios a una nueva rama llamada rama- stash. Para probar como funciona, haremos stash de unos cambios y luego los volveremos a aplicar. 1 2 3 4 5 6 7 8 9 $ git checkout -b rama-stash Switched to a new branch 'rama-stash'
$ nano README.md
#Agregamos al final del archivo el siguiente prrafo y guardamos.
Recuerden que para la explicacin completa de este curso se pueden dirigir a 10 11 12 13 14 15 16 17 18 19 20 21 [codehero.co](http://codehero.co) o directamente a [codehero.co/series/git-desde-cero](http://codehero.co/series/git- desde-cero/)
#Si llegamos a mirar el status podemos apreciar los cambios
$ git status #On branch rama-stash #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: README.md # no changes added to commit (use "git add" and/or "git commit -a") Ahora guardaremos los cambios y posteriormente los volveremos a aplicar. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $ git stash Saved working directory and index state WIP on rama-stash: 48eb2db Mejor archivo README HEAD is now at 48eb2db Mejor archivo README
#Miramos el status y vemos que se encuentra limpio
$ git status #On branch rama-stash nothing to commit, working directory clean
#Podemos ver los cambios que se encuentran guardados en stash
$ git stash list Saved working directory and index state WIP on rama-stash: 48eb2db Mejor archivo README stash@{0}: WIP on rama-stash: 48eb2db Mejor archivo README Ahora nos toca escoger si queremos reaplicar los cambios o simplemente borrarlos, cualquiera de las dos opciones es posible en este momento. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #Para aplicar los cambios $ git stash pop #On branch rama-stash #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: README.md # no changes added to commit (use "git add" and/or "git commit -a") Dropped refs/stash@{0} (f511b3332361558cff180717868ac208132bb2bf)
#para borrarlos $ git stash drop Si existiera ms de un stash disponible, se tiene que decir explcitamente si queremos reaplicar los cambios o borrarlos de la siguiente manera: 1 2 $ git stash pop stash@{0} #Para reaplicar $ git stash drop stash@{0} #Para borrarlos El comando stash es uno de los ms utilizados cuando requerimos cambiarnos de rama para arreglar otro problema o simplemente requerimos un cambio de rama para realizar una prueba. Mi consejo es que siempre que puedan aplicarlo lo hagan y por favor no realicen commits con cdigo con errores.
Conclusin En este ltimo captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento para realizar la unin de ramas de una mejor manera y de cmo guardar cambios sin realizar un commit en los proyectos que desarrollemos, estos atributos son fundamentales en el flujo de trabajo de git. Profundizaremos un poco ms sobre rebase en captulos posteriores. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la prxima semana!
Git desde Cero: Comandos interactivos.
Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre como agregar interactivamente archivos al escenario (staging) y continuaremos con gi t r ebase tocando un punto importante sobre como modificar el historial de cambios. Los comandos a utilizar esta semana sern los siguientes: git rebase -i git add -i
Add -i Muchas veces cuando modificamos una gran cantidad de archivos y llega el punto de agregarlos al stage nos damos cuenta que no todos los archivos que modificamos guardan una relacin y por consiguiente ese nuevo commit que vamos a realizar tendr un ttulo y un comentario que no refleja todos los cambios realizados o por otro lado refleja todos los cambios pero los mismos no guardan una relacin entre s. Tomando un ejemplo. En una aplicacin MVC, pudimos haber modificado las vistas, el controlador y el modelo de los usuarios y haciendo esto nos dimos cuenta de unos detalles que pertenecan a las vistas relacionadas con las publicaciones del blog, estas no tienen nada que ver con los usuarios, pero de igual forma las corregimos. Cuando vayamos a realizar el commit la buena prctica nos indica que deberamos realizar no uno sino dos (2)commits para representar estos dos cambios distintos, la cuestin es, que puede ser algo tedioso agregar uno a uno estos cambios. Es aqu que el comando gi t add - i nos facilita y nos provee una manera agradable para realizar nuestro cometido. Cmo funciona? Vamos interactivamente a agregar una serie de archivos tanto nuevos como viejos al escenario de git y posteriormente a consolidarlos para ver visualmente como funciona el comando. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #Creamos un nuevo archivo $ touch nuevo_archivo.md
#Con un editor de texto agregamos la siguiente lnea.
$ nano nuevo_archivo.md #Este nuevo archivo ser utilizado para demostrar el "add interactivo".
#Luego modificamos el archivo hola_jonathan.md agregando Nueva informacin para este archivo.
#Por ltimo Archivo2_cambio_de_nombre.txt, agregando Agregamos la quinta lnea del archivo.
#Ahora interactivamente vamos a agregar todos estos archivos como dos commits distintos.
*** Commands *** 23 24 25 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help What now>4 Lo que nos indica la pantalla en este momento es que tenemos 2 archivos que presentan cambios pero no se han agregado al stage. Queremos agregar el nuevo archivo creado al escenario y sumarle uno de los viejos para realizar posteriormente un commit. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #Continuando What now>4 1: nuevo_archivo.md Add untracked>>1 * 1: nuevo_archivo.md Add untracked>>#Presionamos la tecla enter/return. added one path
*** Commands *** 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help What now>1 #Revisamos el git status staged unstaged path 1: unchanged +2/-0 Archivo2_cambio_de_nombre.txt 2: unchanged +2/-0 hola_jonathan.md 3: +1/-0 nothing nuevo_archivo.md
*** Commands *** 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help What now>2 En este momento observamos que luego de agregar el nuevo archivo y de revisar el stage utilizando la opcin 1, el comando interactivo ya nos dice que hemos agregado satisfactoriamente al stage el nuevo_archivo.md y presenta 1 lnea de cambio. Continuemos, agreguemos uno de los viejos archivos al stage. 1 2 #Continuando What now>2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 staged unstaged path 1: unchanged +2/-0 Archivo2_cambio_de_nombre.txt 2: unchanged +2/-0 hola_jonathan.md Update>>2 #Elegimos el segundo archivo. staged unstaged path 1: unchanged +2/-0 Archivo2_cambio_de_nombre.txt * 2: unchanged +2/-0 hola_jonathan.md Update>>#Presionamos la tecla enter/return. updated one path
*** Commands *** 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help What now>1 #Revisamos el git status staged unstaged path 1: unchanged +2/-0 Archivo2_cambio_de_nombre.txt 2: +2/-0 nothing hola_jonathan.md 3: +1/-0 nothing nuevo_archivo.md
*** Commands *** 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help What now>6 Vemos que en este momento existen nuestros 2 archivos en escenario. Ahora podemos realizar un diff sobre cualquiera de los archivos que ah se encuentren. Este diff dentro del comando interactivo es un simil a utilizar el comando gi t di f f - - cached que utilizamos en los primeros cursos. 1 2 3 4 5 6 7 #Continuando What now>6 staged unstaged path 1: +2/-0 nothing hola_jonathan.md 2: +1/-0 nothing nuevo_archivo.md Review diff>>#elegimos cualquiera de los 2 *** Commands *** 8 9 10 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help What now>7 #Nos salimos. Hemos concluido y salido del gi t add - i y agregamos nuestros dos archivos para el commit, si queremos, podemos ejecutar el comando gi t st at us para comprobar que lo que hemos agregado mediante el comando gi t add - i funcion como esperabamos. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ git status #On branch master #Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: hola_jonathan.md # new file: nuevo_archivo.md # #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: Archivo2_cambio_de_nombre.txt # Podemos observar que todo est listo para realizar el commit que queremos. El commit se realiza normalmente utilizando nuestro conocido comando gi t commi t . Para este caso en particular haremos algo diferente para demostrar el comandogi t r ebase - i . Guardaremos estos cambios en un stash, los llevaremos a una nueva rama y haremos el rebase interactivo. Previo a realizar un gi t st ash agregamos todos los archivos al escenario antes de cambiar de rama. 1 2 3 4 5 6 $ git add . $ git stash Saved working directory and index state WIP on master: f2ead5d Referencia en readme. HEAD is now at f2ead5d Referencia en readme.
$ git co -b rama-para-rebase-interactivo Switched to a new branch 'rama-para-rebase-interactivo'
#Aplicamos los cambios del stash
$ % git stash pop #On branch rama-para-rebase-interactivo #Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: nuevo_archivo.md # #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: Archivo2_cambio_de_nombre.txt # modified: hola_jonathan.md # Dropped refs/stash@{0} (eb15ce2cc60a1829f24442fb14b3e69eb0866580) En este momento s realizaremos los respectivos commits como estaban planeados. Es decir, el archivo nuevo y no de los viejos. 1 2 3 4 5 6 7 8 9 10 $ git add hola_jonathan.md $ git commit -m"Commit planeado. archivo nuevo y viejo" [rama-para-rebase-interactivo a735092] Commit planeado. archivo nuevo y viejo 2 files changed, 3 insertions(+) create mode 100644 nuevo_archivo.md
#Hacemos el commit del archivo viejo que qued solo.
$ git status #On branch rama-para-rebase-interactivo 11 12 13 14 15 16 17 18 19 20 21 22 #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: Archivo2_cambio_de_nombre.txt # no changes added to commit (use "git add" and/or "git commit -a")
$ git add Archivo2_cambio_de_nombre.txt $ git commit -m"Archivo2 con cambios en la lnea 5" [rama-para-rebase-interactivo 38a72fd] Archivo2 con cambios en la lnea 5 1 file changed, 2 insertions(+) Ahora pasemos al rebase interactivo.
Rebase -i El comando gi t r ebase - i nos permite realizar varias cosas, entre ellas modificar el historial de cambios. Es decir, podemos comprimir varios commits en uno solo, borrar commits, cambiarles el mensaje o simplemente modificar un commitcompletamente. El comando es bastante complejo pero es muy interesante. Recomendamos utilizarlo con cuidado. Cabe destacar que para utilizar este comando git abre un editor de texto por lo que se recomienda predefinir uno previamente. En nuestro caso utilizaremos el popular Sublime Text 2 para esto. Con el siguiente comando podemos predefinir el editor en git. gi t conf i g - - gl obal cor e. edi t or " subl - w" o si prefieren usar vim. gi t conf i g - - gl obal cor e. edi t or " vi m" . Cuando utilicemos el comando gi t r ebase - i tenemos que tener claro que en la pantalla del editor de texto aparecern los commits ordenados desde el ms viejo al ms nuevo. El rebase interactivo nos presenta todas estas opciones. Pick Pick se utiliza para incluir un commit. Por defecto se le ver una lista de los commits existentes en el rebase, en el orden de ms viejo (superior) a la ms reciente (abajo). Reorganizar el orden de los commits durante el rebase cambiar el orden de los commits cuando concluya el mismo. Reword Esto es similar al Pick, pero el proceso de rebase se detendr y le dar la oportunidad de cambiar el mensaje asociado alcommit. El contenido de la confirmacin no se modificar. Edit Ejecutar el Pick y luego pausar el rebase. Durante esta pausa puede modificar el commit, aadir o eliminar archivos dentro del mismo. Tambin se pueden hacer otros commits y luego continuar el rebase, esto permite separar un commit grande en unos ms pequeos. Squash Este comando le permite combinar dos o ms commits en uno solo. fixup Esto es similar al squash, pero el mensaje asociado al commit se descartar y se utilizar el mensaje que tenia el commit con el commando pick. Exec Esto le permite ejecutar comandos shell arbitrarios automticamente contra un commit. Una vez comprendido esto, hagamos nuestro gi t r ebase - i con un squash de los 2 commits para tener un historial ms limpio. 1 2 3 4 5 6 7 8 9 $ git rebase -i master
#Se abre el editor de texto y se nos presenta lo siguiente.
pick a735092 Commit planeado. archivo nuevo y viejo pick 38a72fd Archivo2 con cambios en la lnea 5
#Rebase f2ead5d..38a72fd onto f2ead5d # 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #Commands: # p, pick =use commit # r, reword =use commit, but edit the commit message # e, edit =use commit, but stop for amending # s, squash =use commit, but meld into previous commit # f, fixup =like "squash", but discard this commit's log message # x, exec =run command (the rest of the line) using shell # #These lines can be re-ordered; they are executed fromtop to bottom. # #If you remove a line here THAT COMMIT WILL BE LOST. # #However, if you remove everything, the rebase will be aborted. # #Note that empty commits are commented out
#Realizaremos el siguiente cambio en la segunda lnea nicamente, cambiamos pick por squash.
pick a735092 Commit planeado. archivo nuevo y viejo squash 38a72fd Archivo2 con cambios en la lnea 5
#Guardamos los cambios y cerramos el editor. Se abrir nuevamente para que modifiquemos el mensaje del commit si nos provoca. Pero no haremos nada. El resultado es el siguiente.
[detached HEAD de13f1b] Commit planeado. archivo nuevo y viejo 3 files changed, 5 insertions(+) create mode 100644 nuevo_archivo.md Successfully rebased and updated refs/heads/rama-para-rebase-interactivo. Luego queda realizar el merge con la rama master y todo estar listo. 1 2 3 4 $ git checkout master $ git merge rama-para-rebase-interactivo Updating f2ead5d..de13f1b Fast-forward 5 6 7 8 9 10 11 12 13 Archivo2_cambio_de_nombre.txt | 2 ++ hola_jonathan.md | 2 ++ nuevo_archivo.md | 1 + 3 files changed, 5 insertions(+) create mode 100644 nuevo_archivo.md
#Borramos la rama recin unida.
$ git branch -d rama-para-rebase-interactivo En este punto si observamos nuestro log observamos que existe un solo commit que contiene todas las modificaciones antes descritas. Debo recordarles nuevamente que no realicen un rebase sobre una rama que sea pblica y menos todava si hace un squasho un edit. Todo el mundo se los agradecer.
Conclusin En este ltimo captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para utilizar ramas y modificar el historial de cambios y agregar archivos interactivamente. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la entrante!
Git desde Cero: Personalizar la configuracin de Git.
Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre como personalizar la configuracin de git. Pondremos colores en nuestro terminal que funcionan para representar cambios, colores en el log, alias de comandos, entre otros detalles. Por ser un curso un poco distinto no nos enfocaremos en comandos particulares sino ms bien en el archivo .gitconfig que se encuentra en el $HOME del usuario.
Configuracin de git push Posterior a la versin 1.7.11 de git, se introdujeron cambios en la manera como git realiza push y requiere que se escoja una opcin por defecto. En este momento existen cinco (5) maneras diferentes para trabajar con el comando push que son:nothing, current, upstream, matching y simple. Nothing: Utilizando esta opcin por defecto el comando gi t push no subir nada. Current: Utilizando current por defecto se subirn los cambios a una rama remota que tenga el mismo nombre que la rama local. Es decir: si, estamos trabajando sobre una rama llamada hola-mundo y hacemos gi t push de los cambios que tengamos locales, se subirn a una rama en el repositorio remoto con el mismo nombre, sino existe, crear la rama. Upstream: Referencia la rama remota con la local. Estas no tienen porqu tener el mismo nombre para subir los cambios. Simple: Funciona de la misma manera que upstream pero se niega completamente a subir la informacin si la rama que est en el repositorio remoto no existe o no se llama igual que la local. Matching: Absolutamente todas las ramas deben tener el mismo nombre en los dos extremos, es decir, tanto local como remoto. Si se crea una rama local se crear remota tambin. nota: Como preferencia personal globalmente utilizo Current ya que se adapta ms a mi manera de trabajar. En todo caso, sera adecuado que vayan probando cual les funciona mejor ya que todas las opciones son interesantes. Cmo coloco una opcin de estas por defecto? Es bastante, se podra colocar una global o una local (para un proyecto especfico) de la siguiente manera. 1 $ git config --global push.default current 2 3 #De manera local en un proyecto especfico. $ git config --local push.default upstream Todas configuraciones globales se escriben en un archivo en el $HOME del usuario que tiene siempre el mismo nombre y se llama .gitconfig es oculto. Por otro lado las configuraciones locales de proyecto se escriben en la carpeta .git dentro de un archivo que se llama config, este archivo es el mismo que contiene las referencias a las ramas remotas y configuraciones del proyecto, etc.
Configuracin de git pull Normalmente cuando utilizamos gi t pul l sobre una rama, sta realiza dos funciones gi t f et ch y gi t mer ge sta ltima puede ocasionar conflictos que debemos solucionar y posteriormente unirlos a mano con otro merge agregando informacin que no aporta nada al historial del proyecto. Por esta razn es recomendable, que de requerir realizar un pull se emplee el comando rebase en vez del merge de manera directa. Para realizar esto debemos cambiar la configuracin por defecto de git o utilizar gi t pul l - - r ebase cada vez que se quieran descargar actualizaciones del servidor remoto. Como manera ms practica cambiemos la configuracin por defecto 1 $ git config --global --bool pull.rebase true De requerir volver a un simple merge por una ocasin especfica se puede emplear el comando gi t pul l - - no- r ebasey listo.
Configurando alias a comandos. De la misma manera que los sistemas operativos *nix tienen una utilidad llamada alias para colocar un nombre alternativo a archivos, comandos, direcciones, etc.. Git tambin lo incorpora, pero de manera especfica para sus comandos.
Para qu podemos utilizar los alias? Si se estn preguntando en que caso particular se puede utilizar esta utilidad, mi respuesta directa sera, en aquellos comandos que utilizan frecuentemente o que realmente son complicados de escribir cuando se necesitan. Como ejemplo crearemos alias a tres (3) comandos altamente utilizados. gi t st at us gi t checkout gi t l og - - pr et t y=f or mat : ' %h - %an, %ar - %s' - - gr aph Para el status utilizaremos la abreviacin st, para checkout como co y el log como lg. 1 2 3 4 5 $ git config --global alias.st status
$ git config --global alias.co checkout
$ git config --global alias.lg "log --pretty=format:'%h - %an, %ar : %s' --graph" Ahora si reiniciamos el Terminal con bash - l , exec $SHELL - l o simplemente cerrando y abriendo uno. los tendremos funcionando. Como haba dicho ms arriba si realizamos una lectura del archivo .gitconfig podremos ver como est estructurado el mismo. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ cat ~/.gitconfig [alias] co =checkout st =status lg =log --pretty=format:'%h - %an, %ar : %s' --graph [core] editor =subl -w [user] name =albertogg email =example@gmail.com [push] default =current [pull] rebase =true De manera muy sencilla se puede entender para que funciona cada etiqueta del archivo.
Configurando colores en el terminal. Si tienen un terminal con ZSH con oh-my-zsh o su alternativa en Bash seguramente te gustan los colores, la personalizacin del terminal y estoy seguro que vas a poder observar colores por defecto cuando empleemos las opciones que te vamos a ensear! Cmo le pongo colores a un status o a un log? Existen dos maneras claves, si lo que quieres ver son un par de colores y no te importa mucho, puedes dejar las opciones por defecto que te mostraremos a continuacin, pero si quieres que el terminal vomite un arcoiris cuando escribas status o logte llevar un poco ms de tiempo pero es igualmente sencillo. Primero para utilizar los colores que git nos proporciona por defecto debemos incluir esta opcin gi t conf i g - - gl obal col or . ui t r ue. Luego de manera especfica agregar que comandos queremos colorear. 1 2 3 $ git config --global color.ui true $ git config --global color.status auto $ git config --global color.log auto. A partir de este momento cuando empleemos estos comandos se representarn las modificaciones en el status con colores rojo y verde. Por otro lado el log tendr algo de amarillo en los ttulos. De los colores que nos ofrece git como el estandar u opcin por defecto tambin los podemos personalizarlos de la siguiente manera: 1 2 $ git config color.status.changed green $ git config color.status.untracked cyan Esto cambiar el color de los archivos modificados a verde y de los archivos que git no sigue en cyan. Si queremos representar todo el texto con un color diferente en cualquier seccin, podramos crear un alias en conjunto con los colores, algo como: 1 $ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit Ten en cuenta que git es altamente personalizable y ms cuando mezclamos nuestros conocimientos con un poco de ayuda del internet.
Conclusin En este ltimo captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para configurar y personalizar git a la medida vale la pena si quieren indagar un poco ms sobre este tema que revisen el manual gi t conf i g - h y busquen por internet. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la semana entrante!
Git desde Cero: Submdulos.
Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre como agregar, actualizar y utilizar un submdulo en nuestros proyectos. Los comandos a utilizar esta semana sern los siguientes: git submodule * (varios comandos)
Introduccin a submdulos De manera frecuente vemos la necesidad de utilizar otro proyecto o librera dentro del proyecto en que se est trabajando. En algunos lenguajes de programacin como Ruby o Python existen manejadores de libreras que facilitan esta tarea. Hay otros como Objective-c que no tienen (cocoa-pods existe pero a la fecha no es la herramienta por excelencia) y es por esta razn se torna engorrosa la tarea de instalar y actualizar libreras de terceros o de nosotros mismos en cualquier proyecto que estemos realizando. Git viene a resolver el problema de instalacin o reutilizacin de cdigo con submdulos. Los submdulos no son ms que proyectos git dentro de una subcarpeta que a su vez se encuentra dentro de otro proyecto git, el cual permite clonar un segundo repositorio dentro del repositorio padre el cual viene siento en el que se est trabajando y nos posibilita mantener los cambios separados. Esto puede parecer algo engorroso al principio pero vamos a probarlo para observar sus pro y sus contra.
Agregando un submdulo Para este curso, agregaremos otro de los proyectos de Codehero como submdulo del curso de git. y haremos la demostracin completa de como agregar, clonar, y los posibles problemas asociados a los submdulos. Empecemos por agregar el submdulo, en este caso ser el de chef. Lo primero que debemos hacer es ir y buscar el URL del repositorio en git. 1 2 3 4 5 6 7 8 $ git submodule add https://github.com/codeheroco/chef.git chef-submodule Cloning into 'chef-submodule'... remote: Counting objects: 335, done. remote: Compressing objects: 100% (190/190), done. remote: Total 335 (delta 77), reused 332 (delta 77) Receiving objects: 100% (335/335), 267.46 KiB | 72.00 KiB/s, done. Resolving deltas: 100% (77/77), done. Checking connectivity... done Con el comando anterior hemos realizado lo siguiente. Creamos un submdulo llamado chef-submodule el cual viene siendo una carpeta ms dentro de nuestro proyecto y descargamos todo el contenido del repositorio chef dentro de ella. Si ahora miramos el gi t st at us del repositorio principal observamos lo siguiente. 1 2 3 4 $ git status #On branch master #Changes to be committed: # (use "git reset HEAD <file>..." to unstage) 5 6 7 8 # # new file: .gitmodules # new file: chef-submodule # Se cre un archivo oculto llamado .gitmodules el cual tiene la informacin necesaria sobre l o los submdulos que queramos tener en nuestro proyecto. 1 2 3 4 $ cat .gitmodules [submodule "chef-submodule"] path =chef-submodule url =https://github.com/codeheroco/chef.git Es importante que este archivo suba al control de versiones y no se agregue en ningn momento al archivo .gitignore. Si ahora realizamos un gi t di f f - - cached sobre nuestro submdulo podemos ver que aunque chef-submodule es una subcarpeta con un repositorio interno independiente de nuestro proyecto, git identifica que se realizaron cambios dentro de la misma, lo que nos indica que se debe realizar un gi t commi t para respaldar el nuevo estado del proyecto principal. 1 2 3 4 5 6 7 8 9 $ git diff --cached chef-submodule diff --git a/chef-submodule b/chef-submodule new file mode 160000 index 0000000..57532b1 --- /dev/null +++b/chef-submodule @@ -0,0 +1 @@ +Subproject commit 57532b1d0888246b38c94ba2c70861548257cd6f (END) Si observamos detenidamente el diff, vemos que el cambio que git detecta es simplemente un cambio en el HEAD del submdulo, es decir que el hash del ltimo commit cambi. Realicemos el commit del proyecto con el submdulo. 1 2 3 4 $ git commit -m"Primer commit con un submdulo" [master 2614422] Primer commit con un submdulo 2 files changed, 4 insertions(+) create mode 100644 .gitmodules 5 create mode 160000 chef-submodule De manera efectiva hemos guardado nuestro proyecto en un repositorio git en conjunto con el submdulo.
Clonando un repositorio con un submdulo Si quisiramos clonar el proyecto completo del tutorial-git ahora que tiene un submdulo, tendramos que realizar los siguientes pasos: Clonar el repositorio principal. Cambiar al directorio del repositorio Inicializar el submdulo. Actualizar el submdulo. Realicemos la demostracin: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $ git clone https://github.com/codeheroco/tutorial-git.git Cloning into 'tutorial-git'... remote: Counting objects: 49, done. remote: Compressing objects: 100% (31/31), done. remote: Total 49 (delta 18), reused 43 (delta 12) Unpacking objects: 100% (49/49), done. Checking connectivity... done
$ git submodule update Cloning into 'chef-submodule'... remote: Counting objects: 335, done. remote: Compressing objects: 100% (190/190), done. remote: Total 335 (delta 77), reused 332 (delta 77) Receiving objects: 100% (335/335), 267.46 KiB | 67.00 KiB/s, done. Resolving deltas: 100% (77/77), done. Checking connectivity... done Submodule path 'chef-submodule': checked out '57532b1d0888246b38c94ba2c70861548257cd6f' De la misma manera que actualizamos el submdulo aqu, para descargar la informacin que contiene dicho submdulo, se realiza cuando se requiere actualizar en caso de que alguien haya introducido alguna modificacin. sta actualizacin viene siendo lo mismo que hacer gi t pul l - - r ebase en el repositorio principal.
Posibles problemas introducidos con submdulos Uno de los principales errores que se cometen al utilizar submdulos es cuando uno de los desarrolladores introduce cambios locales en el cdigo de alguno de los submdulos, realiza su commit, y lo confirma en el repositorio principal, hacepush del repositorio principal pero no del submdulo. Entonces cuando alguien quiere realizar un gi t submodul e updat eel commit que se encuentra en la cabecera no corresponde con el que dice la informacin del proyecto ocurriendo un error incorregible hasta que no se actualice el submdulo por la persona correcta. 1 2 3 $ git submodule update fatal: reference isnt a tree: 57532b1d0888246b38c94ba2c70861548257cd6f Unable to checkout '57532b1d0888246b38c94ba2c70861548257cd6f' in submodule path 'chef-submodule' Por esta razn hay que tener cuidado cuando uno utiliza submdulos, por un pequeo olvido nos puede causar una tarde amarga.
Conclusin En este ltimo captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para utilizar submdulos dentro de nuestros proyectos, ya sea para reutilizar nuestro propio cdigo o simplemente agregar una librera externa. Si quieren indagar un poco ms sobre este tema que revisen el manual gi t submodul e - h y busquen por internet. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la semana entrante!
Git desde Cero: Utilizando Git Subtree.
Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre como agregar, actualizar y utilizar una alternativa a los submdulos de git, llamada subtree en nuestros proyectos. Los comandos a utilizar esta semana sern los siguientes: git subtree (mltiples comandos) git remote add * git fetch
Por qu utilizar subtree y no submdulos? Si recuerdan la semana pasada cuando aprendimos submdulos observamos que pueden existir ciertos problemitas o complejidades cuando se emplea el esquema de submdulos para el manejo de subprojectos. Existen varias razones por las cuales uno podra preferir utilizar subtree (subrbol) por encima de un submdulo, entre las ms destacadas se encuentran: Manejo del subtree utiliza prcticamente los mismos comandos bsicos que aprendimos en las primeras lecciones. Cuando clonamos un proyecto con un subtree no debemos aplicar ms comandos adicionales. Los subtrees no agregan metadata adicional al proyecto (.gitmodule). Subtree es soportado por versiones viejas de git antes de la 1. 5. 2. De las razones que probablemente no nos agraden tanto, se encuentran las siguientes: Contribuir cambios desde el subtree al proyecto original es un poco ms complicado de lo normal. Tener la capacidad para no mezclar cdigo entre el proyecto principal y el subtree queda de parte de nosotros.
Cmo se usa un subtree? El comando o utilidad de subtree viene por defecto incluido en git desde la versin 1. 7. 11 de Mayo del 2012. Les recomiendo que de encontrarse en una versin ms vieja que la antes mencionada actualicen para que disfruten de esta poderosa herramienta. Existen dos formas bsicas para utilizar subrbol, una rpida y otra organizada. La diferencia entre las dos es la longitud del comando que debemos memorizar. Comencemos por la rpida. Para esta prueba vamos a utilizar el repositorio de node y express rutas de codehero.co. Cmo agregar el subrbol al proyecto? 1 2 3 4 5 $ git subtree add --prefix node_express_subtree https://github.com/codeheroco/nodejs-y-express-rutas master --squash git fetch https://github.com/codeheroco/nodejs-y-express-rutas master Fromhttps://github.com/codeheroco/nodejs-y-express-rutas * branch master ->FETCH_HEAD Added dir 'node_express_subtree' Con este comando hemos creado una capeta llamada node_express_subtree donde estamos guardando la informacin del repositorio node y express rutas que se encuentra en la rama mast er y adems solo estamos almacenando localmente el ltimo commit en nuestro ordenador al usar la bandera - - squash. Si observamos el log, podemos apreciar lo que se describi en el prrafo anterior. 1 2 3 4 5 $ git log --pretty=format:'%h - %an, %ar : %s' --graph * 08bddd4 - albertogg, 59 minutes ago : Merge commit '4f34bfe8efc8f797bac71dfcd736cb7fa14efc42' as 'node_express_subtree' |\ | * 4f34bfe - albertogg, 59 minutes ago : Squashed 'node_express_subtree/' content fromcommit 0f81501 * 2614422 - albertogg, 7 days ago : Primer commit con un submdulo Qu pasa si semanas despus, se han introducido mltiples cambios al proyecto que nosotros tenemos como subproyecto y queremos actualizarlo? Pues la respuesta es bastante sencilla. Al igual que cuando utilizamos pul l para actualizar nuestro proyecto principal hacemos esto pero agregando el subcomando subt r ee, de la siguiente manera: 1 2 3 4 $ git subtree pull --prefix node_express_subtree https://github.com/codeheroco/nodejs-y-express-rutas master --squash Fromhttps://github.com/codeheroco/nodejs-y-express-rutas * branch master ->FETCH_HEAD Subtree is already at commit 0f815018df127cd663ecc8b89500d5f40f40b9b4. Como el proyecto node y express rutas no presenta modificaciones el comando nos dice que se encuentra en el commit0f815018df127cd663ecc8b89500d5f40f40b9b4, es decir en la ltima versin. La manera ms organizada de utilizar sera agregando en primera mano la ruta remota al proyecto con un alias para no tener que recordar el URL del mismo. El trabajo posterior a esto es prcticamente lo mismo que se realiz en la manera rpida con ligeras modificaciones. 1 2 3 4 $ git remote add -f node_express_subtree https://github.com/codeheroco/nodejs-y-express-rutas Updating node_express_subtree Fromhttps://github.com/codeheroco/nodejs-y-express-rutas * [new branch] master ->node_express_subtree/master Si revisamos las ramas remotas que tenemos asociadas al proyecto observamos que node_expr ess_subt r ee est identificada dentro de la lista. 1 2 3 4 5 $ git remote -v node_express_subtree https://github.com/codeheroco/nodejs-y-express-rutas (fetch) node_express_subtree https://github.com/codeheroco/nodejs-y-express-rutas (push) origin git@github.com:codeheroco/tutorial-git.git (fetch) origin git@github.com:codeheroco/tutorial-git.git (push) Ahora agregamos el subrbol al proyecto. 1 $ git subtree add --prefix node_express_subtree node_express_subtree master --squash Para actualizar el subrbol 1 2 3 4 5 $ git fetch node_express_subtree $ git subtree pull --prefix node_express_subtree node_express_subtree master --squash Fromhttps://github.com/codeheroco/nodejs-y-express-rutas * branch master ->FETCH_HEAD Subtree is already at commit 0f815018df127cd663ecc8b89500d5f40f40b9b4. Cmo contribuir cambios desde el subtree? Debemos tener una rama de upst r eamque debera ser un fork del proyecto original al que queremos contribuir en nuestra cuenta o carpeta personal de github (esto nicamente si dicho proyecto se encuentra en github) y agregar su direccin remota. 1 $ git remote add albertogg-node-express https://github.com/albertogg/nodejs-y-express-rutas Una vez que tengamos esta direccin remota disponible queda hacer un push a nuestro proyecto y posteriormente hacer un pull-request al proyecto principal. 1 $ git subtree push --prefix=node_express_subtree albertogg-node-express master S que puede parecer algo confuso, pero realmente es lo que hemos estado trabajado a lo largo de todos estos cursos, nicamente se est agregando el subcomando de gi t subt r ee antes del resto de las acciones principales de git.
Conclusin En este ltimo captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para utilizar subrboles dentro de nuestros proyectos, ya sea para reutilizar nuestro propio cdigo o simplemente agregar una librera externa. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la semana entrante!
Git desde Cero: Blame y Bisect
Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre como realizar debugging utilizando Git, con las herramientas gi t bi sect y gi t bl ame. Los comandos a utilizar esta semana sern los siguientes: git blame * (varios comandos) git bisect * (varios comandos)
Realizar debugging en git? Muchas veces en nuestros proyectos y de manera involuntaria, introducimos errores en el cdigo fuente. Existen herramientas que nos ayudan a resolver, a cubrir y darnos cuenta de los defectos que hemos introducido de forma inmediata sobre todo cuando se programa de manera orientada a pruebas, mayormente conocida como TDD (Test Driven Development). Con todo y estas ayudas para asegurarnos de que nuestras funciones realizan lo que queremos; muchas veces entre una versin y otra el comportamiento de una funcin cambia ligeramente y nuestra unidad de pruebas no lo detecta. Cmo confiamos plenamente en ella realizamos un commit de nuestro cdigo y lo subimos al repositorio remoto. Seguimos programando y subimos otros ms. De repente nuestros usuarios comienzan a levantar tickets a cerca de un error recurrente; cuando revisamos el cdigo fuente para detectar porqu se produce este error, no detectamos a simple vista que es lo que sucede. En este punto recurrimos a el control de versiones para ir a versiones anteriores y ver que hemos cambiado en estos ltimos commits. Canalizamos la falla a un archivo, y utilizamos nuestras herramientas gi t bl ame ygi t bi sect las cuales nos ayudarn a detectar, cuando se introdujo el error y que lo motiva.
Qu realiza el git blame? El comando gi t bl ame nos permite observar toda la informacin de manera detallada a cerca de un commit. Entre la informacin que nos brinda el comando est: Quin escribi cada linea en el archivo, cuando lo hizo y a que commitpertenece. La palabra blame en idioma Ingls es referente a quien echarle la culpa o quien es el culpable segn sea su contexto. Por este motivo llaman a este comando de esta forma. Vamos a verlo en accin. 1 2 3 4 5 6 7 8 9 10 11 $ git blame app.js c4c4f2a2 (J onathan Wiesel 2013-09-02 22:38:34 -0430 6) var dotenv =require('dotenv')(); c4c4f2a2 (J onathan Wiesel 2013-09-02 22:38:34 -0430 7) dotenv.load(); c4c4f2a2 (J onathan Wiesel 2013-09-02 22:38:34 -0430 8) ae36bb76 (Oscar Vicente Gonzlez Greco 2013-08-25 14:05:52 -0430 9) var express =require('express') ae36bb76 (Oscar Vicente Gonzlez Greco 2013-08-25 14:05:52 -0430 10) , http =require('http') ae36bb76 (Oscar Vicente Gonzlez Greco 2013-08-25 14:05:52 -0430 11) , path =require('path') c4c4f2a2 (J onathan Wiesel 2013-09-02 22:38:34 -0430 12) , db =require('./dbConfig') 98b032f9 (Oscar Vicente Gonzlez Greco 2013-08-29 18:14:19 -0430 13) , auth =require('./passportConfig') 98b032f9 (Oscar Vicente Gonzlez Greco 2013-08-29 18:14:19 -0430 14) , flash =require("connect-flash"); ae36bb76 (Oscar Vicente Gonzlez Greco 2013-08-25 14:05:52 -0430 15) Podemos apreciar que lo primero que nos muestra es el hash corto, nico del commit, luego encontramos el nombre de usuario que realiz, la fecha, y la respectiva lnea de cdigo. Tambin podemos filtra el nmero de commits que queremos observar. Por ejemplo: si sabemos que nuestro problema comenz a ocurrir a partir de un commit especfico y se refleja hasta X commit ms adelante filtramos estos resultados para encontrar que se modific en estos commit. 1 $ git blame ae36..c4c4 -- app.js Si queremos cambiar el nombre de la persona por su email, realizamos lo siguiente. 1 $ git blame -e app.js En general y con la ayuda este comando podemos encontrar quin fue el culpable de introducir un error particular en uno de nuestros proyectos.
Qu realiza el git bisect? Este comando nos ayuda a verificar que fue lo que sucedi con nuestro cdigo entre varios commits, es decir. Le notificamos a Git que versin est buena o no produce el error y que versin da el error o se comporta de manera extraa. De aqu en adelante git busca un commit intermedio a estos dos que le dimos anteriormente y realiza una especie decheckout el cual nos permite estar en la versin de cdigo del commit intermedio, es aqu cuando realizamos nuestras pruebas, si todo marcha acode a lo deseado, le notificamos a git que ste commit se encuentra bien y proseguimos, luego git vuelve a buscar otro commit intermedio a este nuevo que nosotros confirmamos como correcto y el commit final de nuestra bsqueda. Realizamos el mismo procedimiento hasta dar con el error. Vamos a demostrarlo. 1 2 3 4 5 6 7 8 $ git log * c811a8b - J onathan Wiesel, 3 days ago : cambiado tamao de username en model user * 489c942 - J onathan Wiesel, 3 days ago : ignorado archivo de intelliJ * 98b032f - Oscar Vicente Gonzlez Greco, 5 days ago : se agrego soporte para sesiones con passport.js * 288dce7 - Oscar Vicente Gonzlez Greco, 9 days ago : se eliminaron los DS_store ; * 2b0356f - Oscar Vicente Gonzlez Greco, 9 days ago : re arregl gitignore * ae36bb7 - Oscar Vicente Gonzlez Greco, 9 days ago : Se elimin intellij. se agreg orm. se reorganiz estructura del proyecto a una ms mantenible. * e2d314d - Oscar Vicente Gonzlez Greco, 2 weeks ago : commit inicial / se hizo un CRUD de usurio Vamos a elegir el commit e2d314d cmo bueno y c4c4f2a cmo el malo. 1 2 3 4 5 $ git bisect start $ git bisect good e2d314d $ git bisect bad c4c4f2a Bisecting: 3 revisions left to test after this (roughly 2 steps) [98b032f929230bcda22367f90223b270a3199800] se agrego soporte para sesiones con passport.js En este punto corremos nuestra suite de pruebas o las pruebas necesarias. 1 2 3 $ git bisect good Bisecting: 1 revision left to test after this (roughly 1 step) [c811a8b18de58a2aed18b70df6019b03672ef637] cambiado tamao de username en model user Corremos nuevamente la suite de pruebas o las pruebas necesarias. 1 2 $ git bisect good Bisecting: 0 revisions left to test after this (roughly 0 steps) 3 [b53c0dd8432aa928cded2efe2f49f2a3a81adcff] agregado modelo vehicle y userVehicle, agregado listar todos los vehculos del sistema Corremos nuevamente la suite de pruebas o las pruebas necesarias. Encontramos el error, marcamos como malo. 1 2 3 4 5 6 7 8 9 10 11 12 13 $ git bisect bad b53c0dd8432aa928cded2efe2f49f2a3a81adcff is the first bad commit commit b53c0dd8432aa928cded2efe2f49f2a3a81adcff Author: J onathan W Date: Sat Aug 31 17:38:23 2013 -0430
agregado modelo vehicle y userVehicle, agregado listar todos los vehculos del sistema
:100644 100644 983255ad9dd82962c0e577a89ee9fdc2ae77060d 260904ad4a32820ce4103e57e4558d06b2111f40 M app.js :040000 040000 03f3fa7be92462c3c4cbc52d1e023516540fe62f 4bddcd8a960bc0f6944e2c078b9e11d2f58085fd M controllers :100644 100644 6d17e5f8f000caf50ae4e13d93f6c1b0317a6711 49278121379ba65eb8db4652625bd4be34c802ce M dbConfig.js :040000 040000 5b87e3f615ac423234361bb062eaa2afd0011c3a ebba61f808c3d7894bcf02faf31d85c49e227e3b M models Reseteamos el estado del bisect 1 2 3 $ git bisect reset Previous HEAD position was b53c0dd... agregado modelo vehicle y userVehicle, agregado listar todos los vehiculos del sistema Switched to branch 'master' De Aqu en adelante nos toca realizar un checkout de la versin que queremos corregir, o parcharla directamente sobre lo que venimos trabajando.
Conclusin En este ltimo captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para poder debugear con ayuda de git, utilizando las herramientas que nos ofrece. Dichas herramientas ciertamente nos pueden salvar de graves problemas, de igual forma te invitamos a revisar la documentacin de ambas herramientas. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la semana entrante!
Git desde Cero: Reset y Cherry-pick.
Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre como regresar los cambios a un determinado commit utilizando gi t r eset y como de como pasar un commit especfico de una rama a otra utilizandogi t cher r y- pi ck. Los comandos a utilizar esta semana sern los siguientes: git reset * (varios comandos) git cherry-pick * (varios comandos)
Cmo regresar el cdigo fuente a un estado puntual? En git existen varias maneras para regresar a un estado pasado del proyecto. En este curso hablaremos de tres maneras, hard, soft y mixed. Si se utiliza soft (gi t r eset - - sof t ) para retornar a un punto en especfico del proyecto, el mismo lo logra sin disolver el estado actual del proyecto, esto porque no restablece el indice ni la rama de trabajo. Cuando aplicamos este comando todos los archivos pertenecientes a commits posteriores a el quedan en stage listos para cualquier otra operacin que se desee realizar. De forma similar acta el comando mixed (gi t r eset - - mi xed), la nica diferencia con el comando soft es que el los cambios no se quedan en stage. Este es el comando por defecto que usa git cuando no se le asigna una bandera (mixed, soft, hard, etc). De ser necesario retornar completamente a un estado pasado, ignorando todos los commits que se encuentren por encima (ms nuevos) que este, se utiliza gi t r eset - - har d, Este comando particular ignora completamente todos los cambios que hemos realizado ya que restablece el indice y la rama de trabajo al punto donde se encontraban. Estos tres mtodos antes descritos podemos decir que son los ms populares, ya que a la hora de haber realizado algo realmente errado utilizamos el r eset - - har d para retornar al estado anterior descartando todo, y cuando realizamos un mal commit ya sea porque el mensaje no nos gust o agregamos muchos archivos en un solo commit empleamos r eset - - sof t o r eset - - mi xed. Hagamos una prueba para observar lo que describimos anteriormente. 1 2 3 4 5 6 7 8 $ git lg -6 * 926a59c - albertogg, 31 minutes ago : Archivo de prueba para cherry-pick * 08bddd4 - albertogg, 2 weeks ago : Merge commit '4f34bfe8efc8f797bac71dfcd736cb7fa14efc42' as 'node_express_subtree' |\ | * 4f34bfe - albertogg, 2 weeks ago : Squashed 'node_express_subtree/' content fromcommit 0f81501 * 2614422 - albertogg, 3 weeks ago : Primer commit con un submdulo * de13f1b - albertogg, 5 weeks ago : Commit planeado. archivo nuevo y viejo * f2ead5d - albertogg, 6 weeks ago : Referencia en readme. Nos vamos a devolver hasta el commit con el hash 2614422 empleando los tres mtodos. Comenzando por el soft. 1 2 3 4 5 6 7 8 9 10 11 12 13 $ git reset --soft 2614422d18 $ git status #On branch master #Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. # (use "git pull" to update your local branch) # #Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: cherry-test.md # new file: node_express_subtree/.gitignore # new file: node_express_subtree/app.js # new file: node_express_subtree/package.json Podemos observar que toda la informacin que se encontraba en los commits de hash 4f34bfe, 08bddd4 y 926a59c ahora estn en el stage nuevamente. Si llegramos a realizar otro commit en este punto cambiaremos el rbol de nuestro proyecto. Ahora probemos con mixed. 1 2 3 4 5 6 7 8 9 10 11 12 $ git reset --mixed 2614422d18 $ git status #On branch master #Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. # (use "git pull" to update your local branch) # #Untracked files: # (use "git add <file>..." to include in what will be committed) # # cherry-test.md # node_express_subtree/ nothing added to commit but untracked files present (use "git add" to track) Utilizando este comando apreciamos que todo lo que se encotraba en los commits de hash 4f34bfe, 08bddd4 y 926a59c no se descart pero se encuentra en archivos modificados, pero sin estar en el stage. Por ltimo encontramos hard. 1 2 3 4 5 6 7 8 $ git reset --hard 2614422d18 HEAD is now at 2614422 Primer commit con un submdulo $ git status #On branch master #Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. # (use "git pull" to update your local branch) # nothing to commit, working directory clean Aqu podemos observar que tal como lo explicamos anteriormente, se descartan todos los cambios que se encuentran por encima del commit que reseteamos.
Cmo escoger un commit particular de una rama? Muchas veces cuando estamos trabajando bajo el esquema de ramas, arreglamos un bug y seguimos trabajando en una rama que no es la principal (master). Luego queremos que ste arreglo pase a produccin (master), pero no podemos unir toda la rama ya que en este momento no nos interesa todo lo que all se encuentra. Es aqu cuando gi t cher r y- pi ckentra en accin para extraer nicamente el commit que nosotros queremos. Hagamos una prueba del comando: 1 $ git co -b prueba-pick Creamos una rama a partir de master. 1 2 3 4 5 $ touch cherry-test.md $ cat cherry-test.md #Titulo 1
Archivo de prueba. Creamos un archivo y le agregamos contenido. 1 2 3 4 5 $ git add . $ git commit -m"Archivo de prueba para cherry-pick" [prueba-pick 65161e1] Archivo de prueba para cherry-pick 1 file changed, 3 insertions(+) create mode 100644 cherry-test.md Agregamos al stash y realizamos el commit. 1 2 $ git co master Switched to branch 'master' Cambiamos de nuevo a la rama principal (master). 1 2 3 4 $ git cherry-pick 65161e1 [master 926a59c] Archivo de prueba para cherry-pick 1 file changed, 3 insertions(+) create mode 100644 cherry-test.md En este momento utilizando el hash corto 65161e1 que nos arrojo el commit sobre la rama prueba-pick, le decimos al commando cherry-pick que nos extraiga dicho commit y lo agregue a la rama principal. Ahora, podemos comprobar que se encuentra agregado revisando el log. 1 2 3 4 5 6 $ git lg -4 * 926a59c - albertogg, 16 minutes ago : Archivo de prueba para cherry-pick * 08bddd4 - albertogg, 2 weeks ago : Merge commit '4f34bfe8efc8f797bac71dfcd736cb7fa14efc42' as 'node_express_subtree' |\ | * 4f34bfe - albertogg, 2 weeks ago : Squashed 'node_express_subtree/' content fromcommit 0f81501 * 2614422 - albertogg, 3 weeks ago : Primer commit con un submdulo De sta misma manera se puede aplicar el procedimiento para extraer cualquier commit particular hacia cualquier rama que se desee. Lo importante es estar ubicado en la rama a la que se le aplicar el commit a la hora de ejecutar el gi t cher r y- pi ck hash.
Conclusin En este ltimo captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para poder restablecer el proyecto a estados anteriores, ya sea descartando cambios parcial o completamente. Tambin aprendimos a copiar un commit particular de una rama a otra sin necesidad de unir las dos ramas. Ciertamente estas herramientas nos pueden llegar salvar de graves problemas, eso si, como consejo, J AMAS utilicen un reset sobre cambios que ya se encuentren respaldados en un repositorio remoto. Te invitamos a revisar la documentacin de ambas herramientas. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la semana entrante!
Git desde Cero: Git hooks.
Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre algunos de los hooks (ganchos) ms populares que tiene git.
Qu son git hooks? Como se habrn dado cuenta a lo largo de toda esta serie, git tiene una innumerable cantidad de funciones. Los hooks o ganchos son otras de estas tantas funciones extremadamente tiles pero poco utilizadas por muchos de nosotros. Loshooks son un conjunto de acciones que se ejecutan antes o despus de un comando particular de git, es decir, si estamos utilizando un pre-commit hook se ejecutar una accin antes de realizar el commit, si dicha accin realizada antes del commit tiene una respuesta negativa podemos cancelar el commit, arrojar un error y viceversa. Podemos decir que loshooks son una capa extra que nos ayudan a no pasar por alto ciertos detalles.
Tipos de hooks Existen una gran cantidad de hooks disponibles para aplicar, haremos un pequeo resumen de cada uno: applypatch-msg: ayuda a formatear un mensaje para cumplir un estndar deseado del proyecto (si existe). Tambin puede ser utilizado para rechazar un commit despus de inspeccionar el mensaje. Si se encuentra activado el hookcommit-msg, applypatch-msg lo invoca. pre-applypatch: es usado para inspeccionar la rama donde se est trabajando y no permite un commit si el mismo no pasa unas pruebas. Si se encuentra activado pre-commit hook lo invoca. post-appl ypatch: es usado principalmente para notificaciones (escribe un mensaje que se desee por la consola). pre-commit: es invocado por gi t commi t , la utilidad por defecto de este hook es atrapar espacios en blanco al final de cada lnea y abortar el commit si esto llega a ocurrir. Pero se puede agregar cualquier cantidad de pruebas a este hook para asegurar que nuestros commits se encuentran como queremos que estn. Se puede ignorar este hook utilizando la bandera - - no- ver f y al final del commit. prepare-commit-msg: el propsito de este hook es preparar el comentario con un formato por defecto que uno desee que tenga (si existe). Un ejemplo de un comportamiento similar de este hook es cuando generamos un mergede una rama y git nos genera de manera automtica un comentario referente al merge. commit-msg: funciona de la misma manera que applypatch-msg. Podemos ignorarlo haciendo uso de la bandera - - no- ver f y. post-commit: funciona de la misma manera que post-applypatch (imprime un mensaje de notificacin) pero acta una vez que se realiz el commit. pre-rebase: ste gancho es activado por el comando gi t r ebase y puede ser usado para prevenir que una rama sea rebasada. post-checkout: ste gancho se activa cuando se utiliza gi t checkout y puede ser usado para mostrar las diferencias entre las diferentes ramas o setear alguna metadata necesaria. post-merge: es invocado por el comando gi t mer ge y puede ser usado para salvar o restablecer cualquier metadata asociada con una rama de trabajo. pre-recei ve: este gancho es invocado por gi t - r ecei ve- pack en el repositorio remoto, y ocurre cuando se realiza un gi t push. Es el encargado de actualizar las referencias de los objetos y el estado del update (actualizacin). update: de la misma manera que el pre-recei ve se invoca con gi t - r ecei ve- pack y ocurre con el comando gi t - push. Este gancho actualiza las referencias del repositorio remoto y puede ser utilizado para prevenir un gi t push - f (forzado). post-receive: es ejecutado por gi t - r ecei ve- pack y ocurre cuando utilizamos el comando gi t push. A diferencia de los otro dos update y pre-receive acta del lado del servidor. Se puede utilizar este gancho para enviar emails despus de realizar el commit o verificar cualquier informacin de relevancia. post-rewrite: es invocado por los comandos que reescriben commits tales como gi t commi t - - amend o gi t r ebase. Esta informacin fue tomada de kernel.org.
Cmo se usan los hooks? Para poder utilizar algn hook debemos crearlos manualmente. La mayora de los hooks son scripts de shell, aunque podemos utilizar otros lenguajes de scripting si queremos. Absolutamente todos los hooks que necesitemos o creemos deben estar en la carpeta . gi t / hooks/ dentro del repositorio de git de nuestro inters. Por defecto todos los proyectos de git se crean con hooks pero hay que renombrarlos correctamente para que funcionen. Hagamos una pequea demostracin de como se usan: Entremos primero en la carpeta para observar cuales son los ganchos que por defecto que vienen con la creacin del repositorio git. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ cd .git/hooks $ ls -la total 40 drwxr-xr-x 11 albertogg 374 Sep 18 14:27 . drwxr-xr-x 15 albertogg 510 Sep 18 14:27 .. -rwxr-xr-x 1 albertogg 452 J un 26 23:08 applypatch-msg.sample -rwxr-xr-x 1 albertogg 896 J un 26 23:08 commit-msg.sample -rwxr-xr-x 1 albertogg 189 J un 26 23:08 post-update.sample -rwxr-xr-x 1 albertogg 398 J un 26 23:08 pre-applypatch.sample -rwxr-xr-x 1 albertogg 640 Sep 18 14:27 pre-commit -rw-r--r-- 1 albertogg 1348 J un 26 23:08 pre-push.sample -rwxr-xr-x 1 albertogg 4951 J un 26 23:08 pre-rebase.sample -rwxr-xr-x 1 albertogg 1239 J un 26 23:08 prepare-commit-msg.sample -rwxr-xr-x 1 albertogg 3611 J un 26 23:08 update.sample Vamos a utilizar en este caso el pre-commit hook. Debemos renombrar los archivos y quitarles la terminacin .sample para que git los reconozca normalmente. 1 $ mv pre-commit.sample pre-commit Ahora voy a agregar unos espacios en blanco a cualquier lnea dentro de uno de los archivos del repositorio y luego a intentar realizar un commit para que observen lo que sucede. 1 2 3 4 5 6 7 $ nano Archivo2_cambio_de_nombre.txt #agrego unos espacios en blanco al final de la segunda lnea.
#intento realizar un "commit" y esto es lo que ocurre.
$ git commit -am"Prueba de hook" Archivo2_cambio_de_nombre.txt:2: trailing whitespace. +Agregando una segunda linea Se cancel el commit ya que no pas la prueba que realiza el pre-commit hook. A partir de este momento debemos corregir y volver a realizar el commit para observar si hemos solventado todos los problemas existentes, de ser as se realizar el commit normalmente y sin espacios en blanco.
Quin utiliza git hooks? Si han llegado a utilizar servicios como heroku.com muy seguramente se habrn dado cuenta que cada vez que uno realiza un gi t push hacia el repositorio git de heroku, el mismo utiliza varios hooks para detectar que tipo de proyecto es (lenguaje, framework, estructura de carpetas) y de esa manera buscar el buildpack adecuado para nuestro proyecto y as descargarse las libreras adecuadas y construir el proyecto en el servidor. Si alguna vez han subido un proyecto que heroku no reconoce tambin se habrn dado cuenta que el hook no permite la actualizacin y subida de las referencias del proyecto al servidor, cancelando el push.
Conclusin En este ltimo captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para poder entender que son estos hooks y para que nos pueden ayudar en un proyecto. Capaz cuando leas el contenido de este curso no pienses que necesitas hooks, pero en un proyecto donde trabajan muchas personas es muy probaba que podamos prevenir comportamientos no deseados si los usamos. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la semana entrante!
Git desde Cero: Reflog y Fsck
Bienvenidos a un nuevo captulo de Git desde cero en este curso hablaremos sobre como recuperar algn commit que pudo perderse o ser borrado sin querer cuando modificamos el historial o borramos una rama. Para esto utilizaremos gi t r ef l og y como alternativa extrema si por algn motivo no podemos recuperarlo utilizaremos gi t f sck.
Qu es reflog? Ya sabemos que git nos ayuda a hacer un seguimiento de todos las actualizaciones (commits) que realizamos. Este mecanismo para realizar el seguimiento de todas las actualizaciones se llama reflog . la informacin que recoge el reflog viene siendo la misma que la del gi t l og, pero presentada de manera diferente ya que es almacenada dentro de la misma carpeta . gi t / l ogs/ . Como ya dijimos que reflog es el mecanismo para realizar seguimiento de todas las actualizaciones de nuestro proyecto, podemos afirmar en pocas palabras que nos permite visualizar commits perdidos. Puede ocurrir, que en algn momento, uno de los commits que hemos realizado se pierda, borremos una rama, o simplemente cuando reescribimos el historial de cambios borramos algo no deseado. El reflog tiene archivados todos y cada uno de los estados anteriores de una rama y nos permite revertir o ir a cualquier estado anterior del proyecto de ser necesario. Es muy importante tener claro lo que esta herramienta realiza, ya que seguramente la vamos a tener que utilizar en algn momento. Qu se escribe en el reflog? Cada vez que se acuatiza la cabeza HEAD del rbol en que nos encontremos se escribe en el reflog. Es decir, cada vez que cambiamos de rama, realizamos un pull, utilizamos un merge, rebase, o simplemente agregamos un nuevo commit, git escribe dentro del reflog. Cmo se usa? El reflog se utiliza por medio del comando gi t r ef l og tiene ciertas banderas como expire para expirar datos dentro del reflog, pero por lo general solo utilizamos el comando normal. 1 2 3 4 5 6 7 8 9 $ git reflog --relative-date On branch master 926a59c HEAD@{7 days ago}: reset: moving to 926a59cc1c 47fede5 HEAD@{7 days ago}: commit: Prueba del hook 926a59c HEAD@{2 weeks ago}: reset: moving to 926a59c 2614422 HEAD@{2 weeks ago}: reset: moving to 2614422d18 926a59c HEAD@{2 weeks ago}: reset: moving to 926a59c 2614422 HEAD@{2 weeks ago}: reset: moving to 2614422d18 ... Mediante la bandera - - r el at i ve- dat e apreciamos una fecha relativa de cuando se realiz el commit {7 days ago}, esto nos puede ayudar de cierta manera a orientarnos mejor. Si necesitan recuperar algo particular a partir de este momento solo deben utilizar el comando gi t checkout y luego gi t r eset - - har d HashDel Commi t para recuperar o ir a un estado particular. Hagamos esta simple prueba, vamos a regresar al commit del captulo 8 de nmero de13f 1b lo vamos a buscar el por mensaje. 1 2 3 $ git reflog --relative-date | grep -i planeado de13f1b HEAD@{7 weeks ago}: rebase -i (squash): Commit planeado. archivo nuevo y viejo a735092 HEAD@{7 weeks ago}: commit: Commit planeado. archivo nuevo y viejo Luego vamos a crear una rama nueva para no afectar el estado actual de nuestra rama principal. 1 2 $ git co -b prueba-reflog Switched to a new branch 'prueba-reflog' Y por ltimo a ir a ese estado particular. 1 2 $ git reset --hard de13f1b HEAD is now at de13f1b Commit planeado. archivo nuevo y viejo Este procedimiento es exactamente el mismo que se debe realizar cuando se pierde un commit, y de querer podemos utilizar gi t cher r y- pi ck para trasladar el commit a la rama que queramos. Qu es fsck? Fsck es esa herramienta que viene a salvarnos la vida cuando creemos que todo est perdido. En sistemas operativos *nix el comando fsck es referido a File System Check y revisa las inconsistencias del File System para comprobar de que no se haya perdido o daado nada con un apagn repentino o un crash de algn programa. En git el comando revisa la integridad de la base de datos interna de git y busca los objetos que no esten apuntados a otro objeto. Cuando se pierde un commit y no tenemos el reflog ya sea porque los expiramos en alguna oportunidad o simplemente borramos la carpeta . gi t / l ogs el comando gi t f sck puede ayudarnos a identificar estos commits sueltos a los que nosotros nos referimos como perdidos. Cmo se usa? El fsck se utiliza por medio del comando gi t f sck. Una vez aplicado el comando comienza a revisar la base de datos de git. Tambin podemos utilizar las siguientes banderas - - f ul l o - - unr eachabl e. full realiza una revisin de mltiples carpetas para encontrar todos los objetos posibles. Por otra parte unreachable refleja los objetos que existen pero no se pueden encontrar en ningn otro nodo de referencias. Cuando se encuentran aqu es porque probablemente nosotros borramos una rama o tag que los contena. Vamos a probar los dos comandos y observar las distintas salidas. 1 $ git fsck --full 2 3 4 5 6 7 8 Checking object directories: 100% (256/256), done. dangling blob 43882b2283b87566d08b5307ff3c5e8abd095b6f dangling commit 4b7347b7514526606484599ee67d7b7abb601a14 dangling blob b4f0de027a1ccdc432ac652052e78e2f53caa1ff dangling blob bead78cc772d5149ce300480d274d09cf5632368 dangling commit eb15ce2cc60a1829f24442fb14b3e69eb0866580 dangling commit f511b3332361558cff180717868ac208132bb2bf Ahora aplicamos el - - unr eachabl e 1 2 3 4 5 6 7 8 9 10 11 $ git fsck --unreachable Checking object directories: 100% (256/256), done. unreachable commit 32018436db16348f4d84bb8b40aa394a195c6ded unreachable blob 43882b2283b87566d08b5307ff3c5e8abd095b6f unreachable commit 4b7347b7514526606484599ee67d7b7abb601a14 unreachable commit 81d47a325c1a73efe01fb67753ff2c32e0da44c0 unreachable commit a1248a18c03eedac7046bc140d058647aded02ab unreachable blob b4f0de027a1ccdc432ac652052e78e2f53caa1ff unreachable blob bead78cc772d5149ce300480d274d09cf5632368 unreachable commit eb15ce2cc60a1829f24442fb14b3e69eb0866580 unreachable commit f511b3332361558cff180717868ac208132bb2bf Podemos apreciar que entre los dos existen objetos similares y todos tienen un hash por lo cual si aplicamos el mismo procedimiento utilizado con el reflog vamos a poder retornar dicho commit a el historial. Debemos tener en cuenta que estos objetos que se reflejan no duran para siempre; es muy probable que en algn momento sean eliminados por git si el mismo comienza a correr su gc (garbage colector) o corremos el comando gi t gc.
Conclusin En este ltimo captulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para poder recuperar algn commit que hayamos podido borrar. Como sugerencia debes tener en cuenta que si esperas demasiado para recuperar un commit puede ser demasiado tarde si git ya corri su recolector de basura, as que si identificas que algo no est bien corre los comandos reflog y fsck para asegurar de que todo est como debera estar. Te invitamos a revisar la documentacin de ambas herramientas. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Hasta la semana entrante!
Git desde Cero: Instalando git en un servidor
Bienvenidos a un nuevo y ltimo captulo de Git desde cero en este curso hablaremos sobre cmo utilizar git dentro de nuestro servidor privado. Explicaremos los protocolos que existen para realizar esta tarea, crearemos y alojaremos un proyecto en el servidor privado utilizando el protocolo ssh.
Para este curso asumimos que el lector tiene un entendimiento bsico sobre el manejo del terminal en Sistemas Operativos *nix, que sabe y ha generado unas llaves de ssh con anterioridad.
Protocolos Cuando nos referimos a protocolos, hablamos de las reglas y normas que permiten que dos o ms entidades se comuniquen entre ellas para transmitir informacin. Git trabaja con mltiples protocolos de comunicacin. Si hacemos referencia aGithub ya se habrn dado cuenta que al querer clonar un repositorio existen dos (2) protocolos disponibles, HTTP y SSH. Vamos a explicar cules son los pro y contras de ambos, pero para el ejemplo nos basaremos nicamente en ssh. SSH Posiblemente SSH sea el medio de transporte de comunicacin ms utilizado en git. La razn de esto es que en la mayora de los servidores ya se encuentra instalado por defecto. Por otra parte SSH tambin es un protocolo de autenticacin de red, lo que nos ayuda a filtrar los usuarios que tienen permiso de lectura y escritura en nuestro repositorio. Pro Siempre se debe usar para autenticar escritura en un repositorio. Fcil de instalar. Se encuentra instalado en casi todos los sistemas *nix. El acceso mediante el protocolo es seguro. Efectivo a la hora de transferir data. Contra No permite acceso annimo al repositorio. Se debe tener acceso al servidor para poder utilizarlo. HTTP/S Este protocolo es el protocolo del internet, y por ende es muy fcil de poner a trabajar en cualquier servidor. Para poder utilizar el protocolo con un repositorio es cuestin de crear una carpeta con el repositorio git dentro de una de las carpetas alto tipo / var / www/ ht docs/ conocidas por nuestro servidor web (nginx, lighttpd, apache, etc.), activar el post - updat ehook que viene dentro de la carpeta hooks y ya. Pro Muy fcil de instalar. Todo el mundo tiene acceso de descarga. Emplea bajos recursos del servidor. Se pueden tener repositorios de solo lectura. Por lo general este protocolo siempre se encuentra habilitado detrs de los firewalls. Contra Ms lento para clonar y descargar. Se transfiere toda la data de repositorio y no los cambios nicamente. Es un protocolo bruto.
Cmo se instala? Para realizar toda la instalacin vamos a utilizar un Sistema Operativo Ubuntu 13.04 de 64 bits. Aparte debemos tener instalado el paquete git-core y adems debemos tener creado o saber crear el par de llaves de ssh. De ser posible para facilitar un poco la cosa instalar ssh- copy- i d en la mquina personal. Lo primero es tener acceso al servidor. Una vez dentro de servidor vamos a crear un usuario llamado gi t . Luego copiar la llave ssh del usuario, crear un repositorio y por ltimo subirle contenido al mismo. 1 $ sudo adduser git Seguimos las preguntas e indicaciones para crear el usuario, luego nos cambiamos a ese usuario y creamos la carpeta . ssh 1 2 3 $ su git $ cd $ mkdir .ssh Ahora existen dos maneras posibles de copiar las llaves del usuario hacia el servidor. Estando en nuestro computador y si tenemos ssh- copy- i d empleamos el siguiente comando. 1 $ ssh-copy-id git@192.168.1.2 #IP del servidor. Si no tenemos ssh- copy- i d instalado debemos hacerlo manual 1 $ cat .ssh/id_rsa.pub | ssh git@192.168.1.2 "cat >>~/.ssh/authorized_keys" Les recuerdo nuevamente las llaves ssh deben estar creadas previamente. Ahora crearemos un repositorio vaco dentro de la carpeta ~/ mi pr oyect o en el $HOME del usuario. 1 2 3 4 5 $ mkdir ~/miproyecto $ cd ~/miproyecto $ mkdir miproyecto.git $ cd miproyecto.git $ git --bare init La bandera - - bar e genera el repositorio pero completamente vaco. Ahora en la computadora del usuario o nuestra computadora vamos a subir un proyecto que tengamos a el servidor. 1 2 $ cd miproyecto_local $ git init 3 4 5 6 $ git add . $ git commit -m'initial commit' $ git remote add origin git@192.168.1.2:/home/git/miproyecto.git $ git push origin master Listo, a partir de este momento otros pueden clonar y subir cambios al proyecto simplemente agregando su llave de ssh al servidor. Fcil cierto? Ya sabemos que es sencillo, pero es un dolor de cabeza estar agregando las llaves ssh de todos los compaeros del proyecto uno a uno, para esto se crearon herramientas como Gitolite y Gitosis. Este par de herramientas son scripts que ayudan a manejar las llaves ssh dentro del archivo aut hor ed_keys y a su vez un control de acceso. Instalarlas no es tarea fcil es alto tedioso y por la complejidad no lo haremos en este curso, pero queremos que estn al tanto de que estas herramientas existen. Si llegan a instalar acceso mediante HTTP/S para el repositorio tambin pueden utilizar un visualizador web del proyecto, es decir, una pgina web como si fuese Github que les permite ver commits, tags, branches y toda la informacin relevante del proyecto en una pgina web sper sencilla pero muy til. La interfaz se llama GitWeb, para activarla necesitamos un servidor web (valga la redundancia), algo como webr i ck en ruby o cualquier otro servidor web sencillo. Se utiliza ejecutando el siguiente comando: 1 2 $ git instaweb --httpd=webrick $ git instaweb --httpd=webrick --stop #Para detener el daemon Recuerden que para que la interfaz sea pblica la debemos agregar a un VirtualHost en apache o a un Server Block en nginx. La informacin de este artculo fue extrada de el libro Pro Git.
Conclusin En este ltimo captulo y en conjunto con los captulos anteriores hemos adquirido el conocimiento necesario para poder hospedar nuestro propio servidor de git con acceso SSH para nuestro pequeo grupo de trabajo. Te invitamos a revisar la documentacin de Git para que extiendas t conocimiento an ms. Si te surge algn tipo de duda no te detengas y djanos un comentario, que gustosamente lo responderemos. Esperamos que sta serie sobre git les haya gustado bastante! Si requieren algn tema adicional que sea de su agrado y no se nombr durante los 16 captulos de la serie pueden solicitarlo en los comentarios. Saludos!
Git desde Cero: Feature Branch Workflow
Bienvenidos a este captulo Especial de Git desde cero en el que hablaremos de un tema particular que ciertamente me parece muy conveniente discutir. Feature Branch Workflow es uno de los tantos Workflows que existen en Git pero probablemente sea el ms popular ya que es el utilizado en dentro de GitHub, inclusive es posible que conozcan este Workflow como el GitHub flow.
En qu consiste este workflow? Este workflow ayuda a no tener tantos conflictos como en el workflow centralizado al momento de realizar tareas de pull y push ya que est basado en crear ramas que parten de master llamadas feature branch o topic branch donde las mismas no interrumpen el trabajo de los dems. Dichas ramas tienen un nico propsito, es decir, son creadas para agregar una funcionalidad especfica, corregir un error (bug), borrar funcionalidad deprecada etc Siempre sern utilizadas para algo puntual. Una vez que se culmine lo que se est realizando en el feature branch dicha funcionalidad debe ser unida a master nuevamente y as ir repitiendo el ciclo durante el desarrollo. Adems de lo antes mencionado, cuando todo nace y muere en master debemos asumir que dicha rama debe estar libre de errores de compilacin o ejecucucin (obviamente siempre habr algn bug) y debe en todo momento mast er debe poder ser desplegable en produccin sin preocupaciones.
Creando una rama Este punto particular ya lo hemos tocado anteriormente. Lo que haremos aqu ser explicar un poco la nomenclatura de nombres que le ponemos a las ramas. Es importante que el nombre sea muy explicto as nuestro grupo de trabajo podr saber en todo momento en qu estamos trabajando. Debemos crear los feature branches siempre a partir de master y los nombres de dichos branches deben ser algo como:f i x- i ssue- 123, f i x- l ogi n- bug, add- mor e- admi n- f unci onal i t i es, add- t wo- f act or - aut h. Los nombres siempre deben ser lo ms explicito y significativos posibles. 1 2 3 $ git checkout master $ git checkout -b add-two-factor-auth Switched to a new branch 'add-two-factor-auth' Ahora podemos comenzar a agregar commits a nuestra nueva rama.
Agregando cambios En este punto comenzamos a agregar cambios a nuestra rama. El contenido de dichos cambios debe estar relacionados nica y exclusivamente a add- t wo- f act or - aut h. Los cambios que agregaremos son: eliminar, editar, o agregar informacin a archivos los cuales iremos persistiendo en unidades pequeas y congruentes. De esta manera un commit con un ttulo de 50 caracteres o menos bastar para conocer que puede estar contenido en los cambios realizados. Basados en esto, hemos ido agregando commits a nuestra rama y los hemos ido subiendo a una rama con el mismo nombre pero en el repositorio remoto. En este punto nuestra rama local est adelante de la remota por 4 commits y es probable que nos hayamos dado cuenta que podemos mejorar un poco nuestro historial de cambios, ordenandolo mejor o simplemente unir (squashing) ciertos cambios en un slo mensaje. Es importante saber que modificar el historial en cualquier momento es peligroso, ya que si estamos trabajando con varias personas podemos ocasionar graves problemas y por lo tanto si este es el punto es preferible no utilizar los siguientes cambios si no se est seguro de lo que se hace. 1 $ git rebase -i @{u} Esto nos abrir nuestro editor predeterminado y podremos ajustar los mensajes de commit, hacer el squashing o simplemente borrar un cambio del que nos arrepentimos. Cuando hayamos culminado el proceso guardamos, cerramos el editor y subimos los cambios. Les recuerdo que esto solo lo debemos realizar si consideramos que es necesario ajustar el historial. Luego compartimos dichos cambios con el equipo.
Abrir un Pull Request Esta es una de las etapas ms importantes antes de introducir nuestras modificaciones a master. Se preguntarn Por qu? Sencillo, al abrir un pull request compartiremos el historial de cambios pblicamente con las dems personas del equipo de trabajo. Ellos tendrn la oportunidad abiertamente de indagar sobre las modificaciones que hemos realizado, agregar ellos mismos algn cambio o simplemente pedir que corrijamos ciertos detalles. Esta etapa tambin es conocida como etapa de discusin o Code Review. Para bajar cualquier actualizacin desde el repositorio remoto a su mquina deben utilizar el siguiente comando: 1 $ git pull --rebase Si algn miembro del equipo de trabajo desea probar nuestra rama en su mquina puede realizar dos cosas: Probar directamente sobre origin en un detached HEAD Crear un branch local a partir de los cambios que se encuentran en origin Primera opcin: 1 $ git checkout origin/add-two-factor-auth Segunda opcin: 1 $ git checkout -b add-two-factor-auth origin/add-two-factor-auth Algo que debo aclarar es que podemos crear un pull request en cualquier momento del desarrollo, no tiene que ser cuando consideremos que hemos terminado. A veces abrir un pull request temprano puede salvarnos de tener que hacer ms cambios de los previstos, simplemente al mostrar un screenshot pidiendo ayuda a un compaero. Una vez que todos estn de acuerdo y se de la funcionalidad por concluda pasamos a la ltima fase.
Unir y puesta en produccin Hemos verificado que las pruebas pasan, la nueva funcionalidad est como la queremos, ahora procederemos a unir los cambios a master. Para esto debemos debemos pasarnos primero a la mast er y luego unir nuestra rama add- t wo- f act or - aut h. 1 2 3 4 5 $ git checkout master $ git merge --no-ff add-two-factor-auth $ git push $ git branch -d add-two-factor-auth $ git push origin :add-two-factor-auth Unimos la rama utilizando el comando gi t mer ge - - no- f f <f eat ur e br anch> porque queremos explicitamente generar un nuevo commit que referencie el la unin de nuestro feature branch add- t wo- f act or - aut h a mast er . Adems de esto se har notar en nuestro log cuales fueron los commits que se hicieron en dicha rama. 1 2 3 4 5 6 7 $ git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%C(bold blue)<%an>%Creset' --abbrev-commit
* 1166260 - (HEAD, origin/master, master) Merge pull request #82 fromalbertogg/fix-inline-code-mobile (2 days ago)<Alberto Grespan>|\ | * a975c6e - Agregar wrapping de codigo inline. Fixes #81 (2 days ago)<J onathan Wiesel> |/ * 7f61657 - :cactus: Merge branch 'fix-serie-detalle' (3 days ago)<J onathan Wiesel>|\ | * 0a91c25 - Eliminar post_cat del front-matter de las series (3 days ago)<Alberto Grespan>| * 222f3e4 - Cambiar el post_cat por series_header (3 days ago)<Alberto Grespan>| * ef73f19 - Cambiar la lgica para mostrar el detalle de serie (3 days ago)<Alberto Grespan> * | 79ed01e - Agregar how-to de Yeoman (3 days ago)<J onathan Wiesel>|/ * 4f99989 - Se agrego el post java properties (3 days ago)<carlospicca> * ad3e6a8 - Arreglar el post de javascript que estaba roto (4 days ago)<Alberto Grespan> Luego se procede a subir los cambios a master, borrar la rama local y por ltimo borrar la rama remota. En este punto si tenemos hooks con alguna herramienta de Continuos Integration como Travis CI correr la suite de pruebas y luego mediante otro hook se realizar el deploy en produccin.
Conclusin Una ventaja muy grande de trabajar con este workflow es que al ser bastante participativo la mayoa de los miembros del equipo de trabajo conocer con bastante detalle todo el cdigo fuente del proyecto. Hay personas que pueden ver como tediosa la tarea de estar creando, uniendo y eliminando cientos de ramas a lo largo del desarrollo de un proyecto pero la realidad es que todo gira entorno a mast er es decir, al final de cuentas mantenemos slo una rama. Por ltimo si les gusta el Open Source y GitHub esta es la manera para poder contribuir y dejar una huella en este mundo.