-
1. Inicio - Sobre el Control de Versiones
-
2. Fundamentos de Git
-
3. Ramificaciones en Git
-
4. Git en el Servidor
- 4.1 Los Protocolos
- 4.2 Configurando Git en un servidor
- 4.3 Generando tu clave pública SSH
- 4.4 Configurando el servidor
- 4.5 El demonio Git
- 4.6 HTTP Inteligente
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Git en un alojamiento externo
- 4.10 Resumen
-
5. Git en entornos distribuidos
-
6. GitHub
-
7. Herramientas de Git
- 7.1 Revisión por selección
- 7.2 Organización interactiva
- 7.3 Guardado rápido y Limpieza
- 7.4 Firmando tu trabajo
- 7.5 Buscando
- 7.6 Reescribiendo la Historia
- 7.7 Reiniciar Desmitificado
- 7.8 Fusión Avanzada
- 7.9 Rerere
- 7.10 Haciendo debug con Git
- 7.11 Submódulos
- 7.12 Agrupaciones
- 7.13 Replace
- 7.14 Almacenamiento de credenciales
- 7.15 Resumen
-
8. Personalización de Git
-
9. Git y Otros Sistemas
- 9.1 Git como Cliente
- 9.2 Migración a Git
- 9.3 Resumen
-
10. Los entresijos internos de Git
-
A1. Apéndice A: Git en otros entornos
- A1.1 Interfaces gráficas
- A1.2 Git en Visual Studio
- A1.3 Git en Eclipse
- A1.4 Git con Bash
- A1.5 Git en Zsh
- A1.6 Git en Powershell
- A1.7 Resumen
-
A2. Apéndice B: Integrando Git en tus Aplicaciones
- A2.1 Git mediante Línea de Comandos
- A2.2 Libgit2
- A2.3 JGit
-
A3. Apéndice C: Comandos de Git
- A3.1 Configuración
- A3.2 Obtener y Crear Proyectos
- A3.3 Seguimiento Básico
- A3.4 Ramificar y Fusionar
- A3.5 Compartir y Actualizar Proyectos
- A3.6 Inspección y Comparación
- A3.7 Depuración
- A3.8 Parcheo
- A3.9 Correo Electrónico
- A3.10 Sistemas Externos
- A3.11 Administración
- A3.12 Comandos de Fontanería
10.5 Los entresijos internos de Git - Las especificaciones para hacer referencia a… (refspec)
Las especificaciones para hacer referencia a… (refspec)
A lo largo del libro hemos utilizado sencillos mapeados entre ramas remotas y referencias locales, pero las cosas pueden ser bastante más complejas. Supón que añades un remoto tal que:
$ git remote add origin https://github.com/schacon/simplegit-progit
Esto añade una nueva sección a tu archivo .git/config
, indicando el nombre del remoto (origin
), la ubicación (URL) del repositorio remoto y la referencia para recuperar (fetch) desde él:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/*
El formato para esta referencia es un signo {plus}
opcional, seguido de una sentencia <orig>:<dest>
; donde <orig>
es la plantilla para referencias en el lado remoto y <dest>
el lugar donde esas referencias se escribirán en el lado local.
El {plus}
, si está presente, indica a Git que debe actualizar la referencia incluso en los casos en que no se dé un avance rápido (fast-forward).
En el caso por defecto en que es escrito por un comando git remote add
, Git recupera del servidor todas las referencias bajo refs/heads/
, y las escribe localmente en refs/remotes/origin/
.
De tal forma que, si existe una rama master
en el servidor, puedes acceder a ella localmente a través de
$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master
Todas estas sentencias son equivalentes, ya que Git expande cada una de ellas a refs/remotes/origin/master
.
Si, en cambio, quisieras hacer que Git recupere únicamente la rama master
y no cualquier otra rama en el servidor remoto, puedes cambiar la linea de recuperación a
fetch = +refs/heads/master:refs/remotes/origin/master
Quedando así esta referencia como la referencia por defecto para el comando git fetch
para ese remoto.
Para hacerlo puntualmente en un momento concreto, puedes especificar la referencia directamente en la linea de comando.
Para recuperar la rama master
del servidor remoto a tu rama origin/mymaster
local, puedes lanzar el comando
$ git fetch origin master:refs/remotes/origin/mymaster
Puedes incluso indicar múltiples referencias en un solo comando. Escribiendo algo así como:
$ git fetch origin master:refs/remotes/origin/mymaster \
topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
! [rejected] master -> origin/mymaster (non fast forward)
* [new branch] topic -> origin/topic
En este ejemplo, se ha rechazado la recuperación de la rama master porque no era una referencia de avance rápido (fast-forward).
Puedes forzarlo indicando el signo {plus}
delante de la referencia.
Es posible asimismo indicar referencias múltiples en el archivo de configuración. Si, por ejemplo, siempre recuperas las ramas master y experiment, puedes poner dos líneas:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/experiment:refs/remotes/origin/experiment
Pero, en ningún caso puedes poner referencias genéricas parciales; por ejemplo, algo como esto sería erroneo:
fetch = +refs/heads/qa*:refs/remotes/origin/qa*
Aunque, para conseguir algo similar, puedes utilizar los espacios de nombres . Si tienes un equipo QA que envía al servidor una serie de ramas, y deseas recuperar la rama master y cualquier otra de las ramas del equipo, pero no recuperar ninguna rama de otro equipo, puedes utilizar una sección de configuración como esta:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
De esta forma, puedes asignar fácilmente espacios de nombres; y resolver así complejos flujos de trabajo donde tengas simultáneamente, por ejemplo, un equipo QA enviando ramas, varios desarrolladores enviando ramas también y equipos integradores enviando y colaborando en ramas remotas.
Enviando (push) referencias
Es útil poder recuperar (fetch) referencias relativas en espacios de nombres, tal y como hemos visto, pero, ¿cómo pueden enviar (push) sus ramas al espacio de nombres qa/
los miembros de equipo QA ?.
Pues utilizando las referencias (refspecs) para enviar.
Si alguien del equipo QA quiere enviar su rama master
a la ubicación qa/master
en el servidor remoto, puede lanzar algo así como:
$ git push origin master:refs/heads/qa/master
Y, para que se haga de forma automática cada vez que ejecute git push origin
, puede añadir una entrada push
a su archivo de configuración:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master
Esto hará que un simple comando git push origin
envíe por defecto la rama local master
a la rama remota qa/master
,
Borrando referencias
Se pueden utilizar las referencias (refspec) para borrar en el servidor remoto. Por ejemplo, lanzando algo como:
$ git push origin :topic
Se elimina la rama topic del servidor remoto, ya que la sustituimos por nada.
(Al ser la referencia <origen>:<destino>
, si no indicamos la parte <origen>
, realmente estamos diciendo que enviamos nada a <destino>
.)