Você está na página 1de 59

TALLER DE INTRODUCCIN A GIT

SERGIO GMEZ BACHILLER

Esta pgina se ha dejado vaca a propsito

ndice de contenidos
Captulo 1 Sistemas de control de versiones . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1 Definicin, clasificacin y funcionamiento. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Introduccin a git. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Captulo 2 Aspectos bsicos de Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15


2.1 Instalacin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.2 Configuracin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

Captulo 3 Uso bsico de Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17


3.1 Crear un proyecto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.2 Trabajando con el historial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

Captulo 4 Uso avanzado de Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25


4.1 Deshacer cambios. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2 Moviendo y borrando archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

Captulo 5 Ramas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.1 Administracin de ramas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.2 Fusin de ramas y resolucin de conflictos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.3 Mezclando con la rama master . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

Captulo 6 Administracin de repositorios. . . . . . . . . . . . . . . . . . . . . . . . . 41


6.1 Trabajando con otros repositorios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.2 Repositorios bsicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

Captulo 7 Github . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
7.1 Configuracin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
7.2 Clientes grficos para GitHub. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
7.3 Trabajando con un proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
7.4 Trabajando con Github . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
7.5 ltimo paso, documentacin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

Esta pgina se ha dejado vaca a propsito

Captulo 1

Sistemas de control de versiones


1.1 Definicin, clasificacin y funcionamiento
Se llama control de versiones a la gestin de los diversos cambios que se realizan sobre los
elementos de algn producto o una configuracin del mismo. Una versin, revisin o edicin de un producto, es el estado en el que se encuentra dicho producto en un momento
dado de su desarrollo o modificacin. Aunque un sistema de control de versiones puede
realizarse de forma manual, es muy aconsejable disponer de herramientas que faciliten
esta gestin dando lugar a los llamados sistemas de control de versiones o SVC (del ingls
System Version Control).
Estos sistemas facilitan la administracin de las distintas versiones de cada producto
desarrollado, as como las posibles especializaciones realizadas (por ejemplo, para algn
cliente especfico). Ejemplos de este tipo de herramientas son entre otros: CVS, Subversion, SourceSafe, ClearCase, Darcs, Bazaar , Plastic SCM, Git, Mercurial, Perforce.

1.1.1 Terminologa
Repositorio ("repository")
El repositorio es el lugar en el que se almacenan los datos actualizados e histricos de
cambios.
Revisin ("revision")
Una revisin es una versin determinada de la informacin que se gestiona. Hay
sistemas que identifican las revisiones con un contador (Ej. subversion). Hay otros
sistemas que identifican las revisiones mediante un cdigo de deteccin de
modificaciones (Ej. git usa SHA1).

Captulo 1 Sistemas de control de versiones

Taller de introduccin a Git

Etiqueta ("tag")
Los tags permiten identificar de forma fcil revisiones importantes en el proyecto. Por
ejemplo se suelen usar tags para identificar el contenido de las versiones publicadas
del proyecto.
Rama ("branch")
Un conjunto de archivos puede ser ramificado o bifurcado en un punto en el tiempo
de manera que, a partir de ese momento, dos copias de esos archivos se pueden
desarrollar a velocidades diferentes o en formas diferentes de forma independiente el
uno del otro.
Cambio ("change")
Un cambio (o diff, o delta) representa una modificacin especfica de un documento
bajo el control de versiones. La granularidad de la modificacin que es considerada
como un cambio vara entre los sistemas de control de versiones.
Desplegar ("checkout")
Es crear una copia de trabajo local desde el repositorio. Un usuario puede especificar
una revisin en concreto u obtener la ltima. El trmino 'checkout' tambin se puede
utilizar como un sustantivo para describir la copia de trabajo.
Confirmar ("commit")
Confirmar es escribir o mezclar los cambios realizados en la copia de trabajo del
repositorio. Los trminos 'commit' y 'checkin' tambin se pueden utilizar como
sustantivos para describir la nueva revisin que se crea como resultado de confirmar.
Conflicto ("conflict")
Un conflicto se produce cuando diferentes partes realizan cambios en el mismo
documento, y el sistema es incapaz de conciliar los cambios. Un usuario debe resolver
el conflicto mediante la integracin de los cambios, o mediante la seleccin de un
cambio en favor del otro.
Cabeza ("head")
Tambin a veces se llama tip (punta) y se refiere a la ltima confirmacin, ya sea en el
tronco ('trunk') o en una rama ('branch'). El tronco y cada rama tienen su propia
cabeza, aunque HEAD se utiliza a veces libremente para referirse al tronco.
Tronco ("trunk")
La nica lnea de desarrollo que no es una rama (a veces tambin llamada lnea base,
lnea principal o mster).

Taller de introduccin a Git

Captulo 1 Sistemas de control de versiones

Fusionar, integrar, mezclar ("merge")


Una fusin o integracin es una operacin en la que se aplican dos tipos de cambios en
un archivo o conjunto de archivos. Algunos escenarios de ejemplo son los siguientes:
Un usuario, trabajando en un conjunto de archivos, actualiza o sincroniza su
copia de trabajo con los cambios realizados y confirmados, por otros usuarios, en
el repositorio.
Un usuario intenta confirmar archivos que han sido actualizado por otros
usuarios desde el ltimo despliegue ('checkout'), y el software de control de
versiones integra automticamente los archivos (por lo general, despus de
preguntarle al usuario si se debe proceder con la integracin automtica, y en
algunos casos slo se hace si la fusin puede ser clara y razonablemente resuelta).
Un conjunto de archivos se bifurca, un problema que exista antes de la
ramificacin se trabaja en una nueva rama, y la solucin se combina luego en la
otra rama.
Se crea una rama, el cdigo de los archivos es independiente editado, y la rama
actualizada se incorpora ms tarde en un nico tronco unificado.

1.1.2 Clasificacin
Podemos clasificar los sistemas de control de versiones atendiendo a la arquitectura utilizada para el almacenamiento del cdigo:
Locales
Los cambios son guardados localmente y no se comparten con nadie. Esta arquitectura
es la antecesora de las dos siguientes.

Captulo 1 Sistemas de control de versiones

Taller de introduccin a Git

Figura 1.1 Sistema de control de versiones local

Figura 1.2 Sistema de control de versiones centralizado


Centralizados
Existe un repositorio centralizado de todo el cdigo, del cual es responsable un nico
usuario (o conjunto de ellos). Se facilitan las tareas administrativas a cambio de
8

Taller de introduccin a Git

Captulo 1 Sistemas de control de versiones

reducir flexibilidad, pues todas las decisiones fuertes (como crear una nueva rama)
necesitan la aprobacin del responsable. Algunos ejemplos son CVS y Subversion.
Distribuidos
Cada usuario tiene su propio repositorio. Los distintos repositorios pueden
intercambiar y mezclar revisiones entre ellos. Es frecuente el uso de un repositorio,
que est normalmente disponible, que sirve de punto de sincronizacin de los
distintos repositorios locales. Ejemplos: Git y Mercurial.

Figura 1.3 Sistema de control de versiones distribuido


Ventajas de sistemas distribuidos
No es necesario estar conectado para guardar cambios.
Posibilidad de continuar trabajando si el repositorio remoto no est accesible.
9

Captulo 1 Sistemas de control de versiones

Taller de introduccin a Git

El repositorio central est ms libre de ramas de pruebas.


Se necesitan menos recursos para el repositorio remoto.
Ms flexibles al permitir gestionar cada repositorio personal como se quiera.

1.2 Introduccin a git


Git es un sistema de control de versiones distribuido que se diferencia del resto en el modo
en que modela sus datos. La mayora de los dems sistemas almacenan la informacin como una lista de cambios en los archivos, mientras que Git modela sus datos ms como un
conjunto de instantneas de un mini sistema de archivos.

Figura 1.4 Modelo de datos de los sistemas distribuidos tradicionales

Figura 1.5 Modelo de datos de Git

1.2.1 Los tres estados


Git tiene tres estados principales en los que se pueden encontrar tus archivos: confirmado
(committed), modificado (modified), y preparado (staged). Confirmado significa que los
datos estn almacenados de manera segura en tu base de datos local. Modificado significa
que has modificado el archivo pero todava no lo has confirmado a tu base de datos. Prepa10

Taller de introduccin a Git

Captulo 1 Sistemas de control de versiones

rado significa que has marcado un archivo modificado en su versin actual para que vaya
en tu prxima confirmacin.
Esto nos lleva a las tres secciones principales de un proyecto de Git: el directorio de Git (Git
directory), el directorio de trabajo (working directory), y el rea de preparacin (staging
area).

Figura 1.6 Directorio de trabajo, rea de preparacin, y directorio de Git

1.2.2 Flujos de trabajo distribuidos con git


Hemos visto en qu consiste un entorno de control de versiones distribuido, pero ms all
de la simple definicin, existe ms de una manera de gestionar los repositorios. Estos son
los flujos de trabajo ms comunes en Git.
Flujo de trabajo centralizado
Existe un nico repositorio o punto central que guarda el cdigo y todo el mundo
sincroniza su trabajo con l. Si dos desarrolladores clonan desde el punto central, y
ambos hacen cambios; tan solo el primero de ellos en enviar sus cambios de vuelta lo
podr hacer limpiamente. El segundo desarrollador deber fusionar previamente su
trabajo con el del primero, antes de enviarlo, para evitar el sobreescribir los cambios
del primero
11

Captulo 1 Sistemas de control de versiones

Taller de introduccin a Git

Figura 1.7 Flujo de trabajo centralizado


Flujo de trabajo del Gestor-de-Integraciones
Al permitir multiples repositorios remotos, en Git es posible tener un flujo de trabajo
donde cada desarrollador tenga acceso de escritura a su propio repositorio pblico y
acceso de lectura a los repositorios de todos los dems. Habitualmente, este escenario
suele incluir un repositorio cannico, representante "oficial" del proyecto. Este modelo
se puso muy de moda a raz de la forja GitHub.

Figura 1.8 Flujo de trabajo del Gestor-de-Integraciones


Flujo de trabajo con Dictador y Tenientes
Es una variante del flujo de trabajo con multiples repositorios. Se utiliza generalmente
en proyectos muy grandes, con cientos de colaboradores. Un ejemplo muy conocido es
el del kernel de Linux. Unos gestores de integracin se encargan de partes concretas
del repositorio; y se denominan tenientes. Todos los tenientes rinden cuentas a un
gestor de integracin; conocido como el dictador benevolente. El repositorio del
dictador benevolente es el repositorio de referencia, del que recuperan (pull) todos los
colaboradores.

12

Taller de introduccin a Git

Captulo 1 Sistemas de control de versiones

Figura 1.9 Flujo de trabajo con Dictador y Tenientes

13

Esta pgina se ha dejado vaca a propsito

14

Captulo 2

Aspectos bsicos de Git


2.1 Instalacin
2.1.1 Instalando en Linux
Si quieres instalar Git en Linux a travs de un instalador binario, en general puedes hacerlo a travs de la herramienta bsica de gestin de paquetes que trae tu distribucin. Si
ests en Fedora, puedes usar yum:
$ yum install git-core

O si ests en una distribucin basada en Debian como Ubuntu, prueba con apt-get:
$ apt-get install git

2.1.2 Instalando en Windows


Instalar Git en Windows es muy fcil. El proyecto msysGit tiene uno de los procesos de
instalacin ms sencillos. Simplemente descarga el archivo exe del instalador desde la pgina de GitHub, y ejectalo:
http://msysgit.github.com/
Una vez instalado, tendrs tanto la versin de lnea de comandos (incluido un cliente SSH
que nos ser til ms adelante) como la interfaz grfica de usuario estndar. Se recomienda no modificar las opciones que trae por defecto el instalador.

15

Captulo 2 Aspectos bsicos de Git

Taller de introduccin a Git

2.2 Configuracin
2.2.1 Tu identidad
Lo primero que deberas hacer cuando instalas Git es establecer tu nombre de usuario y
direccin de correo electrnico. Esto es importante porque las confirmaciones de cambios
(commits) en Git usan esta informacin, y es introducida de manera inmutable en los
commits que envas:
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

Tambin se recomienda configurar el siguiente parmetro:


$ git config --global push.default simple

2.2.2 Bash Completion


Bash completion es una utilidad que permite a bash completar rdenes y parmetros. Por
defecto suele venir desactivada en Ubuntu y es necesario modificar el archivo $HOME/.bashrc para poder activarla. Simplemente hay que descomentar las lneas que lo activan,

2.2.3 Tu clave pblica/privada


Muchos servidores Git utilizan la autentificacin a travs de claves pblicas SSH. Y, para
ello, cada usuario del sistema ha de generarse una, si es que no la tiene ya. El proceso para
hacerlo es similar en casi cualquier sistema operativo. Ante todo, asegurarte que no tengas ya una clave. (comprueba que el directorio $HOME/usuario/.ssh no tiene un archivo
id_dsa.pub o id_rsa.pub).
Para crear una nueva clave usamos la siguiente orden:
$ ssh-keygen -t rsa -C "Cuenta Thinstation"

16

Captulo 3

Uso bsico de Git


3.1 Crear un proyecto
3.1.1 Crear un programa "Hola Mundo"
Creamos un directorio donde colocar el cdigo
$ mkdir curso-de-git
$ cd curso-de-git

Creamos un fichero hola.php que muestre Hola Mundo.


<?php
echo "Hola Mundo\n";

3.1.2 Crear el repositorio


Para crear un nuevo repositorio se usa la orden git init
$ git init
Initialized empty Git repository in /home/cc0gobas/git/curso-de-git/.git/

3.1.3 Aadir la aplicacin


Vamos a almacenar el archivo que hemos creado en el repositorio para poder trabajar, despus explicaremos para qu sirve cada orden.
$ git add hola.php
$ git commit -m "Creacin del proyecto"
[master (root-commit) e19f2c1] Creacin del proyecto

17

Captulo 3 Uso bsico de Git

Taller de introduccin a Git

1 file changed, 2 insertions(+)


create mode 100644 hola.php

3.1.4 Comprobar el estado del repositorio


Con la orden git status podemos ver en qu estado se encuentran los archivos de nuestro repositorio.
$ git status
# On branch master
nothing to commit (working directory clean)

Si modificamos el archivo hola.php:


<?php
@print "Hola {$argv[1]}\n";

Y volvemos a comprobar el estado del repositorio:


$ git status
# On branch master
# Changes not staged for commit:
#
(use "git add <file>..." to update what will be committed)
#
(use "git checkout -- <file>..." to discard changes in working
directory)
#
#
modified:
hola.php
#
no changes added to commit (use "git add" and/or "git commit -a")

3.1.5 Aadir cambios


Con la orden git add indicamos a git que prepare los cambios para que sean almacenados.
$
$
#
#
#
#
#
#

git add hola.php


git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified:

hola.php

3.1.6 Confirmar los cambios


Con la orden git commit confirmamos los cambios definitivamente, lo que hace que se
guarden permanentemente en nuestro repositorio.
18

Taller de introduccin a Git

Captulo 3 Uso bsico de Git

$ git commit -m "Parametrizacin del programa"


[master efc252e] Parametrizacin del programa
1 file changed, 1 insertion(+), 1 deletion(-)
$ git status
# On branch master
nothing to commit (working directory clean)

3.1.7 Funcionamiento de git: se guardan cambios, no ficheros.


Modificamos nuestra aplicacin para que soporte un parmetro por defecto y aadimos
los cambios.
<?php
$nombre = isset($argv[1]) ? $argv[1] : "Mundo";
@print "Hola, {$nombre}\n";
git add hola.php

Volvemos a modificar el programa para indicar con un comentario lo que hemos hecho.
<?php
// El nombre por defecto es Mundo
$nombre = isset($argv[1]) ? $argv[1] : "Mundo";
@print "Hola, {$nombre}\n";

Y vemos el estado en el que est el repositorio


$ git status
# On branch master
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
#
modified:
hola.php
#
# 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:
hola.php
#

Almacenamos los cambios por separado:


$ git commit -m "Se aade un parmetro por defecto"
[master 3283e0d] Se aade un parmetro por defecto
19

Captulo 3 Uso bsico de Git

Taller de introduccin a Git

1 file changed, 2 insertions(+), 1 deletion(-)


$ git status
# On branch master
# Changes not staged for commit:
#
(use "git add <file>..." to update what will be committed)
#
(use "git checkout -- <file>..." to discard changes in working
directory)
#
#
modified:
hola.php
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git add .
$ git status
# On branch master
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
#
modified:
hola.php
#
$ git commit -m "Se aade un comentario al cambio del valor por defecto"
[master fd4da94] Se aade un comentario al cambio del valor por defecto
1 file changed, 1 insertion(+)

El valor "." despues de git add indica que se aadan todos los archivos que hayan cambiado.

3.2 Trabajando con el historial


3.2.1 Observando los cambios
Con la orden git log podemos ver todos los cambios que hemos hecho:
$ git log
commit fd4da946326fbe8b24e89282ad25a71721bf40f6
Author: Sergio Gmez <sergio@uco.es>
Date:
Sun Jun 16 12:51:01 2013 +0200
Se aade un comentario al cambio del valor por defecto
commit 3283e0d306c8d42d55ffcb64e456f10510df8177
Author: Sergio Gmez <sergio@uco.es>
Date:
Sun Jun 16 12:50:00 2013 +0200
Se aade un parmetro por defecto

20

Taller de introduccin a Git

Captulo 3 Uso bsico de Git

commit efc252e11939351505a426a6e1aa5bb7dc1dd7c0
Author: Sergio Gmez <sergio@uco.es>
Date:
Sun Jun 16 12:13:26 2013 +0200
Parametrizacin del programa
commit e19f2c1701069d9d1159e9ee21acaa1bbc47d264
Author: Sergio Gmez <sergio@uco.es>
Date:
Sun Jun 16 11:55:23 2013 +0200
Creacin del proyecto

Tambin es posible ver versiones abreviadas o limitadas, dependiendo de los parmetros:


$ git log --oneline
fd4da94 Se aade un comentario al cambio del valor por defecto
3283e0d Se aade un parmetro por defecto
efc252e Parametrizacin del programa
e19f2c1 Creacin del proyecto
git log --oneline --max-count=2
git log --oneline --since='5 minutes ago'
git log --oneline --until='5 minutes ago'
git log --oneline --author=sergio
git log --oneline --all

Una versin muy til de git log es la siguiente, pues nos permite ver en que lugares est
master y HEAD, entre otras cosas:
$ git log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (HEAD, master) [Sergio Gmez]
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto [Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]

3.2.2 Crear alias


Como estas rdenes son demasiado largas, Git nos permite crear alias para crear nuevas rdenes parametrizadas. Para ello editaremos un archivo llamado .gitconfig que est en
nuestro $HOME y le aadiremos estas lneas al final:
[alias]
hist = log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short

21

Captulo 3 Uso bsico de Git

Taller de introduccin a Git

3.2.3 Recuperando versiones anteriores


Cada cambio es etiquetado por un hash, para poder regresar a ese momento del estado del
proyecto se usa la orden git checkout.
$ git checkout e19f2c1
Note: checking out 'e19f2c1'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again.
Example:
git checkout -b new_branch_name
HEAD is now at e19f2c1... Creacin del proyecto
$ cat hola.php
<?php
echo "Hello, World\n";

El aviso que nos sale nos indica que estamos en un estado donde no trabajamos en ninguna
rama concreta. Eso significa que los cambios que hagamos podran "perderse" porque si no
son guardados en una nueva rama, en principio no podramos volver a recuperarlos. Hay
que pensar que Git es como un rbol donde un nodo tiene informacin de su nodo padre,
no de sus nodos hijos, con lo que siempre necesitaramos informacin de dnde se encuentran los nodos finales o de otra manera no podramos acceder a ellos.

3.2.4 Volver a la ltima versin de la rama master.


Usamos git checkout indicando el nombre de la rama:
$ git checkout master
Previous HEAD position was e19f2c1... Creacin del proyecto

3.2.5 Etiquetando versiones


Para poder recuperar versiones concretas en la historia del repositorio, podemos etiquetarlas, lo cual es ms facil que usar un hash. Para eso usaremos la orden git tag.
$ git tag v1

22

Taller de introduccin a Git

Captulo 3 Uso bsico de Git

Ahora vamos a etiquetar la versin inmediatamente anterior como v1-beta. Para ello podemos usar los modificadores ^ o ~ que nos llevarn a un ancestro determinado. Las siguientes dos rdenes son equivalentes:
$ git checkout v1^
$ git checkout v1~1
$ git tag v1-beta

Si ejecutamos la orden sin parmetros nos mostrar todas las etiquetas existentes.
$ git tag
v1
v1-beta

Y para verlas en el historial:


$ git hist master --all
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (tag: v1, master) [Sergio Gmez]
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (HEAD, tag:
v1-beta) [Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]

3.2.6 Borrar etiquetas


Para borrar etiquetas:
git tag -d nombre_etiqueta

3.2.7 Visualizar cambios


Para ver los cambios que se han realizado en el cdigo usamos la orden git diff. La orden
sin especificar nada ms, mostrar los cambios que no han sido aadidos an, es decir, todos los cambios que se han hecho antes de usar la orden git add. Despus se puede indicar
un parmetro y dar los cambios entre la versin indicada y el estado actual. O para comparar dos versiones entre s, se indica la ms antigua y la ms nueva. Ejemplo:
$ git diff v1-beta v1
diff --git a/hola.php b/hola.php
index a31e01f..25a35c0 100644
--- a/hola.php
+++ b/hola.php
@@ -1,3 +1,4 @@
<?php
+// El nombre por defecto es Mundo
23

Captulo 3 Uso bsico de Git

$nombre = isset($argv[1]) ? $argv[1] : "Mundo";


@print "Hola, {$nombre}\n";

24

Taller de introduccin a Git

Captulo 4

Uso avanzado de Git


4.1 Deshacer cambios
4.1.1 Deshaciendo cambios antes de la fase de staging.
Volvemos a la rama mster y vamos a modificar el comentario que pusimos:
$ git checkout master
Previous HEAD position was 3283e0d... Se aade un parmetro por defecto
Switched to branch 'master'
$ # Modificamos hola.php
$ cat hola.php
<?php
// Este comentario est mal y hay que borrarlo
$nombre = isset($argv[1]) ? $argv[1] : "Mundo";
@print "Hola, {$nombre}\n";
$ git status
# On branch master
# Changes not staged for commit:
#
(use "git add <file>..." to update what will be committed)
#
(use "git checkout -- <file>..." to discard changes in working
directory)
#
#
modified:
hola.php
#
no changes added to commit (use "git add" and/or "git commit -a")

El mismo Git nos indica que debemos hacer para aadir los cambios o para deshacerlos:

25

Captulo 4 Uso avanzado de Git

Taller de introduccin a Git

$ git checkout hola.php


$ git status
# On branch master
nothing to commit, working directory clean
$ cat hola.php
<?php
// El nombre por defecto es Mundo
$nombre = isset($argv[1]) ? $argv[1] : "Mundo";
@print "Hola, {$nombre}\n";

4.1.2 Deshaciendo cambios antes del commit


Vamos a hacer lo mismo que la vez anterior, pero esta vez s aadiremos el cambio al stag
(sin hacer commit).
$ # Modificamos hola.php
$ cat hola.php
<?php
// Este comentario est mal y hay que borrarlo
$nombre = isset($argv[1]) ? $argv[1] : "Mundo";
@print "Hola, {$nombre}\n";
$ git add hola.php
$ git status
# On branch master
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
#
modified:
hola.php
#

De nuevo, Git nos indica qu debemos hacer para deshacer el cambio almacenado en el
stag:
$ git reset HEAD hola.php
Unstaged changes after reset:
M
hola.php
$ git status
# On branch master
# Changes not staged for commit:
#
(use "git add <file>..." to update what will be committed)
#
(use "git checkout -- <file>..." to discard changes in working
directory)
#
#
modified:
hola.php
#
26

Taller de introduccin a Git

Captulo 4 Uso avanzado de Git

no changes added to commit (use "git add" and/or "git commit -a")
$ git checkout hola.php

Y ya tenemos nuestro repositorio limpio otra vez.

4.1.3 Deshaciendo commits no deseados.


Si a pesar de todo hemos hecho un commit y nos hemos equivocado, podemos deshacerlo
con la orden git revert. Modificamos otra vez el archivo como antes pero ahora s hacemos commit:
$ # Modificamos hola.php
$ cat hola.php
<?php
// Este comentario est mal y hay que borrarlo
$nombre = isset($argv[1]) ? $argv[1] : "Mundo";
@print "Hola, {$nombre}\n";
$ git add hola.php
$ git commit -m "Ups... este commit est mal."
master 5a5d067] Ups... este commit est mal
1 file changed, 1 insertion(+), 1 deletion(-)

4.1.4 Crear un "reverting commit"


$ git revert HEAD --no-edit
[master 817407b] Revert "Ups... este commit est mal"
1 file changed, 1 insertion(+), 1 deletion(-)
$ git hist
* 817407b 2013-06-16 | Revert "Ups... este commit est mal" (HEAD,
master) [Sergio Gmez]
* 5a5d067 2013-06-16 | Ups... este commit est mal [Sergio Gmez]
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (tag: v1) [Sergio Gmez]
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (tag: v1-beta)
[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]

4.1.5 Borrar commits de una rama


El anterior apartado revierte un commit, pero deja huella en el historial de cambios. Para
hacer que no aparezca hay que usar la orden git reset.
$ git reset --hard v1
HEAD is now at fd4da94 Se aade un comentario al cambio del valor por
defecto
$ git hist
27

Captulo 4 Uso avanzado de Git

Taller de introduccin a Git

* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por


defecto (HEAD, tag: v1, master) [Sergio Gme
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (tag: v1-beta)
[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]

El resto de cambios no se han borrado (an), simplemente no estn accesibles porque git
no sabe como referenciarlos. Si sabemos su hash podemos acceder an a ellos. Pasado un
tiempo, eventualmente Git tiene un recolector de basura que los borrar. Se puede evitar
etiquetando el estado final.
De todas maneras, reset es una operacin delicada, que debe evitarse, sobre todo cuando se
trabaja en repositorios compartidos.

4.1.6 Modificar un commit


Esto se usa cuando hemos olvidado aadir un cambio a un commit que acabamos de realizar.
$ cat hola.php
<?php
// Autor: Sergio Gmez
// El nombre por defecto es Mundo
$nombre = isset($argv[1]) ? $argv[1] : "Mundo";
@print "Hola, {$nombre}\n";
$ git commit -a -m "Aadido el autor del programa"
[master cf405c1] Aadido el autor del programa
1 file changed, 1 insertion(+)

El parmetro -a hace un git add antes de hacer commit de todos los archivos modificados o borrados (de los nuevos no), con lo que nos ahorramos un paso. Ahora nos percatamos que se nos ha olvidado poner el correo electrnico.
$ cat hola.php
<?php
// Autor: Sergio Gmez <sergio@uco.es>
// El nombre por defecto es Mundo
$nombre = isset($argv[1]) ? $argv[1] : "Mundo";
@print "Hola, {$nombre}\n";
$ git add hola.php
$ git commit --amend -m "Aadido el autor del programa y su email"
[master 96a39df] Aadido el autor del programa y su email
1 file changed, 1 insertion(+)
$ git hist
28

Taller de introduccin a Git

Captulo 4 Uso avanzado de Git

* 96a39df 2013-06-16 | Aadido el autor del programa y su email (HEAD,


master) [Sergio Gmez]
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (tag: v1) [Sergio Gmez]
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (tag: v1-beta)
[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]

4.2 Moviendo y borrando archivos


4.2.1 Mover un archivo a otro directorio con git
Para mover archivos usaremos la orden git mv:
$
$
$
#
#
#
#
#
#

mkdir lib
git mv hola.php lib
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed:

hola.php -> lib/hola.php

4.2.2 Mover y borrar archivos.


Otra forma de hacer lo mismo:
$
$
$
$

mkdir lib
mv hola.php lib
git add lib/hola.php
git rm hola.php

Y ya podemos guardar los cambios:


$ git commit -m "Movido hola.php a lib."
[master 8c2a509] Movido hola.php a lib.
1 file changed, 0 insertions(+), 0 deletions(-)
rename hola.php => lib/hola.php (100%)

29

Esta pgina se ha dejado vaca a propsito

30

Captulo 5

Ramas
5.1 Administracin de ramas
5.1.1 Crear una nueva rama
Cuando vamos a trabajar en una nueva funcionalidad, es conveniente hacerlo en una nueva rama, para no modificar la rama principal y dejarla inestable. Aunque la orden para
manejar ramas es git branch podemos usar tambin git checkout.
$ git branch hola
$ git checkout hola
Switched to branch 'hola'

O de forma ms rpida:
$ git checkout -b hola
Switched to a new branch 'hola'

5.1.2 Modificaciones en la rama secundaria


Aadimos un nuevo archivo en el directorio lib llamado HolaMundo.php:
<?php
class HolaMundo
{
private $nombre;
function __construct($nombre)
{
31

Captulo 5 Ramas

Taller de introduccin a Git

$this->nombre = $nombre;
}
function __toString()
{
return sprintf ("Hola, %s.\n", $this->nombre);
}
}

Y modificamos hola.php:
<?php
// Autor: Sergio Gmez <sergio@uco.es>
// El nombre por defecto es Mundo
require('HolaMundo.php');
$nombre = isset($argv[1]) ? $argv[1] : "Mundo";
print new HolaMundo($nombre);

Podramos confirmar los cambios todos de golpe, pero lo haremos de uno en uno, con su
comentario.
$ git add lib/HolaMundo.php
$ git commit -m "Aadida la clase HolaMundo"
[hola 6932156] Aadida la clase HolaMundo
1 file changed, 16 insertions(+)
create mode 100644 lib/HolaMundo.php
$ git add lib/hola.php
$ git commit -m "hola usa la clase HolaMundo"
[hola 9862f33] hola usa la clase HolaMundo
1 file changed, 3 insertions(+), 1 deletion(-)

Y ahora con la orden git checkout podemos movernos entre ramas:


$ git checkout master
Switched to branch 'master'
$ git checkout hola
Switched to branch 'hola'

5.1.3 Modificaciones en la rama master


Podemos volver y aadir un nuevo archivo a la rama principal:
$ git checkout master
Switched to branch 'master'
$ cat README.md
32

Taller de introduccin a Git

Captulo 5 Ramas

# Curso de GIT
Este proyecto contiene el curso de introduccin a GIT
$ git add README.md
$ git commit -m "Aadido README.md"
[master c3e65d0] Aadido README.md
1 file changed, 3 insertions(+)
create mode 100644 README.md
$ git hist --all
* c3e65d0 2013-06-16 | Aadido README.md (HEAD, master) [Sergio Gmez]
| * 9862f33 2013-06-16 | hola usa la clase HolaMundo (hola) [Sergio
Gmez]
| * 6932156 2013-06-16 | Aadida la clase HolaMundo [Sergio Gmez]
|/
* 81c6e93 2013-06-16 | Movido hola.php a lib [Sergio Gmez]
* 96a39df 2013-06-16 | Aadido el autor del programa y su email [Sergio
Gmez]
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (tag: v1) [Sergio Gmez]
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (tag: v1-beta)
[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]

Y vemos como git hist muestra la bifurcacin en nuestro cdigo.

5.2 Fusin de ramas y resolucin de conflictos


5.2.1 Mezclar ramas
Podemos incorporar los cambios de una rama a otra con la orden git merge
$ git checkout hola
Switched to branch 'hola'
$ git merge master
Merge made by the 'recursive' strategy.
README.md | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 README.md
$ git hist --all
*
9c6ac06 2013-06-16 | Merge commit 'c3e65d0' into hola (HEAD, hola)
[Sergio Gmez]
|\
* | 9862f33 2013-06-16 | hola usa la clase HolaMundo [Sergio Gmez]
* | 6932156 2013-06-16 | Aadida la clase HolaMundo [Sergio Gmez]
33

Captulo 5 Ramas

Taller de introduccin a Git

| |
| * c3e65d0 2013-06-16 | Aadido README.md [Sergio Gmez]
|/
* 81c6e93 2013-06-16 | Movido hola.php a lib [Sergio Gmez]
* 96a39df 2013-06-16 | Aadido el autor del programa y su email [Sergio
Gmez]
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (tag: v1) [Sergio Gmez]
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (tag: v1-beta)
[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]

De esa forma se puede trabajar en una rama secundaria incorporando los cambios de la rama principal o de otra rama.

5.2.2 Resolver conflictos


Un conflicto es cuando se produce una fusin que Git no es capaz de resolver. Vamos a modificar la rama master para crear uno con la rama hola.
$ git checkout master
M
lib/hola.php
Already on 'master'
$ cat lib/hola.php
<?php
// Autor: Sergio Gmez <sergio@uco.es>
print "Introduce tu nombre:";
$nombre = trim(fgets(STDIN));
@print "Hola, {$nombre}\n";
$ git add lib/hola.php
$ git commit -m "Programa interactivo"
[master 9c85275] Programa interactivo
1 file changed, 2 insertions(+), 2 deletions(-)
$ git hist --all
*
9c6ac06 2013-06-16 | Merge commit 'c3e65d0' into hola (hola) [Sergio
Gmez]
|\
* | 9862f33 2013-06-16 | hola usa la clase HolaMundo [Sergio Gmez]
* | 6932156 2013-06-16 | Aadida la clase HolaMundo [Sergio Gmez]
| | * 9c85275 2013-06-16 | Programa interactivo (HEAD, master) [Sergio
Gmez]
| |/
| * c3e65d0 2013-06-16 | Aadido README.md [Sergio Gmez]
|/
34

Taller de introduccin a Git

Captulo 5 Ramas

* 81c6e93 2013-06-16 | Movido hola.php a lib [Sergio Gmez]


* 96a39df 2013-06-16 | Aadido el autor del programa y su email [Sergio
Gmez]
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (tag: v1) [Sergio Gmez]
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (tag: v1-beta)
[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]

Volvemos a la rama hola y fusionamos:


$ git checkout hola
Switched to branch 'hola'
$ git merge master
Auto-merging lib/hola.php
CONFLICT (content): Merge conflict in lib/hola.php
Automatic merge failed; fix conflicts and then commit the result.
$ cat lib/hola.php
<?php
// Autor: Sergio Gmez <sergio@uco.es>
<<<<<<< HEAD
// El nombre por defecto es Mundo
require('HolaMundo.php');
$nombre = isset($argv[1]) ? $argv[1] : "Mundo";
print new HolaMundo($nombre);
=======
print "Introduce tu nombre:";
$nombre = trim(fgets(STDIN));
@print "Hola, {$nombre}\n";
>>>>>>> master

La primera parte marca el cdigo que estaba en la rama donde trabajbamos (HEAD) y la
parte final el cdigo de donde fusionbamos. Resolvemos el conflicto:
$ cat lib/hola.php
<?php
// Autor: Sergio Gmez <sergio@uco.es>
require('HolaMundo.php');
print "Introduce tu nombre:";
$nombre = trim(fgets(STDIN));
print new HolaMundo($nombre);
$ git add lib/hola.php
35

Captulo 5 Ramas

Taller de introduccin a Git

$ git commit -m "Solucionado el conflicto al fusionar con la rama master"


[hola a36af04] Solucionado el conflicto al fusionar con la rama master

5.2.3 Rebasing vs Merging


Rebasing es otra tcnica para fusionar distinta a merge y usa la orden git rebase. Vamos
a dejar nuestro proyecto como estaba antes del fusionado:
$ git checkout hola
Switched to branch 'hola'
$ git hist
*
a36af04 2013-06-16 | Solucionado el conflicto al fusionar con la
rama master (HEAD, hola) [Sergio Gmez]
|\
| * 9c85275 2013-06-16 | Programa interactivo (master) [Sergio Gmez]
* |
9c6ac06 2013-06-16 | Merge commit 'c3e65d0' into hola [Sergio
Gmez]
|\ \
| |/
| * c3e65d0 2013-06-16 | Aadido README.md [Sergio Gmez]
* | 9862f33 2013-06-16 | hola usa la clase HolaMundo [Sergio Gmez]
* | 6932156 2013-06-16 | Aadida la clase HolaMundo [Sergio Gmez]
|/
* 81c6e93 2013-06-16 | Movido hola.php a lib [Sergio Gmez]
* 96a39df 2013-06-16 | Aadido el autor del programa y su email [Sergio
Gmez]
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (tag: v1) [Sergio Gmez]
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (tag: v1-beta)
[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]
$ git reset --hard 9862f33
HEAD is now at 9862f33 hola usa la clase HolaMundo
$ git checkout master
Switched to branch 'master'
$ git hist
* 9c85275 2013-06-16 | Programa interactivo (HEAD, master) [Sergio Gmez]
* c3e65d0 2013-06-16 | Aadido README.md [Sergio Gmez]
* 81c6e93 2013-06-16 | Movido hola.php a lib [Sergio Gmez]
* 96a39df 2013-06-16 | Aadido el autor del programa y su email [Sergio
Gmez]
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (tag: v1) [Sergio Gmez]
36

Taller de introduccin a Git

Captulo 5 Ramas

* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (tag: v1-beta)


[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]
$ git reset --hard c3e65d0
HEAD is now at c3e65d0 Aadido README.md

Y nuestro estado ser:


$ git hist --all
* 9862f33 2013-06-16 | hola usa la clase HolaMundo (hola) [Sergio Gmez]
* 6932156 2013-06-16 | Aadida la clase HolaMundo [Sergio Gmez]
| * c3e65d0 2013-06-16 | Aadido README.md (HEAD, master) [Sergio Gmez]
|/
* 81c6e93 2013-06-16 | Movido hola.php a lib [Sergio Gmez]
* 96a39df 2013-06-16 | Aadido el autor del programa y su email [Sergio
Gmez]
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (tag: v1) [Sergio Gmez]
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (tag: v1-beta)
[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]
$ git checkout hola
Switched to branch 'hola'
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: Aadida la clase HolaMundo
Applying: hola usa la clase HolaMundo
$ git hist --all
* 491f1d2 2013-06-16 | hola usa la clase HolaMundo (HEAD, hola) [Sergio
Gmez]
* c13d75c 2013-06-16 | Aadida la clase HolaMundo [Sergio Gmez]
* c3e65d0 2013-06-16 | Aadido README.md (master) [Sergio Gmez]
* 81c6e93 2013-06-16 | Movido hola.php a lib [Sergio Gmez]
* 96a39df 2013-06-16 | Aadido el autor del programa y su email [Sergio
Gmez]
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (tag: v1) [Sergio Gmez]
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (tag: v1-beta)
[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]

37

Captulo 5 Ramas

Taller de introduccin a Git

Lo que hace rebase es volver a aplicar todos los cambios a la rama mster, desde su nodo
ms reciente. Eso significa que se modifica el orden o la historia de creacin de los cambios. Por eso rebase no debe usarse si el orden es importante o si la rama es compartida.

5.3 Mezclando con la rama master


Ya hemos terminado de implementar los cambios en nuestra rama secundaria y es hora
de llevar los cambios a la rama principal. Usamos git merge para hacer una fusin normal:
$ git checkout master
Switched to branch 'master'
$ git merge hola
Updating c3e65d0..491f1d2
Fast-forward
lib/HolaMundo.php | 16 ++++++++++++++++
lib/hola.php
| 4 +++2 files changed, 19 insertions(+), 1 deletion(-)
create mode 100644 lib/HolaMundo.php

Vemos que indica que el tipo de fusin es fast-forward. Este tipo de fusin tiene el problema que no deja rastro de la fusin, por eso suele ser recomendable usar el parmetro --no-ff
para que quede constancia siempre de que se ha fusionado una rama con otra.

38

Taller de introduccin a Git

Captulo 5 Ramas

Figura 5.1 Diferencias entre tipos de fusin

39

Esta pgina se ha dejado vaca a propsito

40

Captulo 6

Administracin de repositorios
6.1 Trabajando con otros repositorios
6.1.1 Clonar un repositorio
Clonar es la accin de copiar el contenido de un repositorio para generar otra copia de trabajo. Se usa la orden git clone. Vamos a clonar nuestro respositorio de ejemplo en otro
directorio:
$ cd ..
$ git clone curso-git curso-git-clonado
Cloning into 'curso-git-clonado'...
done.

Y comprobamos que el nuevo repositorio es igual que el que tenamos:


$ cd curso-git-clonado/
$ ls
README.md lib
$ git hist --all
* 491f1d2 2013-06-16 | hola usa la clase HolaMundo (HEAD, origin/master,
origin/hola, origin/HEAD, master) [Sergio Gmez]
* c13d75c 2013-06-16 | Aadida la clase HolaMundo [Sergio Gmez]
* c3e65d0 2013-06-16 | Aadido README.md [Sergio Gmez]
* 81c6e93 2013-06-16 | Movido hola.php a lib [Sergio Gmez]
* 96a39df 2013-06-16 | Aadido el autor del programa y su email [Sergio
Gmez]
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (v1) [Sergio Gmez]
41

Captulo 6 Administracin de repositorios

Taller de introduccin a Git

* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (v1-beta)


[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]

Bueno, no exactamente igual. Hay unas nuevas ramas llamadas origin/* que indican que
estn vinculadas con un repositorio externo. Podemos verlas con la orden git remote:
$ git remote show origin
* remote origin
Fetch URL: /home/cc0gobas/git/curso-git
Push URL: /home/cc0gobas/git/curso-git
HEAD branch (remote HEAD is ambiguous, may be one of the following):
hola
master
Remote branches:
hola
tracked
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)

6.1.2 Ramas remotas


Para poder ver las ramas remotas debemos usar el parmetro -a en la orden git branch:
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/hola
remotes/origin/master

6.1.3 Cmo actualizar el repositorio copia


Cuando se trabaja en grupo, es normal que el repositorio remoto cambie. Vamos a modificarlo y ver como podemos actualizar el repositorio copia:
$
$
$
#

cd ..
cd curso-git
cat README.md
Curso de GIT

Este proyecto contiene el curso de introduccin a GIT.


Ahora es un repositorio compartido.
$ git add README.md
42

Taller de introduccin a Git

Captulo 6 Administracin de repositorios

$ git commit -m "Cambiado el README.md"


[master 3d2db03] Cambiado el README.md
1 file changed, 2 insertions(+), 1 deletion(-)

Al proceso de traer una actualizacin se le llama pull y de hecho hay una orden llamada
git pull que realiza ese cometido. Vamos a ver, de todas maneras, el camino largo usando git fetch. Esta ltima rden lo que hace es actualizar la rama origin/master y origin/
HEAD de nuestro repositorio copia, pero no actualiza las ramas locales. Es decir, no fusiona las ramas remotas con las locales:
$ cd ../curso-git-clonado/
$ git fetch
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
De /home/cc0gobas/git/curso-git
491f1d2..3d2db03 master
-> origin/master
$ git hist --all
* 3d2db03 2013-06-17 | Cambiado el README.md (origin/master,
origin/HEAD) [Sergio Gmez]
* 491f1d2 2013-06-16 | hola usa la clase HolaMundo (HEAD, origin/hola,
master) [Sergio Gmez]
* c13d75c 2013-06-16 | Aadida la clase HolaMundo [Sergio Gmez]
* c3e65d0 2013-06-16 | Aadido README.md [Sergio Gmez]
* 81c6e93 2013-06-16 | Movido hola.php a lib [Sergio Gmez]
* 96a39df 2013-06-16 | Aadido el autor del programa y su email [Sergio
Gmez]
* fd4da94 2013-06-16 | Se aade un comentario al cambio del valor por
defecto (v1) [Sergio Gmez]
* 3283e0d 2013-06-16 | Se aade un parmetro por defecto (v1-beta)
[Sergio Gmez]
* efc252e 2013-06-16 | Parametrizacin del programa [Sergio Gmez]
* e19f2c1 2013-06-16 | Creacin del proyecto [Sergio Gmez]

Podemos comprobar que el archivore README.md no ha cambiado. Para hacer los cambios
tendremos que fusionar las ramas como hemos visto:
$ git merge origin/master
Updating 491f1d2..3d2db03
Fast-forward
README.md | 3 ++1 file changed, 2 insertions(+), 1 deletion(-)

43

Captulo 6 Administracin de repositorios

Taller de introduccin a Git

Los dos pasos anteriores se suelen reducir en uno solo:


$ git pull
Updating 491f1d2..3d2db03
Fast-forward
README.md | 3 ++1 file changed, 2 insertions(+), 1 deletion(-)

Por qu existe entonces git fetch? Pues porque normalmente los integradores prefieren ver los cambios que se van a realizar antes de hacerlos. Se puede hacer un checkout a la
rama remota para ver lo que ha cambiado.

6.1.4 Aadir una rama de seguimiento


Cuando se clona un repositorio, en el repositorio local solo se crea una rama mster, pero
las ramas secundarias que ya existan en el repositorio remoto no se crean. Solo aparecen
a travs de las ramas remotas origin/*. Para crear ramas locales que hagan seguimiento de
esas ramas remotas usaremos git branch:
$ git branch --track hola origin/hola
Branch hola set up to track remote branch hola from origin.
$ git branch -a
hola
* master
remotes/origin/HEAD -> origin/master
remotes/origin/hola
remotes/origin/master
$ git hist --max-count=2
* 3d2db03 2013-06-17 | Cambiado el README.md (HEAD, origin/master,
origin/HEAD, master) [Sergio Gmez]
* 491f1d2 2013-06-16 | hola usa la clase HolaMundo (origin/hola, hola)
[Sergio Gomez]

6.1.5 Borrar ramas remotas


Para borrar una rama local se usaba git branch:
$ git branch -d nombre-rama

Pero para borrar una rama que est en el repositorio remoto hay que usar git push colocando el smbolo : antes del nombre de la rama:
$ git push origin :nombre-rama

44

Taller de introduccin a Git

Captulo 6 Administracin de repositorios

6.2 Repositorios bsicos


6.2.1 Creacin
Los repositorio bsicos (en ingls conocidos como bare repositories) no contienen la parte
llamada "directorio de trabajo" y son usados especficamente para ser compartidos, se usa indicando el parmetro --bare a las rdenes git clone y git init:
$ cd ..
$ git clone --bare curso-git curso-git.git
Cloning into bare repository 'curso-git.git'...
hecho.
$ ls curso-git.git/
branches config description HEAD hooks info
refs

objects

packed-refs

6.2.2 Aadir un repositorio remoto


Es posible indicar, para un proyecto ya existente, que utilice un repositorio remoto. En este caso, al proyecto original vamos a indicarle que use el nuevo repositorio bsico:
$ cd curso-git
$ git remote add origin ../curso-git.git

6.2.3 Subir cambios


El escenario que tenemos ahora es el siguiente:
Un repositorio bsico llamado curso-git.git donde se almacenar centralmente el
proyecto.
Un repositorio llamado curso-git donde trabajaremos.
Este es el escenario normal, un directorio centralizado y compartido y uno donde trabajamos localmente. En este escenario, iremos realizando cambios en nuestro directorio y,
posteriormente, los subiremos al repositorio compartido. Para eso usaremos la orden git
push.
Vamos a modificar nuestro archivo README.md de nuevo y a subir los cambios:
$ cat README.md
# Curso de GIT
Este proyecto contiene el curso de introduccin a GIT.
Ahora es un repositorio compartido.
Con esto ya estamos terminando el curso.
$ git add README.md
45

Captulo 6 Administracin de repositorios

Taller de introduccin a Git

$ git commit -m "Aadido un comentario compartido en README.md"


[master 243d834] Aadido un comentario compartido en README.md
1 file changed, 1 insertion(+)
$ git push -u origin master
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 372 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To ../curso-git.git/
3d2db03..243d834 master -> master
Branch master set up to track remote branch master from origin.

6.2.4 Actualizar cambios desde repositorios compartidos


El repositorio curso-git-clonado era un clon del repositorio original. Git permite modificar
las ramas remotas de un proyecto o aadir ms, de tal manera que podramos hacer ahora
dos cosas con ese repositorio:
Eliminar las referencias de origin/* y crear nuevas al repositorio bsico cursogit.git.
Aadir ms ramas remotas asociadas al repositorio bsico.
Esto ltimo sera:
$ cd ../curso-git-clonado/
$ git remote add shared ../curso-git.git
$ git pull -u shared master
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
De ../curso-git
* branch
master
-> FETCH_HEAD
Updating 3d2db03..243d834
Fast-forward
README.md | 1 +
1 file changed, 1 insertion(+)
$ cat README.md
# Curso de GIT
Este proyecto contiene el curso de introduccin a GIT.
Ahora es un repositorio compartido.
Con esto ya estamos terminando el curso.
46

Taller de introduccin a Git

Captulo 6 Administracin de repositorios

El parmetro -u es equivalente a hacer esto:


git branch --track shared master

47

Esta pgina se ha dejado vaca a propsito

48

Captulo 7

Github
Github es lo que se denomina una forja, un repositorio de proyectos que usan Git como
sistema de control de versiones. Es la forja ms popular, ya que alberga ms de 10 millones
de repositorios. Debe su popularidad a sus funcionalidades sociales, principalmente dos: la
posibilidad de hacer forks de otros proyectos y la posibilidad de cooperar aportando cdigo para arreglar errores o mejorar el cdigo. Si bien, no es que fuera una novedad, s lo es lo
fcil que resulta hacerlo. A raz de este proyecto han surgido otros como Gitorius o Gitlab,
pero Github sigue siendo el ms popular y el que tiene mejores y mayores caractersticas.
algunas de estas son:
Un wiki para documentar el proyecto, que usa MarkDown como lenguaje de marca.
Un portal web para cada proyecto.
Funcionalidades de redes sociales como followers.
Grficos estadsticos.
Revisin de cdigo y comentarios.
Sistemas de seguimiento de incidencias.
Lo primero es entrar en el portal (https://github.com/) para crearnos una cuenta si no la
tenemos an.

7.1 Configuracin
Vamos a aprovechar para aadir la clave RSA que generamos antes, para poder acceder
desde git a los repositorios. Para ellos nos vamos al men de configuracin de usuario, que
en la barra superior se identifica con un icono con un par de herramientas.

49

Captulo 7 Github

Taller de introduccin a Git

Figura 7.1 Barra principal de men


Nos vamos al men 'SSH Keys' y aadimos una nueva clave. En Title indicamos una descripcin que nos ayude a saber de dnde procede la clave y en key volcamos el contenido
del archivo ~/.ssh/id_rsa.pub. Y guardamos la clave.
Con esto ya tendriamos todo nuestro entorno para poder empezar a trabajar desde nuestro
equipo.

7.2 Clientes grficos para GitHub


Adems, para Github existe un cliente propio tanto para Windows como para MacOSX:
Cliente Windows: http://windows.github.com/
Cliente MacOSX: http://mac.github.com/
Para Linux no hay cliente propio, pero s hay plugin para Eclipse:
Cliente Eclipe: http://eclipse.github.com/
De todas maneras, estos clientes solo tienen el fin de facilitar el uso de Github, pero no
son necesarios para usarlo. Es perfectamente vlido usar el cliente de Git o cualquier otro
cliente genrico para Git. Uno de los ms famosos es Smartgit(http://www.syntevo.com/
smartgithg/).

7.3 Trabajando con un proyecto


Antes de nada, este tutorial tiene los siguiente pre-requisitos:
Git
PHP versin 5.4.0 o superior
Composer (Disponible en https://getcomposer.org/download/).
Todo el software se encuentra disponible en Thinstation.

7.4 Trabajando con Github


7.4.1 Clonado de un repositorio.
Nos vamos a la web del proyecto en el que queremos colaborar. En este caso el proyecto
se encuentra en https://github.com/sgomez/miniblog. Pulsamos en el botn de fork y eso
crear una copia en nuestro perfil.
50

Taller de introduccin a Git

Captulo 7 Github

Figura 7.2 Barra de informacin de proyecto


Una vez se termine de clonar el repositorio, nos encontraremos con el espacio de trabajo
del mismo:
En la parte superior informacin sobre los commits, ramas, etiquetas, etc.
Justo debajo un explorador de archivos.
En la parte derecha un selector para cambiar de contexto entre: explorador de
cdigo, peticiones de colaboracin (pull request), wiki, configuracin, etc.
Justo abajo a la derecha informacin sobre como clonar localmente o descargar un
proyecto.

Figura 7.3 Espacio de trabajo


Github nos permite clonar localmente un proyecto por tres vas: HTTPS, SSH y Subversion. Seleccionamos SSH y copiamos el texto que despus aadiremos a la orden git clone como en la primera lnea del siguiente grupo de rdenes:
$
$
$
$

git clone git@github.com:miusuario/miniblog.git


cd miniblog
composer.phar install
php console create-schema

Lo que hace el cdigo anterior es:


51

Captulo 7 Github

Taller de introduccin a Git

1. Clona el repositorio localmente


2. Entramos en la copia
3. Instalamos las dependencias que la aplicacin tiene
4. Arrancamos un servidor web para pruebas
Y probamos que nuestra aplicacin funciona:
$ php -S localhost:9999 -t web/

Podemos usar dos direcciones para probarla:


Frontend: http://localhost:9999/index_dev.php
Backend: http://localhost:9999/index_dev.php/admin/ con usuario admin
y contrasea 1234.

7.4.2 Sincronizar con el repositorio original


Cuando clonamos un repositorio de otro usuario hacemos una copia del original. Pero esa
copia es igual al momento en el que hicimos la copia. Cuando el repositorio original cambie, que lo har, nuestro repositorio no se actualizar solo. Son dos repositorios diferentes!
Necesitamos una manera de poder incorporar los cambios que vaya teniendo el repositorio original en el nuestro. Para eso crearemos una nueva rama remota. Por convenio, y como vimos anteriormente, ya existe una rama remota llamada origin que apunta al repositorio de donde clonamos el proyecto, en este caso apunta a nuestro fork en github:
$ git remote show origin
* remote origin
Fetch URL: git@github.com:miusuario/miniblog.git
Push URL: git@github.com:miusuario/miniblog.git
HEAD branch (remote HEAD is ambiguous, may be one of the following):
develop
master
Remote branches:
develop tracked
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)

Tambin por convenio, la rama remota que hace referencia al repositorio original se llama upstream y se crea de la siguiente manera:
52

Taller de introduccin a Git

Captulo 7 Github

$ git remote add upstream git@github.com:sgomez/miniblog.git


$ git remote show upstream
* remote upstream
Fetch URL: git@github.com:sgomez/miniblog.git
Push URL: git@github.com:sgomez/miniblog.git
HEAD branch: master
Remote branches:
develop new (next fetch will store in remotes/upstream)
master new (next fetch will store in remotes/upstream)
Local ref configured for 'git push':
master pushes to master (local out of date)

En este caso, la URI debe ser siempre la del proyecto original. Y ahora para incorporar actualizaciones, usaremos el merge en dos pasos:
$ git fetch upstream
$ git merge upstream/master

Recordemos que fetch solo trae los cambios que existan en el repositorio remoto sin hacer
ningn cambio en nuestro repositorio. Es la orden merge la que se encarga de que todo est
sincronizado. En este caso decimos que queremos fusionar con la rama master que est en
el repositorio upstream.

7.4.3 Creando nuevas funcionalidades


Vamos a crear una nueva funcionalidad: vamos a aadir una licencia de uso. Para ello preferentemente crearemos una nueva rama.
$
$
#
$
$

git checkout -b add-license


echo "LICENCIA MIT" > LICESE
el error es intencionado
git add LICESE
git commit -m "Archivo de licencia de uso"

En principio habra que probar que todo funciona bien y entonces integraremos en la rama master de nuestro repositorio y enviamos los cambios a Github:
$
$
$
#
$
#

git checkout master


git merge add-license --no-ff
git branch -d add-license
Borramos la rama que ya no nos sirve para nada
git push --set-upstream origin add-license
Enviamos la rama a nuestro repositorio origin

53

Captulo 7 Github

Taller de introduccin a Git

Si volvemos a Github, veremos que nos avisa de que hemos subido una nueva rama y si
queremos crear un pull request.

Figura 7.4 Aviso de nueva rama


Pulsamos y entramos en la peticin de Pull Request. Este es el momento para revisar cualquier error antes de enviar al dueo del repositorio. Como vemos hemos cometido uno,
nombrando el fichero, si lo correguimos debemos hacer otro push para ir actualizando la
rama. Cuando est lista volvemos aqu y continuamos. Hay que dejar una descripcin del
cambio que vamos a hacer.

Figura 7.5 Creando un Pull Request


Una vez hemos terminado y nos aseguramos que todo est correcto, pulsamos Send pull request y le llegar nuestra peticin al dueo del proyecto.

Figura 7.6 Gestin de un _Pull Request_

54

Taller de introduccin a Git

Captulo 7 Github

Sin embargo, para esta prueba, no vamos a cambiar el nombre del archivo y dejaremos el
error como est. As de esta manera al administrador del proyecto le llegar el Pull Request
y la lista de cambios. Ahora en principio, cabra esperar que el administrador aprobara los
cambios, pero podra pasar que nos indicara que cambiemos algo. En ese caso solo habra
que modificar la rama y volverla a enviar.
$ git mv LICESE LICENSE
$ git commit -m "Fix: Nombre de archivo LICENSE"
$ git push

Ahora s, el administrador puede aprobar la fusin y borrar la rama del repositorio. El panel de Github permite aceptar los cambios directamente o informa de como hacer una copia de la rama ofrecida por el usuario para hacer cambios, como puede verse en la siguiente imagen.

Figura 7.7 Conversacin en un _Pull Request_


Una vez que se han aceptado los cambios, podemos borrar la rama y actualizar nuestro repositorio con los datos del remoto como hicimos antes. Por qu actualizar desde el remoto
y no desde nuetra rama add-license? Pues porque usualmente el administrador puede ha-

55

Captulo 7 Github

Taller de introduccin a Git

ber modificado los cambios que le hemos propuesto, o incluso una tercera persona. Recordemos el cariz colaborativo que tiene Github.
$
$
#
$
#

git checkout master


git branch -d add-license
Esto borra la rama local
git push origin --delete add-license
Esto borra la rama remota. Tambin puede hacerse desde la web.

7.4.4 Todo esto es algo complicado...


S, lo es, al menos al principio. Git tiene una parte muy sencilla que es el uso del repositorio
local (rdenes tales como add, rm, mv y commit). El siguiente nivel de complejidad lo
componen las rdenes para trabajar con ramas y fusionarlas (checkout, branch, merge, rebase) y por ltimo, las que trabajan con repositorios remotos (pull, push, fetch, remote).
Adems hay otra serie de rdenes para tener informacin (diff, log, status) o hacer operaciones de mantenimiento (fsck, gc). Lo importante para no perderse en Git, es seguir la siguiente mxima:

No avanzar al siguiente nivel de complejidad, hasta no haber entendido completamente el anterior.

Muy poco sentido tiene ponernos a crear ramas en github si an no entendemos cmo se
crean localmente y para que deben usarse. En la parte de referencias hay varios manuales
en lnea, incluso tutoriales interactivos. Tambin hay mucha documentacin disponible
en Github que suele venir muy bien explicada. En caso de que tengamos un problema que
no sepamos resolver, una web muy buena es StackOverflow (http://stackoverflow.com/)
. Es una web de preguntas y respuestas para profesionales; es muy difcil que se os plantee
una duda que no haya sido ya preguntada y respondida en esa web. Eso s, el ingls es imprescindible.

7.5 ltimo paso, documentacin.


Github permite crear documentacin. En primer lugar, generando un archivo llamado
README. Tambin permite crear una web propia para el proyecto y, adems, una wiki.
Para marcar el texto, se utiliza un lenguaje de marcado de texto denominado Markdown.
En la siguiente web hay un tutorial interactivo: http://www.markdowntutorial.com/. Como en principio, no es necesario saber Markdown para poder trabajar con Git o con Github, no vamos a incidir ms en este asunto.
Sin embargo, para los curiosos dejamos como referencia la web de Easybook
(http://easybook-project.org/) . Este proyecto, que se encuentra tambin en Github, per56

Taller de introduccin a Git

Captulo 7 Github

mite crear documentos en PDF, HTML o ePub a partir de documentos escritos en Markdown. Este manual, por ejemplo, ha sido escrito en Markdown y pasado a PDF con Easybook.

57

Esta pgina se ha dejado vaca a propsito

Referencias
Documentacin oficial en ingls (http://git-scm.com/documentation) .
Documentacin oficial en espaol (quizs incompleta) (http://git-scm.com/book/
es) .
Curso de Git (ingls) (http://gitimmersion.com/lab_01.html) . La mayora de la
documentacin de este manual est basada en este curso.
Curso interactivo de Git (ingls) (http://try.github.io/levels/1/challenges/1) .
Pgina de referencia de todas las rdenes de Git (ingls) (http://gitref.org/) .
Chuleta con las rdenes ms usuales de Git (http://byte.kde.org/~zrusin/git/gitcheat-sheet-large.png) .
Gitmagic (ingles y espaol). Otro manual de Git (http://www-csstudents.stanford.edu/~blynn/gitmagic/intl/es/)
Artculo tcnico: Un modelo exitoso de ramificacin en Git (http://nvie.com/posts/
a-successful-git-branching-model/) .

Você também pode gostar