2011-05-05 9 views
19

Estoy intentando usar la estrategia de combinación de subárbol de git, donde el subdirectorio en el que quiero fusionar está anidado bastante profundamente, actualmente cuatro niveles de profundidad.Git: Subtree ¿Se funden en un subdirectorio profundamente anidado?

Seguí las instrucciones here para agregar el repositorio del módulo como un control remoto, ejecutar git read-tree para obtener el código remoto en un subdirectorio en mi repositorio local, y confirmar esos cambios.

Mi problema surge cuando trato de obtener y fusionar los cambios del control remoto en la rama principal de mi proyecto principal. El paso 5 en la página anterior sugiere una extracción de git con el modificador de subárbol -s. Esto funciona correctamente para mí cuando mi subdirectorio tiene uno, dos o tres niveles de profundidad, pero no cuatro.

Aquí está el resultado de la fusión en un subdirectorio de 2 niveles de profundidad. Puede ver que el archivo README en sites/all/se ha actualizado correctamente. En mi repositorio remoto, el archivo README está en la raíz.

$ git pull -s subtree REMOTE_REPO master 
remote: Counting objects: 5, done. 
remote: Compressing objects: 100% (3/3), done. 
remote: Total 3 (delta 2), reused 0 (delta 0) 
Unpacking objects: 100% (3/3), done. 
From /path/to/my/REMOTE_REPO 
* branch   master  -> FETCH_HEAD 
Merge made by subtree. 
sites/all/README | 2 ++ 
1 files changed, 2 insertions(+), 0 deletions(-) 

Aquí el subdirectorio es de 3 niveles de profundidad: sites/all/modules /. Esto funciona bien, también, tirando de los cambios y actualizando los archivos.

$ git pull -s subtree REMOTE_REPO master 
remote: Counting objects: 5, done. 
remote: Compressing objects: 100% (3/3), done. 
remote: Total 3 (delta 2), reused 0 (delta 0) 
Unpacking objects: 100% (3/3), done. 
From /path/to/my/REMOTE_REPO 
* branch   master  -> FETCH_HEAD 
Merge made by subtree. 
sites/all/modules/README | 2 ++ 
1 files changed, 2 insertions(+), 0 deletions(-) 

Pero ahora mi código está en un subdirectorio 4 niveles de profundidad: sites/all/modules/mi_módulo /. Git parece sacar los cambios de REMOTE_REPO, pero no actualiza los archivos, sino que me dice que ya está actualizado.

$ git pull -s subtree REMOTE_REPO master 
remote: Counting objects: 5, done. 
remote: Compressing objects: 100% (3/3), done. 
remote: Total 3 (delta 2), reused 0 (delta 0) 
Unpacking objects: 100% (3/3), done. 
From /path/to/my/REMOTE_REPO 
* branch   master  -> FETCH_HEAD 
Already up-to-date! 
Merge made by subtree. 

Y si me quedo otra vez de inmediato, no se tire de los cambios o actualizar los archivos.

$ git pull -s subtree REMOTE_REPO master 
From /path/to/my/REMOTE_REPO 
* branch   master  -> FETCH_HEAD 
Already up-to-date. 

Ver el registro de git en este punto se me muestran los cambios desde el repositorio remoto y la fusión, pero los archivos en mi salida no se han actualizado.

¿Esto es un error, o estoy haciendo algo mal?

Actualización: Chris Johnsen ofreció la siguiente opción, que genera un error:

$ git pull -X subtree=sites/all/modules/my_module/ REMOTE_REPO master 
remote: Counting objects: 5, done. 
remote: Compressing objects: 100% (3/3), done. 
remote: Total 3 (delta 2), reused 0 (delta 0) 
Unpacking objects: 100% (3/3), done. 
From /Users/jeff/work/checkouts/compass_suite 
* branch   master  -> FETCH_HEAD 
fatal: entry not found in tree 173d4f16af4d2d61ae5c4b3446c392e8b49cc57d 

Respuesta

10

La estrategia subtree fusión limita artificialmente la profundidad de su búsqueda de donde el subárbol “encaja” en el árbol global. Lamentablemente, este límite está codificado de forma rígida (consulte match-trees.c:267).

Afortunadamente, Git 1.7.0 agregó la opción subtree=… a la estrategia de combinación (predeterminada) recursive. Esta opción le permite especificar exactamente el prefijo para que Git no tenga que adivinar (tanto).

Con Git 1.7.0 o posterior, intente esto:

git pull -X subtree=sites/all/modules/my_module REMOTE_REPO master 
+0

Gracias por su respuesta, Chris. Lo intenté y obtuve un error. Como no puedo publicar el código en los comentarios, he actualizado mi pregunta para mostrar el resultado del comando. – Jeff

+30

Debería haber prestado más atención. Resulta que la barra inclinada final causa el error. Usé subtree = sites/all/modules/my_module/en lugar de subtree = sites/all/modules/my_module. Sin la barra al final, ¡funciona! Gracias de nuevo. – Jeff

+0

Gracias por la respuesta. Utilizo esto para dividir un gran repositorio git en múltiples más pequeños. –

54

Aclaración para los futuros lectores, la solución está en los comentarios de la respuesta de Chris Johnsen. Si ve el error "fatal: entry not found in tree", elimine la barra al final del prefijo del subárbol.

Por ejemplo, si usted está tratando de tirar de un subárbol Páginas GitHub con un comando como

git subtree --prefix gh-pages/ pull origin gh-pages 

y hay conflictos obtendrá un error como

* branch   gh-pages -> FETCH_HEAD 
fatal: entry not found in tree 6e69aa201cad3e5888f1d12af0d910f8a10a8ec3 

Basta con retirar la barra final a partir de los GH-páginas directorio

git subtree --prefix gh-pages pull origin gh-pages 

Esto funcionará e intentará fusionarse. El peor escenario que puede obtener es cuando la fusión automática falla y se obtiene un error como

Automatic merge failed; fix conflicts and then commit the result. 

pero sólo hay que resolver los conflictos de forma manual y ya está.

+0

¡Yikes! Ese fue un mensaje de error útil. –

+4

+1 salvavidas, el mismo problema surge con git-subárbol haciendo una fusión y la misma respuesta. – Amoss

+1

Esto resolvió mi problema. ¿De qué está aceptado hablar? – bentford

Cuestiones relacionadas