Jugando con Git
Vamos a instalar Git en un windows y a jugar un poco con él, nada más algunas operaciones y comandos básicos. Hay muchos más comandos aparte de los que se comentan aquí, y los que se comentan aquí tienen muchas más opciones y posibilidades. Simplemente se pretende dar un vistazo rápido y sencillo al trabajo con git.
Instalación[editar]
Vamos a la página de Git y nos descargamos el instalador de nuestro sistema operativo, windows en mi caso. Es un instalador sencillo estilo Windows y sólo tenemos que ir dándole a "siguiente" en cada ventana.
Hay una ventana algo especial en que nos pregunta si queremos instalar una bash shell (ventana de comandos típica de linux) específica para Git, si queremos hacer la instalación para cygwin (un entorno linux sobre windows) o si queremos incluir los comandos de git dentro de nuestro windows. Esta última opción tiene sus pegas puesto que reemplaza algunos comandos de windows, como find.exe, por el mismo comando paro con el funcionamiento y sintaxis de linux. En mi caso, por ser la menos instrusiva y más directa, elijo una bash shell específica para Git. En una de las ventanas de instalación pueder marcarse para que en los menús del explorador de archivos de windows aparezca una opción "Git bash here", facilitando el abrir esta bash shell en cualquier directorio.
Crear un repositorio[editar]
Crear un repositorio es fácil. Simplemente abrimos la bash shell en el directorio que queramos y ponemos
git init
o bien
git init --bare
El primero inicializa el repositorio como si fuera una copia de trabajo, por lo que crea un subdirectorio .git para poner la información específica de git y nos deja el directorio para nuestros ficheros. El segundo hace lo mismo, pero pensando que ese repositorio va a estar en un servidor y nadie va a tener una copia de trabajo en él, por lo que no crea el subdirectorio .git, sino que pone todos los ficheros específicos de git directamente en ese directorio.
Arrancar un servidor de Git[editar]
Git viene con un servidor propio. Su arranque por defecto, que es de solo lectura, es muy sencillo, basta con ejecutar
git daemon
Si queremos que el servidor admita escritura, debemos indicarlo en el arranque
git daemon --enable=receive-pack
En los repositorios que queremos que sean accesibles desde este servidor, debemos crear el fichero
git-daemon-export-ok
en el subdirectorio .git o directamente en el directorio del repositorio si lo habíamos creado con la opción --bare.
Otras opciones son poner accesible git a través de ssh o de un servidor http, pero no nos vamos a meter ahora en ello.
Clonar un repositorio[editar]
Nuestra primera operación normalmente será clonar un repositorio en nuestro ordenador para tener una copia local. Si el respositorio está en nuestro propio ordenador, podemos hacerlo directamente con el path
git clone ../proyecto micopia
Si está en un directorio compartido de otro ordenador, podemos hacerlo con
git clone file:////ordenador/path_compartido/proyecto micopia
y si el servidor tiene un git daemon arrancado
git clone git://ordenador/path/proyecto micopia
Si hemos arrancado git daemon por defecto, el path será el path absoluto del repositorio en el servidor. Si arrancamos, por ejemplo
git clone git://ordenador_javier/Users/Javier/proyecto micopia
Si arrancamos git daemon con la opción --base_path=/Users/Javier, podemos ahorranos esa primera parte
git clone git://ordenador_javier/proyecto micopia
Hacer cambios en nuestro repositorio local[editar]
Creamos un fichero cualquiera en nuestra copia, por ejemplo, hola.txt con contenido "hola". Para añadirlo a nuestro repositorio
git add hola.txt
Para guardar el cambio definitivamente en nuestro repositorio
git commit -m"comentario" hola.txt
o bien, si hay varios ficheros añadidos con add y queremos meterlos todos de golpe
git commit -m"comentario" -a
Llevar y traer cambios del servidor remoto[editar]
Una vez hechos nuestros cambios locales y hechos los commit, podemos llevar nuestros cambios al servidor del que hemos clonado nuestro repositorio. Este servidor origen de nuestra copia tiene el nombre "origin" por defecto. El comando para llevar estos cambios puede ser
git push origin
o bien simplemente
git push
Si alguien ha hecho cambios en el original y queremos traerlos, los comandos pueden ser
git pull origin
o bien simplemente
git pull
Crear una rama de trabajo[editar]
Una vez clonado nuestro repositorio, podemos querer crear una nueva rama de trabajo, de forma que si el resultado final no nos gusta la desechamos y si nos convece, la juntamos con la principal.
La rama principal de un repositorio se llama por defecto "master". Para hacer una nueva rama ponemos
git checkout -b nuevarama master
o bien simplemente
git checkout -b nuevarama
La opción -b creará una nuevarama de trabajo copia de "master". En vez de "master" se podría poner el nombre de otra rama, o alguna etiqueta o versión concreta. Por ejemplo, con git log podemos ver los números de commit y con uno de ellos podríamos obtener una copia con
git checkout -b ramadesdeversion 48c7081ad62af5eb4db2500511c5462c8f81b2cb
Podemos traer una rama desde el repositorio remoto con
git checkout -b nuevarama origin/rama
Una vez creada la rama, podemos trabajar en ella de la forma habitual, editando ficheros y haciendo git commit desde ellos.
Cambiar de rama[editar]
Si las ramas ya están creadas, podemos cambiar de una a otra con el comando
git checkout rama
o bien
git checkout master
para volver a la rama principal. El comando git branch nos permite ver y manejar ramas
- git branch : nos muestra las ramas en nuestro repositorio local
- git branch -r : nos muestra las ramas en el repositorio del que nos hemos clonado (origin)
- git branch --all : nos muestra todas las ramas, locales y remotas.
Hay, por supuesto, opciones para borrar ramas.
Trabajar con ramas remotas[editar]
Una vez creada nuestra rama local, podemos subirla al servidor original con
git push origin rama git branch --set-upstream rama origin/rama
El primer comando sube nuestra rama al servidor original con el mismo nombre "rama". Sin embargo, al hacer esto la rama local y la remota no quedan ligadas, git no reconoce que sean la misma rama en repositorios distintos, por lo que no sabrá luego hacer git pull ni git push desde esta rama. El segundo comando sirve para ligarlas, indicando que origin/rama (remota) corresponde con rama (local). Una vez hecho este comando, podremos hacer git push y git pull desde esta rama sin problemas.
Nos podemos bajar una rama remota, como ya hemos visto, con
git checkout -b rama origin/rama
que creará la rama local como copia de la remota origin/rama. Esta vez sí queda ligada a la origin/rama, por lo que git push y git pull funcionarán correctamente.
Merge entre ramas[editar]
Si hemos creado una rama y hemos trabajado en los ficheros de la misma, puede en un momento dado interesarnos llevar estos cambios a otra rama, por ejemplo la principal master. Para llevar estos cambios de forma más o menos automática, nos situamos en la rama destino de los cambios (master en nuestro ejemplo)
git checkout master
y ejecutamos el comando merge
git merge rama
Esto intentará hacer los cambios que hicimos en rama en los ficheros de master, Si lo consigue no da error. Si hay alguna cosa que no sabe hacer, nos indicará que hay conflictos en determinados ficheros. El error será parecido a
$ git merge rama Auto-merging hola.txt CONFLICT (content): Merge conflict in hola.txt Automatic merge failed; fix conflicts and then commit the result.
La forma de resolver los conflictos es editar los ficheros que nos indiquen (hola.txt en nuestro ejemplo) y buscar las líneas que se parecen a esto
<<<<<<< HEAD contenido master ======= ccontenido rama >>>>>>> rama
Entre <<< y ==== aparece el contenido en la rama original (master) y entre ==== y >>>> el contenido de la rama, las mismas líneas en ambos casos. Debemos eliminar en el fichero las lineas <<<<HEAD, ====== y >>>>>>rama, así como elegir cual es el contenido bueno del fichero para esas líneas. Una vez hecho con todos los ficheros con conflictos, debemos "añadir" nuevamente estos ficheros
git add hola.txt
y luego un commit sin indicar qué ficheros
git commit -m"resuelto conflicto"
git no admite commits parciales mientras se resuelven conflictos, debemos resolver todos los ficheros y hacer un únioc commit.