Escolar Documentos
Profissional Documentos
Cultura Documentos
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 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 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
Captulo 1
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).
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).
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.
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.
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).
12
13
14
Captulo 2
O si ests en una distribucin basada en Debian como Ubuntu, prueba con apt-get:
$ apt-get install git
15
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
16
Captulo 3
17
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";
El valor "." despues de git add indica que se aadan todos los archivos que hayan cambiado.
20
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
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]
21
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.
22
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
24
Captulo 4
El mismo Git nos indica que debemos hacer para aadir los cambios o para deshacerlos:
25
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
no changes added to commit (use "git add" and/or "git commit -a")
$ git checkout hola.php
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.
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
mkdir lib
git mv hola.php lib
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed:
mkdir lib
mv hola.php lib
git add lib/hola.php
git rm hola.php
29
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'
Captulo 5 Ramas
$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(-)
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]
Captulo 5 Ramas
| |
| * 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.
Captulo 5 Ramas
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
Captulo 5 Ramas
37
Captulo 5 Ramas
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.
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
Captulo 5 Ramas
39
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.
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)
cd ..
cd curso-git
cat README.md
Curso de GIT
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
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.
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
objects
packed-refs
47
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
Captulo 7 Github
Captulo 7 Github
Tambin por convenio, la rama remota que hace referencia al repositorio original se llama upstream y se crea de la siguiente manera:
52
Captulo 7 Github
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.
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:
$
$
$
#
$
#
53
Captulo 7 Github
Si volvemos a Github, veremos que nos avisa de que hemos subido una nueva rama y si
queremos crear un pull request.
54
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.
55
Captulo 7 Github
ber modificado los cambios que le hemos propuesto, o incluso una tercera persona. Recordemos el cariz colaborativo que tiene Github.
$
$
#
$
#
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.
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
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/) .