Skip to content

Latest commit

 

History

History
98 lines (78 loc) · 5.23 KB

File metadata and controls

98 lines (78 loc) · 5.23 KB
Convergencia de Subárbol

La idea de la convergencia de subárboles es que usted tiene dos proyectos, de los cuales uno lleva un subdirectorio del otro y viceversa Cuando especifica una convergencia de subárbol, Git suele ser lo suficientemente inteligente para comprender que uno es un subárbol del otro y convergerá apropiadamente.

Veremos un ejemplo donde se añade un proyecto separado a un proyecto existente y luego se converge el código del segundo dentro de un subdirectorio del primero.

Primero, añadiremos la aplicación Rack a nuestro proyecto. Añadiremos el proyecto Rack como referencia remota en nuestro propio proyecto y luego lo colocaremos en su propia branch:

$ git remote add rack_remote https://github.com/rack/rack
$ git fetch rack_remote
warning: no common commits
remote: Counting objects: 3184, done.
remote: Compressing objects: 100% (1465/1465), done.
remote: Total 3184 (delta 1952), reused 2770 (delta 1675)
Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done.
Resolving deltas: 100% (1952/1952), done.
From https://github.com/rack/rack
 * [new branch]      build      -> rack_remote/build
 * [new branch]      master     -> rack_remote/master
 * [new branch]      rack-0.4   -> rack_remote/rack-0.4
 * [new branch]      rack-0.9   -> rack_remote/rack-0.9
$ git checkout -b rack_branch rack_remote/master
Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master.
Switched to a new branch "rack_branch"

Ahora tenemos la raíz del proyecto Rack en nuestro branch rack_branch y nuestro proyecto en el branch master. Si verifica uno y luego el otro, puede observar que tienen diferentes raíces de proyecto:

$ ls
AUTHORS         KNOWN-ISSUES   Rakefile      contrib         lib
COPYING         README         bin           example         test
$ git checkout master
Switched to branch "master"
$ ls
README

Este concepto es algo extraño. No todas las 'branchs' en su repositorio tendrán que ser 'branchs' del mismo proyecto como tal. No es común, porque rara vez es de ayuda, pero es fácil que los 'branchs' contengan historias completamente diferentes.

En este caso, queremos integrar el proyecto Rack a nuestro proyecto master como un subdirectorio. Podemos hacer eso en Git con git read-tree. Aprenderá más sobre read-tree y sus amigos en ch10-git-internals.asc, pero por ahora sepa que éste interpreta el árbol raíz de una 'branch' en su ''área de staging' y 'directorio de trabajo'. Sólo cambiamos de vuelta a su 'branch' master, e integramos la 'branch' rack_branch al subdirectorio rack de nuestra 'branch' master de nuestro proyecto principal:

$ git read-tree --prefix=rack/ -u rack_branch

Cuando hacemos ``commit'', parece que tenemos todos los archivos Rack bajo ese subdirectorio - como si los hubiéramos copiado de un tarball. Lo interesante es que podemos facilmente converger cambios de una de las 'branchs' a la otra. Entonces, si el proyecto Rack se actualiza, podemos atraer cambios río arriba alternando a esa 'branch' e incorporando:

$ git checkout rack_branch
$ git pull

Luego, podemos converger de vuelta esos cambios a nuestr 'branch' master. Para incorporar los cambios y rellenar previamente el mensaje de `commit'', utilice las opciones `--squash y --no-commit, así como la estrategia de convergencia recursiva de la opción -Xsubtree. (La estrategia recursiva está aquí por defecto, pero la incluímos para aclarar.)

$ git checkout master
$ git merge --squash -s recursive -Xsubtree=rack --no-commit rack_branch
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested

Todos los cambios del proyeto Rack se convergieron y están listos para ser encomendados localmente. También puede hacer lo opuesto - hacer cambios en el subdirectorio rack de su master branch y luego convergerlos a su 'branch' rack_branch más adelante para entregarlos a los mantenedores o empujarlos río arriba.

Esto nos deja una manera de tener un flujo de trabajo algo similar al flujo de trabajo de submódulo sin utilizar submódulos (de los cuales hablamos en [r_git_submodules]). Podemos mantener 'branchs' con otros proyectos relacionados en nuestro repositorio y convergerlos tipo subárbol a nuestro proyecto ocasionalmente. Esto es bueno por ciertas razones, por ejemplo, todo el códido se encomienda a un único lugar. Sin embargo, tiene el defecto de ser un poco más complejo y facilita el cometer errores al reintegrar cambios o empujar accidentalmente una 'branch' a un repositorio con el que no guarda relación.

Otra particularidad es que para diferenciar entre lo que tiene en su subdirectorio rack y el código en su 'branch' rack_branch - para ver si necesita convergerlos - no puede usar el comando diff normal. En lugar de esto, debe ejecutar git diff-tree con la 'branch' que desea comparar:

$ git diff-tree -p rack_branch

O, para comparar lo que hay en su subdirectorio rack con lo que era la 'branch' master en el servidor la última vez que usted hizo fetch, ejecute:

$ git diff-tree -p rack_remote/master