¿Cómo puedo especificar una rama/etiqueta cuando la adición de un Git submódulo?
-
21-09-2019 - |
Pregunta
¿Cómo git submodule add -b
trabajo?
Después de la adición de un submódulo con una rama específica, un nuevo repositorio clonado (después de git submodule update --init
estará en un determinado cometer, no la propia sucursal (git status
en el submódulo muestra "No se encuentra en cualquier rama").
No puedo encontrar ninguna información sobre .gitmodules
o .git/config
sobre el submódulo de la sucursal o cualquier específicos cometer, entonces, ¿cómo Git entenderlo?
También, es posible especificar una etiqueta en lugar de una sucursal?
Yo estoy usando la versión 1.6.5.2.
Solución
Nota: Git 1.8.2 añade la posibilidad de realizar un seguimiento de las ramas. Vea algunas de las respuestas a continuación.
Es un poco confuso para acostumbrarse a esto, pero no son submódulos en una rama. Ellos son, como usted dice, sólo un puntero a una confirmación en concreto del repositorio del submódulo.
Esto significa que, cuando alguien cheques más por su repositorio, o tira de su código, y hace la actualización submódulo git, el submódulo está desprotegido a la confirmación en concreto.
Esto es grande para un submódulo que no cambia a menudo, porque entonces todo el mundo en el proyecto puede tener el submódulo al mismo comprometerse.
Si desea mover el submódulo de una etiqueta en particular:
cd submodule_directory
git checkout v1.0
cd ..
git add submodule_directory
git commit -m "moved submodule to v1.0"
git push
A continuación, otro desarrollador que quiera tener submodule_directory cambió a la etiqueta, lo hace
git pull
git submodule update --init
git pull
cambios que comprometen sus puntos de directorio a submódulo. git submodule update
funde realmente en el nuevo código.
Otros consejos
Me gustaría añadir una respuesta aquí que es en realidad un conglomerado de otras respuestas, pero creo que puede ser más completa.
Usted sabe que tiene un submódulo Git cuando tiene estas dos cosas.
-
Su
.gitmodules
tiene una entrada de este modo:[submodule "SubmoduleTestRepo"] path = SubmoduleTestRepo url = https://github.com/jzaccone/SubmoduleTestRepo.git
-
Tiene un objeto submódulo (llamado SubmoduleTestRepo en este ejemplo) en su repositorio Git. GitHub muestra estos objetos como "submódulo". O hacer
git submodule status
desde una línea de comandos. objetos submódulo Git son tipos especiales de objetos de Git, y que contienen la información para cometer un SHA específica.Cada vez que hacemos una
git submodule update
, rellenará el submódulo con el contenido de la confirmación. Se sabe dónde encontrar el commit debido a la información en el.gitmodules
.Ahora, todo el
-b
hace es añadir una línea en el archivo.gitmodules
. Así pues, siguiendo el mismo ejemplo, se vería así:[submodule "SubmoduleTestRepo"] path = SubmoduleTestRepo url = https://github.com/jzaccone/SubmoduleTestRepo.git branch = master
Nota: único nombre rama se apoya en un archivo
.gitmodules
, pero SHA y TAG no son compatibles (en lugar de eso, de la rama cometer de cada módulo puede ser seguidos y actualizados utilizando "git add .
", por ejemplo, comogit add ./SubmoduleTestRepo
, y que no es necesario cambiar el archivo.gitmodules
cada vez)El objeto submódulo todavía está apuntando a una específica cometió. La única cosa que la opción de compra
-b
que es la posibilidad de añadir una bandera--remote
a su actualización de acuerdo con la respuesta de Vogella:git submodule update --remote
En lugar de poblar el contenido del submódulo para el envío de datos a la que apunta el submódulo, que sustituye esa confirmación con el último informe de cambios en la rama principal, entonces se llena el submódulo con esa confirmación. Esto se puede hacer en dos pasos por djacobs7 respuesta. Ya que ahora ha actualizado el objeto cometer el submódulo hace referencia, tiene que confirmar el objeto submódulo transformó en su repositorio Git.
git submodule add -b
no es un arte de magia manera de mantener todo al día con una rama. Simplemente se añade información sobre una rama en el archivo.gitmodules
y le da la opción de actualizar el objeto submódulo a la última confirmación de una rama especificada antes de ocupar la misma.
(Git 2,22, Q2 2019, ha introducido git submodule set-branch --branch aBranch -- <submodule_path>
)
Tenga en cuenta que Si tiene un existente submódulo que no es seguimiento de una rama sin embargo, y, a continuación (if que haya gIT 1.8.2+ ):
-
Asegúrese de que el repositorio padre sabe que su submódulo ahora rastrea una rama:
cd /path/to/your/parent/repo git config -f .gitmodules submodule.<path>.branch <branch>
-
Asegúrese de que el submódulo es en realidad a más tardar, de esa rama:
cd path/to/your/submodule git checkout -b branch --track origin/branch # if the master branch already exist: git branch -u origin/master master
(Con 'origen' es el nombre de la aguas arriba repo remoto el submódulo se ha clonado a partir de .
Un git remote -v
dentro de esa sub-módulo mostrará la misma. Por lo general, es 'origen')
-
No se olvide de grabar el nuevo estado de su submódulo en tu repositorio padre:
cd /path/to/your/parent/repo git add path/to/your/submodule git commit -m "Make submodule tracking a branch"
-
actualización posterior para ese sub-módulo tendrá que utilizar la opción
--remote
:# update your submodule # --remote will also fetch and ensure that # the latest commit from the branch is used git submodule update --remote # to avoid fetching use git submodule update --remote --no-fetch
Tenga en cuenta que con Git 2.10+ (Q3 2016), se puede utilizar '.
'como nombre de la sucursal:
El nombre de la rama se registra como
submodule.<name>.branch
en.gitmodules
paraupdate --remote
.
Un valor especial de.
se utiliza para indicar que el nombre de la rama en el submódulo debe ser el mismo nombre que la rama corriente en el repositorio actual .
Si desea actualizar todos los submódulos siguientes una rama:
git submodule update --recursive --remote
Tenga en cuenta que el resultado, para cada submódulo actualizada, será casi siempre será una cabeza separada , como se nota Dan Cameron en su respuesta .
( Clintm notas en los comentarios que, si ejecuta git submodule update --remote
y el sha1 resultante es la misma que la rama del submódulo se encuentra actualmente en, no va a hacer nada y dejar el submódulo todavía "en esa rama" y no en el estado de cabeza separada.)
Para garantizar la rama es en realidad desprotegido (y que no modificará el SHA1 del entrada especial que representa el submódulo para la cesión temporal de los padres), sugiere:
git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; git checkout $branch'
Cada submódulo todavía hacen referencia al mismo SHA1, pero si lo hace hacer nuevas confirmaciones, usted será capaz de empujar a ellos, ya que serán referenciados por la rama que desea que el sub-módulo para el seguimiento.
Después de ese empuje dentro de un sub-módulo, no se olvide de volver a la cesión temporal de los padres, agregar, comprometerse y empuje el nuevo SHA1 para los submódulos modificados.
Tenga en cuenta el uso de $toplevel
, recomendado en los comentarios Alexander Pogrebnyak .
$toplevel
se introdujo en git1.7.2 en mayo de 2010:. cometer f030c96
contiene la ruta absoluta del directorio de nivel superior (donde
.gitmodules
es).
dtmland
añade en los comentarios :
El script foreach dejará de submódulos de caja que no están siguiendo una rama.
Sin embargo, este comando le da tanto:
git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git checkout $branch' –
El mismo comando pero más fácil de leer:
git submodule foreach -q --recursive \
'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; \
[ "$branch" = "" ] && \
git checkout master || git checkout $branch' –
Umlaute refina dtmland 's de comandos con una versión simplificada en los comentarios :
git submodule foreach -q --recursive 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
múltiples líneas:
git submodule foreach -q --recursive \
'git checkout \
$(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
Git 1.8.2 añade la posibilidad de realizar un seguimiento de ramas.
# add submodule to track master branch
git submodule add -b branch_name URL_to_Git_repo optional_directory_rename
# update your submodule
git submodule update --remote
Un ejemplo de cómo uso submódulos de Git.
- Crea un nuevo repositorio
- A continuación, clonar otro repositorio como un submódulo
- A continuación, tenemos que submódulo utilizar una etiqueta llamada V3.1.2
- Y luego nos comprometemos.
Y que se ve un poco como esto:
git init
vi README
git add README
git commit
git submodule add git://github.com/XXXXX/xxx.yyyy.git stm32_std_lib
git status
git submodule init
git submodule update
cd stm32_std_lib/
git reset --hard V3.1.2
cd ..
git commit -a
git submodule status
Tal vez ayuda (aunque yo utilizo una etiqueta y no una rama)?
En mi experiencia de conmutación de ramas en el superproject o futuro de las cajas va a causar Cabezas separadas de los submódulos independientemente de si el submódulo se agrega correctamente y seguimiento (es decir,@djacobs7 y @Johnny Z respuestas).
Y en lugar de comprobar manualmente la rama correcta manualmente o a través de una secuencia de comandos git submódulo foreach puede ser utilizado.
Se compruebe el submódulo archivo de configuración para la subdivisión de la propiedad y obtener el conjunto de la rama.
git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'
submódulos de Git son un poco extraño - que siempre están en el modo de "cabeza separada" - que no se actualizan a la última comprometerse en una rama, como era de esperar
.Esto hace algún sentido cuando se piensa en ello, sin embargo. Digamos que creo repositorio foo con submódulo bar . Empujo mis cambios y le digo que se echa un vistazo a cometer a7402be desde el repositorio foo .
A continuación, imagine que alguien comete un cambio al repositorio bar antes de que pueda hacer su clon.
A la salida de comprometerse a7402be desde el repositorio foo , que espera obtener el mismo código empujé. Es por eso que los submódulos no se actualizan hasta que les diga que hacer explícita y luego una nueva confirmación.
En lo personal creo que submódulos son la parte más confusa de Git. Hay un montón de lugares que pueden explicar submódulos mejor que pueda. Recomiendo Pro Git por Scott Chacon.
Para cambiar la rama de un submódulo (asumiendo que ya tiene el submódulo como parte del repositorio):
-
cd
a raíz de su repositorio que contiene los submódulos -
.gitmodules
abierto para la edición - Añadir línea debajo
path = ...
yurl = ...
que dicebranch = your-branch
, para cada submódulo; guardar.gitmodules
archivo. - a continuación, sin cambiar directorio de hacer
$ git submodule update --remote
... esto debe tirar en las últimas confirmaciones en la rama especifica, para cada submódulo así modificado.
Tengo esto en mi archivo .gitconfig. Todavía es un proyecto, pero resultó útil a partir de ahora. Me ayuda para volver a colocar siempre los submódulos a su rama.
[alias]
######################
#
#Submodules aliases
#
######################
#git sm-trackbranch : places all submodules on their respective branch specified in .gitmodules
#This works if submodules are configured to track a branch, i.e if .gitmodules looks like :
#[submodule "my-submodule"]
# path = my-submodule
# url = git@wherever.you.like/my-submodule.git
# branch = my-branch
sm-trackbranch = "! git submodule foreach -q --recursive 'branch=\"$(git config -f $toplevel/.gitmodules submodule.$name.branch)\"; git checkout $branch'"
#sm-pullrebase :
# - pull --rebase on the master repo
# - sm-trackbranch on every submodule
# - pull --rebase on each submodule
#
# Important note :
#- have a clean master repo and subrepos before doing this !
#- this is *not* equivalent to getting the last committed
# master repo + its submodules: if some submodules are tracking branches
# that have evolved since the last commit in the master repo,
# they will be using those more recent commits !
#
# (Note : On the contrary, git submodule update will stick
#to the last committed SHA1 in the master repo)
#
sm-pullrebase = "! git pull --rebase; git submodule update; git sm-trackbranch ; git submodule foreach 'git pull --rebase' "
# git sm-diff will diff the master repo *and* its submodules
sm-diff = "! git diff && git submodule foreach 'git diff' "
#git sm-push will ask to push also submodules
sm-push = push --recurse-submodules=on-demand
#git alias : list all aliases
#useful in order to learn git syntax
alias = "!git config -l | grep alias | cut -c 7-"
Quack para tirar de un módulo específico de otro repositorio Git. Tenemos que tirar de código sin todo el código base del repositorio proporcionado - necesitamos un módulo / archivo muy específicas de ese enorme depósito y debe actualizarse cada vez que corremos actualización
.Así que lo hemos conseguido de esta manera:
Crea configuración
name: Project Name
modules:
local/path:
repository: https://github.com/<username>/<repo>.git
path: repo/path
branch: dev
other/local/path/filename.txt:
repository: https://github.com/<username>/<repo>.git
hexsha: 9e3e9642cfea36f4ae216d27df100134920143b9
path: repo/path/filename.txt
profiles:
init:
tasks: ['modules']
Con la configuración anterior, se crea un directorio del repositorio GitHub proporcionado como se especifica en la configuración del primer módulo, y el otro es para tirar y crear un archivo desde el repositorio dado.
Otros desarrolladores sólo necesitan ejecutar
$ quack
Y se tira el código de las configuraciones anteriores.
El único efecto de la elección de una rama de un submódulo es que, cada vez que se pasa la opción --remote
en la línea de comandos git submodule update
, Git va a salir en cabeza separada Modo (si el comportamiento --checkout
por defecto es seleccionados) el último commit de ese remoto rama seleccionada.
Usted debe tener especial cuidado cuando se utiliza esta característica de seguimiento de la rama remota para submódulos de Git si se trabaja con los clones poco profundas de submódulos.
La rama que elija para este fin en la configuración submódulo no el que se clona durante git submodule update --remote
.
Si pasa el parámetro también --depth
y que no instruyen acerca de qué rama Git que desea clonar - y en realidad no se puede en la línea de comandos git submodule update
!! -., Será implícitamente comportarse como se explica en la documentación git-clone(1)
para git clone --single-branch
cuando el parámetro --branch
explícita no se encuentra, y por lo tanto va a clonar la rama primaria solamente
Con ninguna sorpresa, después de la etapa clon realizada por el comando git submodule update
, será finalmente tratar de ver lo último de confirmación para el remoto rama que configuró previamente para el submódulo, y, si esto no es el primario, que no es parte de su clon sin profundidad local y por lo tanto, se producirá un error con
fatal: Se necesita una única revisión
No se puede encontrar el origen de corriente / NotThePrimaryBranch revisión en ruta submódulo 'mySubmodule'
submódulo git add -b desarrollar --name nombre-sucursal - https: //branch.git