Diferencias entre git submodule y subtree

Respuestas:

177

¿Qué sucede si quiero que los enlaces siempre apunten a la CABEZA del repositorio externo?

Puede hacer un submódulo para seguir el HEAD de una rama de un repositorio remoto de submódulo, con:

o git submodule add -b <branch> <repository> [<path>]. (para especificar una rama a seguir)
o git submodule update --remoteque actualizará el contenido del submódulo al último HEAD de <repository>/<branch>forma predeterminada origin/master. Sin embargo, su proyecto principal seguirá los hashes de HEAD del submódulo, incluso si --remotese usa.


VonC
fuente
su respuesta parece ir en contra de la respuesta votada aquí: stackoverflow.com/questions/10443627/…
Nathan H
@NathanH esto (la posibilidad de rastrear HEAD) se agregó un año después (marzo de 2013, git 1.8.2: github.com/git/git/blob/… )
VonC
Veo que el comportamiento de seguimiento de submódulo también se menciona en su otra respuesta . En ese caso, creo que quiere decir que siempre se apunta al HEAD de un submódulo mediante el uso de ambos add -by, --remoteposteriormente, en los comandos de actualización, según la documentación de actualización del submódulo . En ese caso, ¿ -btodavía se necesita realmente para seguir a HEAD of master?
matanster
@matt the -bse usa para generar los metadatos .gitmodule correctos para el submódulo (es equivalente a a git config -f .gitmodules submodule.<path>.branch <branch>).
VonC
Entonces tiene poco que ver con la habilitación --remote: --remotefunciona también si -bno se ha utilizado add. En ambos casos, la actualización provocará una confirmación en el repositorio principal que aloja el submódulo, por lo que los enlaces realmente "no siempre apuntan al HEAD" de una manera muy automática ... o no lo entendí, o esa afirmación es mejor que se elimine de la respuesta original (?)
matanster
351

submódulo es enlace;

subárbol es copia

Feng
fuente
121

La diferencia conceptual es:

Con los submódulos git , normalmente desea separar un repositorio grande en otros más pequeños. La forma de hacer referencia a un submódulo es de estilo maven : está haciendo referencia a una única confirmación del otro repositorio (submódulo). Si necesita un cambio dentro del submódulo, debe hacer un commit / push dentro del submódulo, luego hacer referencia al nuevo commit en el repositorio principal y luego commit / push la referencia cambiada del repositorio principal. De esa manera, debe tener acceso a ambos repositorios para la compilación completa.

Con git subtree integras otro repositorio en el tuyo, incluido su historial. Entonces, después de integrarlo, el tamaño de su repositorio es probablemente mayor (por lo que esta no es una estrategia para mantener los repositorios más pequeños). Después de la integración, no hay conexión con el otro repositorio, y no necesita acceso a él a menos que desee obtener una actualización. Entonces, esta estrategia es más para reutilizar el código y el historial; personalmente no la uso.

Niklas P
fuente
Pero git subtreecontigo también puedes empujar, si quieres, ¿verdad?
Ixx
@lxx Si conoce la URL del repositorio ...
Franklin Yu
@FranklinYu ¿Por qué no lo sabría? no puede obtener esa información de los metadatos locales de git?
adi518
@ adi518 Sí, si usted fue quien creó el subárbol. Sin embargo, si empujó su repositorio a GitHub y otros lo clonaron, no creo que él / ella sepa automáticamente la URL del subárbol.
Franklin Yu
@NiklasP: ¿puede dar más detalles sobre "hacer referencia a la nueva confirmación en el repositorio principal"? Ese es el único paso que no tengo claro sobre cómo ejecutar y, por lo tanto, "referencia cambiada" tampoco es algo que entiendo.
Robert Oschler
21

el submódulo que
empuja un repositorio principal a un control remoto no empuja los archivos del submódulo

el subárbol que
empuja un repositorio principal a remoto empuja los archivos del subárbol

Maciek Rek
fuente
3
"empujar un repositorio principal a remoto empuja los archivos del subárbol" No, no lo hace.
J Bramble
@JBramble Probablemente debería mencionar que se hace con la aplicación SourceTree, por ejemplo:git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree push -v --tags production refs/heads/master:refs/heads/master
Maciek Rek