¿Cómo puedo especificar una rama/etiqueta cuando la adición de un Git submódulo?

StackOverflow https://stackoverflow.com/questions/1777854

  •  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.

¿Fue útil?

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.

  1. Su .gitmodules tiene una entrada de este modo:

    [submodule "SubmoduleTestRepo"]
        path = SubmoduleTestRepo
        url = https://github.com/jzaccone/SubmoduleTestRepo.git
    
  2. 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, como git 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 para update --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 

Git submódulos

Un ejemplo de cómo uso submódulos de Git.

  1. Crea un nuevo repositorio
  2. A continuación, clonar otro repositorio como un submódulo
  3. A continuación, tenemos que submódulo utilizar una etiqueta llamada V3.1.2
  4. 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 = ... y url = ... que dice branch = 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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top