Git
Chapters ▾ 2nd Edition

7.12 Herramientas de Git - Agrupaciones

Agrupaciones

Aunque ya hemos considerado las maneras mas comunes de transferir la base de datos del Git en el internet (HTTP, SSH, etc.), existe aún una manera de hacerlo, aunque no es muy comúnmente usada puede ser muy útil.

El Git es capaz de “agrupar” la base de datos en un único archivo. Esto puede ser muy útil en varios escenarios. Tal vez tu red está caída y quieres enviar cambios a tu co-trabajdores. Quizas estás trabajando en algún lugar sin conexión y no tienes acceso a la red local por motivos de seguridad. Tal vez su tarjeta inalámbrica / ethernet se rompió. Tal vez no tienes acceso al servidor compartido por el momento, y quieres enviar un correo con actualizaciones y no quieres transferir 40 confirmaciones via format-patch.

Aquí es donde el comando de git bundle es muy útil. El comando bundle juntará todo lo que normalmente se empujaría sobre el cable con un comando de` push git ‘en un archivo binario que puedes enviar por correo a alguien o poner un flash drive, luego desglosarlo en otro repositorio.

Veamos un ejemplo simple. Digamos que tienes un repositorio con dos confirmaciones:

$ git log
commit 9a466c572fe88b195efd356c3f2bbeccdb504102
Author: Scott Chacon <schacon@gmail.com>
Date:   Wed Mar 10 07:34:10 2010 -0800

    Segunda Confirmacion

commit b1ec3248f39900d2a406049d762aa68e9641be25
Author: Scott Chacon <schacon@gmail.com>
Date:   Wed Mar 10 07:34:01 2010 -0800

    Primera confirmaciión

Si quieres enviar ese repositorio a alguien y no tienes acceso a algún repositorio para hacerlo, o simplemente no quieres configurar uno, puedes juntarlo con el `git bundle create `.

$ git bundle create repo.bundle HEAD master
Counting objects: 6, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 441 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)

Ahora tienes un archive nombrado repo.bundle este tiene todos los datos nuevos necesarios para re-crear el repositorio de la rama maester. Con el comando de bundle necesitaras enlistar cualquier referencia o rango especifico de confirmaciones que quieres que sean incluidas. Si tiene la intención de clonar esto en otro lugar, debe agregar HEAD como referencia, así como lo hemos hecho aquí.

Puedes enviar por correo este archivo repo.bundle a alguien más, o ponerlo en una memoria USB y simplemente irte.

Por otro lado, supongamos que se envía este archivo de repo.bundle y deseas trabajar en el proyecto. Puedes clonarlo desde el archivo binario en un directorio, como lo harías desde una URL.

$ git clone repo.bundle repo
Initialized empty Git repository in /private/tmp/bundle/repo/.git/
$ cd repo
$ git log --oneline
9a466c5 second commit
b1ec324 first commit

Si no quieres incluir HEAD en las referencias, tambien tendrás que especificar -b master o cualquier rama que sea incluída porque de otra manera no sabrá que rama revisar.

Digamos que ahora haces tres confirmaciones en ello y quieres enviar nuevas confirmaciones via agrupacion en una USB o por correo.

$ git log --oneline
71b84da last commit - second repo
c99cf5b fourth commit - second repo
7011d3d third commit - second repo
9a466c5 second commit
b1ec324 first commit

Primero necesitamos determinar el rango de confirmaciones que queremos incluir en la agrupación. No como los protocolos de la red que figuraran en el mínimo de datos para transferir desde la red por nosotros, tendremos que hacer esto manualmente. Ahora simplemente puedes hacer la misma cosa y agrupar el repositorio entero, el que trabajará, pero es mejor solo agrupar las diferencias – solamente las tres confirmaciones que hicimos localmente.

Para hacer eso, tienes que calcular la diferencia. Como hemos descrito en Rangos de Commits, Puedes especificar el rango de confirmaciones en un numero de caminos. Para obtener las tres confirmaciones que tenemos en nuestra rama maestra que no estaban en la rama que copiamos originalmente, podemos usar algo como origin/master..master o master ^origin/master. Puedes probar esto con el comando de log.

$ git log --oneline master ^origin/master
71b84da last commit - second repo
c99cf5b fourth commit - second repo
7011d3d third commit - second repo

Entonces ahora que tenemos la lista de confirmaciones queremos incluirlas en la agrupación, agrupémoslas todas. hacemos eso con el comando de git bundle create, dandole un nombre al archivo que queremos que sea parte de la agrupación y el rango de confirmaciones que queremos incluir en el mismo.

$ git bundle create commits.bundle master ^9a466c5
Counting objects: 11, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (9/9), 775 bytes, done.
Total 9 (delta 0), reused 0 (delta 0)

Ahora tenemos un archivo de commits.bundle en nuestro directorio. Si tomamos este y se lo enviamos a nuestro compañero, ella pueda importarlo en el repositorio original, incluso si se ha incluido más trabajo en el tiempo que ha pasado.

Cuando obtenga la agrupación, puede inspeccionarlo para ver que contiene antes de que lo importe en el repositorio. El primer comando es el bundle verify que hará saber si el archivo es actualmente una agrupacion válida del Git y asi tendras todos los requerimientos necesarios para reconstituiirlo apropiadamente.

$ git bundle verify ../commits.bundle
The bundle contains 1 ref
71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master
The bundle requires these 1 ref
9a466c572fe88b195efd356c3f2bbeccdb504102 second commit
../commits.bundle is okay

Si el agrupador a creado una agrupación de solo las dos últimas confirmaciones que se han hecho, en lugar de las tres, tel repositorio original no será capaz de improtarlo, dado que falta un requisito en la historia. El comando de verify debería de verse entonces así:

$ git bundle verify ../commits-bad.bundle
error: Repository lacks these prerequisite commits:
error: 7011d3d8fc200abe0ad561c011c3852a4b7bbe95 third commit - second repo

Como sea, nuestra primera agrupación es válida, Entonces podemos obtener confirmaciones de ella. si quieres ver que ramas están en la agrupación que pueden ser importadas, de igual manera hay un comando para verlo:

$ git bundle list-heads ../commits.bundle
71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master

el sub-comando de verify te dira el encabezado tambien. el punto es ver que puede ser puesto, para que puedas usar el comando de fetch fetch o pull para importar confirmaciones de este archivo. Aquí vamos a buscar la rama master de la agrupación por una llamada other-master en nuestro repositorio:

$ git fetch ../commits.bundle master:other-master
From ../commits.bundle
 * [new branch]      master     -> other-master

Ahora podemos ver que hemos importado las confirmaciones a la rama de other-master’asi mismo como tantas confirmaciones hayamos hecho mientras tanto en nuestra rama 'master .

$ git log --oneline --decorate --graph --all
* 8255d41 (HEAD, master) third commit - first repo
| * 71b84da (other-master) last commit - second repo
| * c99cf5b fourth commit - second repo
| * 7011d3d third commit - second repo
|/
* 9a466c5 second commit
* b1ec324 first commit

Entonces, git bundle puede ser muy util para compartir o hacer operaciones tipo red cuando no tienes la red adecuada o repositorio compartido para hacerlo.