Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 24 additions & 23 deletions book/07-git-tools/sections/subtree-merges.asc
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
[[_subtree_merge]]
===== Fusión de Subárbol

La idea de la fusión del subárbol es que tiene dos proyectos, y uno de los proyectos se asigna a un subdirectorio del otro y viceversa.
Cuando especifica una fusión de subárbol, Git suele ser lo suficientemente inteligente como para darse cuenta de que uno es un subárbol del otro y se fusiona adecuadamente.
===== Convergencia de Subárbol

Veremos un ejemplo de cómo agregar un proyecto separado a un proyecto existente y luego fusionar el código del segundo en un subdirectorio del primero.
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.

Primero, agregaremos la aplicación Rack a nuestro proyecto.
Agregaremos el proyecto Rack como una referencia remota en nuestro propio proyecto y luego lo comprobaremos en su propia rama:
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 propio branch:

[source,console]
----
Expand All @@ -29,8 +30,8 @@ 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 nuestra rama `rack_branch` y nuestro propio proyecto en la rama `master`.
Si echa un vistazo a uno y luego al otro, puede ver que tienen diferentes raíces de proyecto:
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:

[source,console]
----
Expand All @@ -43,30 +44,30 @@ $ ls
README
----

Este es un concepto extraño. No todas las ramas en su repositorio en realidad tienen que ser ramas del mismo proyecto. No es común porque raramente es útil, pero es bastante fácil tener ramas que contengan historias completamente diferentes.
Este concepto es algo extraño. No todos los 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 incluir el proyecto Rack en nuestro proyecto `master` como subdirectorio.
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 <<_git_internals>>, pero por ahora, sepa que lee el árbol raíz de una rama en su área de ensayo y directorio de trabajo actuales.
Acabamos de volver a su rama `master`, y halamos la rama `rack_branch` dentro del subdirectorio `rack` de nuestra rama `master` de nuestro proyecto principal:
Aprenderá más sobre `read-tree` y sus amigos en <<_git_internals>>, pero por ahora sepa que este interpreta el árbol raíz de un branch en su area de staging y directorio de trabajo.
Sólo cambiamos de vuelta a su branch `master`, e integramos el branch `rack_branch` al subdirectorio `rack` de nuestro branch `master` de nuestro proyecto principal:

[source,console]
----
$ git read-tree --prefix=rack/ -u rack_branch
----

Cuando hacemos commit, parece que tenemos todos los archivos de Rack en ese subdirectorio como si los hubiéramos copiado desde un tarball.
Lo que se vuelve interesante es que podemos fusionar con bastante facilidad los cambios de una de las ramas a la otra.
Por lo tanto, si el proyecto de Rack se actualiza, podemos implementar los cambios iniciales al cambiar a esa rama y extraer:
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 uno de los branchs al otro.
Entonces, si el proyecto Rack se actualiza, podemos atraer cambios río arriba alternando a esa branch e incorporando:

[source,console]
----
$ git checkout rack_branch
$ git pull
----

Entonces, podemos fusionar los cambios nuevamente en nuestra rama `master`.
Para incorporar los cambios y rellenar previamente el mensaje del commit, use las opciones `--squash` y `--no-commit`, así como también la opción `-Xsubtree` de la estrategia de fusión recursiva. (La estrategia recursiva es la predeterminada aquí, pero la incluimos para mayor claridad).
Luego, podemos converger de vuelta esos cambios a nuestro 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.)

[source,console]
----
Expand All @@ -76,20 +77,20 @@ Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
----

Todos los cambios del proyecto Rack se fusionan y están listos para hacerles commit localmente.
También puede hacer lo opuesto – realizar cambios en el subdirectorio `rack` de su rama principal y luego combinarlos en su rama `rack_branch` más tarde para enviarlos a los mantenedores o empujarlos hacia arriba.
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 da una manera de tener un flujo de trabajo similar al flujo de trabajo del submódulo sin usar submódulos (que trataremos en <<_git_submodules>>). Podemos mantener ramas con otros proyectos relacionados en nuestro repositorio y hacerles fusión de subárbol en nuestro proyecto de vez en cuando. Es bueno de alguna manera, por ejemplo, a todo el código se le ha hecho commit en un solo lugar. Sin embargo, tiene otros inconvenientes, ya que es un poco más complejo y más fácil cometer errores en la reintegración de cambios o al empujar accidentalmente una rama hacia un repositorio no relacionado.
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 hablaremos en <<_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 un branch a un repositorio con el que no guarda relación.

Otra cosa un poco extraña es que para obtener una diferencia entre lo que tienes en tu subdirectorio `rack` y el código en tu rama `rack_branch` para ver si necesitas fusionarlos – no puedes usar el comando `diff` normal .
En su lugar, debe ejecutar `git diff-tree` con la rama con la que desea comparar:
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 el branch que desea comparar a:

[source,console]
----
$ git diff-tree -p rack_branch
----

O, para comparar lo que está en el subdirectorio `rack` con lo que la rama `master` del servidor fué la última vez que buscó, puede ejecutar
O, para comparar lo que hay en su subdirectorio `rack` con lo que era el branch `master` en el servidor la última vez que usted hizo fetch, ejecute

[source,console]
----
Expand Down