El modelo de subárbol
Un subárbol fusiona la historia de otro repositorio en un subdirectorio del tuyo. A diferencia de los submódulos, no hay gitlink separado ni comandos extra requeridos para clonar — cualquiera que clone tu repo obtiene el contenido del subárbol automáticamente. El costo es una historia más densa; el beneficio es simplicidad operativa.
Añadir un subárbol
git subtree add --prefix=third_party/lib \
https://github.com/example/lib main --squash
El flag --squash colapsa la historia importada en un solo commit. Omítelo si quieres la historia upstream completa.
Traer actualizaciones
git subtree pull --prefix=third_party/lib \
https://github.com/example/lib main --squash
Añade un alias de remote para evitar reescribir la URL:
git remote add lib https://github.com/example/lib
git subtree pull --prefix=third_party/lib lib main --squash
Hacer push hacia upstream
git subtree push --prefix=third_party/lib lib feature-branch
Subárbol vs submódulo
Elige subárboles cuando quieras un clone sin fricción para los novatos, cuando rara vez modifiques el código vendor, o cuando la complejidad de CI alrededor de submódulos te haya mordido. Elige submódulos cuando necesites anclar a un SHA upstream exacto.
Dividir un subdirectorio
git subtree split --prefix=third_party/lib -b lib-only
cd ..
git clone /path/to/parent --branch lib-only lib-extracted
Errores comunes
Olvidar --squash importa decenas de miles de commits upstream. Mezclar ediciones dentro del prefijo con ediciones fuera en el mismo commit hace ruidoso a subtree push.
Alternativa: estrategia merge subtree
git remote add -f lib https://github.com/example/lib
git merge -s ours --no-commit --allow-unrelated-histories lib/main
git read-tree --prefix=third_party/lib/ -u lib/main
git commit -m "Subtree merge of lib"